Home

Awesome

ShellCheck

snip - CLI snippets manager in bash

Description

snip is a simple snippet manager for bash, which allows the user to save useful and important bash code snippets directly from the bash prompt. It is especially useful to save long one-liners, or rarely used commands which we tend to forget. snip is written in pure bash, but uses FZF to allow the user to perform searches on the snippet database.

Screen Cast

Motivation

Shell scripting is a powerful tool in the right hands. The piping capabilities coupled with the many readily available utilities make it possible to perform complex and useful operations on all sorts of data. Most medium to advanced bash users will have a number "code snippets" stored somewhere, from text files to Google Keep. Those solutions involve cutting and pasting, and in the case of web-based solutions, the use of a browser.

Consider for example the following sequence of commands, taken from a real use case, a command to restart a VNC server using systemd-run:

if [[ -s "${VNCPASSWD}" ]]; then
  systemctl --user reset-failed x0tigervncserver;
  systemd-run --user --unit=x0tigervncserver --  /usr/bin/x0tigervncserver \
    --verbose --localhost no --fg  --SecurityTypes=TLSVnc \
    --PasswordFile="${VNCPASSWD}" "${DISPLAY}"
fi

It took a few tries to get the command "just right", which naturally filled the history with all sorts of invalid or "almost valid" commands.

With snip, it's just be a matter of typing Ctrl-x Ctrl-n ("N" for "new") directly at the command-line prompt to save the snippet when the correct command shows. To find and recall a saved snippet just type Ctrl-x Ctrl-R ("R" for "Run", or "Recall").

Features

Installation

Installation is easy. Just cut & paste the two lines below. To upgrade snip, to the latest stable version, just repeat the same commands:

sudo curl -s https://raw.githubusercontent.com/marcopaganini/snip/master/snip >/usr/local/bin/snip
sudo chmod 755 ~/usr/local/bin/snip

Then edit your ~/.bashrc file and add the following:

eval "$(/usr/local/bin/snip setup)"

Alternatively, if you prefer using a one-liners to setup your ~/.bashrc, you can also do:

eval '"$(/usr/local/bin/snip setup)"' >> ~/.bashrc

Using snip

The eval command above installs two new keybindings to your bash configuration:

It's also possible to perform operations directly from the CLI, using snip command. For a list of commands, see the "Appendix: Manual Page" section below. You can also recall the full documentation directly from the command-line by typing snip help.

Future changes

snip is in its early stages and I have a number of ideas for future features. Some ideas:

Similar options

Comments and ideas

Feel free to open issues for any problems you find and send me your comments, ideas, and PRs.

Appendix: Manual Page

NAME
    snip - CLI to manage shell code snippets.

SYNOPSIS
    snip [command] [options]

DESCRIPTION
    The snip utility allows users to easily manage bash code snippets.
    Users can save and execute commands directly from the bash command line,
    with the provided keybindings. It's also possible to perform operations
    on the snippet database directly on the command-line.

OPTIONS
    The first argument is always a command. Commands may or may not have
    options (see below for a summary).

    add [-f, --file FILENAME] [-D, --delete] [command]
        The add command adds a new entry to the snip database. Command must
        be properly quoted and will be added "as-is". The program will ask
        for a description from the keyboard.

        If used with the `--file` option, snip will read the command to be
        saved from a filename. Using `--delete` with the `--file` option
        causes the file to be deleted after its contents are added to the
        database. This is useful when adding content from temporary files.

    edit
        Invoke the text editor on the database file. The database is a simple
        text file using '|' (pipe) as a delimiter. Every line needs to have
        three exact fields: timestamp, description, and command. It is
        acceptable for the command to contain pipe characters, but not for
        the timestamp or description fields. Please note that you can only
        edit the current host database (even though list and find will by
        default show the contents of all hosts).

    find [-q, --query STRING]
        The find command invokes FZF on the database and prints the
        command-line for the snippet chosen by the user. The `--query` flag
        sets the initial query for FZF, if present.

    help
        This helpful message. :)

    list, ls
        The list command issues a formatted listing of the snippet database,
        including the snippet creation timestamps.

    log
        Show a git log --oneline of the database directory.

    repo <reponame>
        Initializes a git repository and start database sync.  <reponame>
        must be an URL pointing to a git repository. TIP: You can create
        private repos in github or gitlab for free and use them to sync your
        snippets.

    setup
        This command issues the required commands to setup the bash
        command-line bindings to easily add snippets and re-run saved
        snippets. To install snip, run this from your `~/.bashrc` file:

        eval "$(/path/to/snip setup)"

        This will create a few functions in your bash namespace and two
        bindings. By default they are:

        Ctrl-X Ctrl-N
            Add the current line as a new snippet. The program will replace
            the text in the command-line with the appropriate `snip add`
            command.  All the user needs to do is press the ENTER key to
            confirm the action and enter a description.

        Ctrl-X Ctrl-R
            Find and run a saved snippet. This will open an FZF window and
            allow the user to choose a snippet to run. Once selected, snip
            will replace the current bash input buffer with the command to
            run.

    sync
        Sync local changes with the git repository. This adds any changes
        to your database file, commits it and does a git pull -r (rebase)
        followed by a git push. The database name contains the host name
        so there should be no conflicts. If anything unusual happen, snip
        will abort execution with an error message.

    version
        Show the program version.

SETUP
    Just add `eval "$(/path/to/snip setup)"` to your `~/.bashrc`. Depending
    on your setup, you may need to add it to `~/.profile` as well).

CONFIGURATION FILE
    On the first run, snip will create an example configuration file with
    default values commented out.

    Currently, it is possible to override a few items in the config file.  To
    do that, edit `~/.config/snip/config.${HOSTNAME}` and/edit add the
    following:

    # bash keybindings
    #
    # The two settings below control the bindings for the add and find
    # commands, respectively. C-key means Control+key. Use man bash and
    # look for the "bind" command to find the full syntax for the sequence.

    SNIP_BIND_ADD='"\C-x\C-n"'
    SNIP_BIND_FIND='"\C-x\C-r"'

    # bat (aka batcat) theme. If you have batcat installed, snip will
    # automatically use it to syntax highlight the snippets in the FZF preview
    # window. You can override the theme using the setting below.To see all
    # available themes, run `cat --list-themes` (or `batcat --list-themes`
    # in some distributions.)

    BAT_THEME="gruvbox-dark"

    The lines above show the default keybindings to add and run commands.
    Please keep in mind that this file is sourced directly by the main
    program, so it should be a valid bash file. Look for the the key syntax
    for "bind -x" in the bash manpage for details.

    # This overrides the default editor (normallly $VISUAL or $EDITOR)
    # Common choiceses are nano, nvim, vim, etc.

    SNIP_EDITOR="nano"

REQUIREMENTS
    This program requires FZF to run (https://github.com/junegunn/fzf). Please note that
    FZF is very popular and available natively in most Linux distributions.

    If installed, snip will use `batcat` (aka bat) to provide syntax highlighting
    in the preview window.

AUTHOR
    (C) Sep/2024 by Marco Paganini <paganini [at] paganini [dot] net>