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.
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").
- Save and recall snippets directly from the bash prompt with keybindings.
- One line setup, won't slow down your
.bashrc
loading. - Uses a simple text file for the database.
- CLI commands to edit the database manually.
- CLI commands to list the contents of the database in a formatted way.
- Supports syncing of multiple hosts via a git repo.
- Automatically saves a time stamp with the command.
- Written in pure shell. To install just copy one file to
/usr/local/bin
or any other location in yourPATH
. - Displays full usage with a simple command (
snip help
).
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
The eval
command above installs two new keybindings to your bash
configuration:
-
Ctrl-X
Ctrl-N
: Add the current line to the snippet database. It will replace the current line with asnip add
command to insert your snippet into the database. Just hit ENTER afterwards and provide a description. -
Ctrl-X
Ctrl-R
: This starts FZF so the user can choose a command to be recalled. The command is inserted in the current command-line input. If no modifications are required, just hit ENTER to execute the command.
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
.
snip
is in its early stages and I have a number of ideas for future features.
Some ideas:
- A bit more color in the FZF selector for those who prefer it.
- zsh integration.
- A
snip delete
command (right now, usesnip edit
and delete the snippet line directly from your editor.) - Other general improvements.
- https://github.com/knqyf263/pet - pet is a snippet manager written in Go. if you like snip, you may like pet too.
Feel free to open issues for any problems you find and send me your comments, ideas, and PRs.
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 [-a, --all] [l, --long] [-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. The `--long` flag shows
all details, including hostname and creation timestamp. The -all
flag tells find to display snippets from all hosts, not only the
current one.
help
This helpful message. :)
list, ls [-a, --all] [-l, --long]
The list command displays a formatted listing of the every command and
its description in the database. If used with the "--long" flag, all
details are listed (host and creation timestamp). The "--all" flag
lists commands from all hosts, instead of the current one only.
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) 2024 by Marco Paganini <paganini [at] paganini [dot] net>