A tool for accessing code snippets contained in a folder of plain text Markdown files.
Snibbets allows me to keep code snippets in raw files, not relying on a dedicated code snippet app. I can collect and edit my snippets using a text editor, nvALT (nvUltra), or simply by saving snippets from my clipboard to a text file using *NIX redirection on the command line. I can add descriptive names and extended descriptions/notes to code snippets using standard Markdown.
What Snibbets does is simply allow a quick search for a specific snippet that I can either output to the terminal, pipe to my clipboard, or access via LaunchBar (via the included LaunchBar Action). It’s basically a wrapper for find and grep with the ability to separate code blocks from other text in my Markdown files.
Collecting Snippets
Snibbets is designed to work with a folder containing Markdown files. Each Markdown file can have somewhat flexible formatting, as long as there’s at least one code block (either indented by 4 spaces/1 tab or fenced with backticks).
I recommend using filenames with multiple extensions (ending with your markdown extension), primarily to define the syntax for a snippet. For example, a css snippet would be *.css.md, a ruby snippet would be *.rb.md. This can aid in searching and makes it easy to script things like adding language tags automatically.
The name of the file should be the description of the snippet, at least in the case where there’s only one snippet in the document. Call it ‘javascript url parser.js.md’ or similar. If I got the snippet from StackOverflow, I give it a name based on the question I searched to find it. Be descriptive.
You can combine multiple snippets in a file, though. For example, I have a file called ‘Ruby hash snippets.rb.md’. That file contains an array of useful snippets, and each one has a descriptive title in an h3 header above it. Those (ATX) headers are used to split the file, and when you search from the command line, you’ll get a menu of all of the snippets in the selected file. (And if you have fzf or gum installed, you can quickly filter through with fuzzy searching and find exactly what you need.)
If a file contains multiple snippets, they should be separated by ATX-style headers (one or more #) describing the snippets. Additional descriptions and notes can be included outside of the code block. Notes are not output on the console, only the code is displayed. If you want a note to be included in console output, make it a blockquote by preceding it with >.
A file titled unix find.bash.md:
title: Unix find commands
tags: bash, shell, unix
### Find by name and execute command
find . -name "rc.conf" -exec chmod o r '{}' \;
### Find by name and grep contents
find . -name "*.php" -exec grep -H googleapis '{}' \;
### Find by age range to CSV
Finds files older than 18months and newer than 24 months, cats the output to a CSV in the format `/some/path/somewhere, size in bytes, Access Time, Modified Time`
find /dir/dir -type f -mtime +540 -mtime -720 -printf \"%p\",\"%s\",\"%AD\",|"%TD\"\n > /dir/dir/output.csv
You can include MultiMarkdown metadata in your snippets, either in a YAML block or just at the top of the file with raw key/value pairs. I mostly use this for adding tags, which are then synced to macOS tags when I save. It makes it easy to search for snippets in nvUltra, and also allows you to do searches like snibbets tag:javascript url parser with Snibbets.
CLI
Dependencies
Snibbets requires Ruby 3.0+. On recent versions of macOS, this is not included by default. You can install it via the Command Line Tools from Apple. On macOS and most other systems, you can also use something like Homebrew, rbenv, rvm, or asdf to install Ruby 3.
If available, menus are generated by fzf or gum. If neither are available, a basic Readline menu system will be displayed, so neither are required, just nice to have as they provide fuzzy filtering, scrolling, and type-ahead completion.
Installation
To install Snibbets:
gem install snibbets
If you’re using the system Ruby, use gem install --user-install snibbets instead.
Configuration
When you run it the first time, Snibbets will write a configuration file to ~/.config/snibbets/snibbets.yml. You can edit that file to set things like your snippets directory, your preferred file extension, and a few other options. Options specified in the config file can always be overriden on the command line with flags.
Once an editor is defined, you can use snibbets --configure to open it automatically. Running that commmand before configuring an editor will use whatever app/utility your system defaults to for YAML files.
| key | type | default | description |
| ——————- | ——- | ———- | ———————————— |
| source | string | *required | Path to snippet directory |
| all | boolean | false | Always display all snippets |
| all_notes | boolean | false | Show full content, including notes |
| copy | boolean | false | always copy output to clipboard |
| editor | string | $EDITOR | command or app to use with –edit |
| extension | string | md | Snippet extension to search |
| highlight | boolean | true | Syntax highlight code |
| highlight_theme | string | | Highlighter theme to use |
| highlighter | string | | Can be skylight or pygments |
| include_blockquotes | boolean | false | include blockquotes in output |
| interactive | boolean | true | display a menu when multiple options |
| launchbar | boolean | false | Output for LaunchBar |
| menus | string | fzf | menu utility: fzf, gum, console |
| name_only | boolean | false | Always search by filename |
| output | string | raw | Output format json, launchbar, raw |
[Configuration Options]
Snippet Location
Set the source key to the folder where you keep your Markdown snippets. Optionally adjust the extension setting if you use an extension other than md (e.g. markdown or txt).
Other Options
The all setting determines how Snibbets handles files
containing multiple snippets. If all is true, then it will
always display every snippet in the selected file. If false,
it will offer a menu and let you choose which snippet to
display. You can use --all on the command line to just
enable this once.
By default, Snibbets displays only the code from each
snippet (and optionally block quotes, see below). If you set
all_notes to true, then the full content of each snippet
containing a code block will be returned, allowing you to
see additional notes on the command line. This can be
toggled at runtime with --notes or --no-notes.
The copy setting determines whether the output is copied
to the clipboard in addition to being displayed on STDOUT.
This is the equivalent of running snibbets QUERY | pbcopy
(macOS) or snibbets QUERY | xclip (Linux). This can be
enabled for just one run with --copy on the command line.
Setting it to true in the config will copy to the clipboard
every time a snippet is displayed. On Mac this will work
automatically, on Windows/Linux you may need to install
xclip or xsel.
The editor setting is used to open the config file, and to
open snippets for editing when using the --edit flag. This
setting can be any command line utility (code, subl,
vim, nano, etc.), or on macOS it can be an application
name (BBEdit, VS Code, etc.) or a bundle identifier
(com.sublimetext.4, com.microsoft.VSCode, etc.). If no
editor is set, then the file will be opened by whatever the
system default is (using open on macOS, start on
Windows, or xdg-openon Linux).
The include_blockquotes setting determines whether
blockquotes are included in the output. By default, Snibbets
removes everything other than code blocks (indented or
fenced) from the output it displays. But if you want to
include a note that you’ll see on the command line, you can
put it in a block quote by preceding each line you want to
preserve with a right angle bracket (>).
The interactive setting determines whether menus will be
displayed. This should generally be true, but if you want
silent operation that just displays the best match
automatically, set it to false.
The menus setting will determine what method is used for
displaying interactive menus. If this is not set, it will be
automatically determined in the order of fzf, gum, and
console. You can manually choose to use one of these
options over another by making it the menus setting.
The name_only key will permanently set Snibbets to only
search for snippets by their filename rather than examining
their contents. You can enable this at runtime using
--name-only in the command.
Syntax Highlighting
The highlight key turns on syntax highlighting. This
requires that either pygmentize or skylighting is
available on your system (both available via package
managers like Homebrew). This feature is still in
development and results may be mixed. You can also set
highlighter to pygments or skylight to force using one
highlighter over the other.
Highlighting using Skylighting requires that your snippets
be named with extra extensions defining the lexer to use.
The last extension before .md (or whatever your snippet
extension is set to) should be the one that the highlighter
will recognize as a valid lexer, e.g. my code.jquery.js.md.
You can also define languages in your fenced code blocks by
putting the lexer name right after the opening fence. When
defining multiple snippets in one file that are of different
languages, this method will ensure that each one is properly
highlighted.
If you don’t use either extensions or fenced code labels
with Skylighting, code won’t get highlighted.
To define a snippet as python code, for example:
```python
class EmlServer(SMTPServer):
no = 0
def process_message(self, peer, mailfrom, rcpttos, data):
filename = '%s-%d.eml' % (datetime.now().strftime('%Y%m%d%H%M%S'),
self.no)
f = open(filename, 'w')
```
You can also define a color scheme with highlight_theme.
If you’re using Pygments, run pygmentize -L styles to see
available options. If you’re using Skylighting, you can
reference any theme in the KDE repository. Skylighting
themes are included in Snibbets and can be referenced by
their filename without .theme, or you can install your own
themes and reference them with a full path. (I recommend
nord when using Sylighting.)
You can turn highlighting on or off for a single run using
--highlight or --no-highlight. Syntax highlighting
definitely affects copyable output, so it’s automatically
disabled when piping/redirecting output. When using
--copy, the code sent to the clipboard is not highlighted.
Installing a Syntax Highlighter
Snibbet’s implementation of Skylighting has limited but
better-looking themes, and has some lexers that Pygments
lacks. However, Pygments has more lexers and a wider array
of themes. It also can determine the target syntax
automatically better than Skylighting (which requires the
syntax to be specified – it’s pulled from the extensions of
your snippets), which is why Pygments is the default if it’s
installed and you don’t configure it otherwise.
Install Pygments using Homebrew (brew install pygments) or pip install pygments.
Usage
Snibbets v2.0.40
Usage: snibbets [options] query
-a, --all If a file contains multiple snippets, output all of them (no menu)
-c, --[no-]copy Copy the output to the clibpoard (also displays on STDOUT)
-e, --edit Open the selected snippet in your configured editor
-n, --[no-]name-only Only search file names, not content
--edit-new Create new snippet by opening editor. Title and language prompted.
--edit-new-titled TITLE Create new snippet by opening editor. Pass filename with language extension(s).
--[no-]notes Display the full content of the snippet
-o, --output FORMAT Output format (json|launchbar|*raw)
-p, --paste, --new Interactively create a new snippet from clipboard contents (Mac only)
-q, --quiet Skip menus and display first match
-s, --source FOLDER Snippets folder to search
--configure Open the configuration file in your default editor
--[no-]blockquotes Include block quotes in output
--[no-]highlight Use pygments or skylighting to syntax highlight (if installed)
--nvultra Open the result in nvUltra
--save Save the current command line options to the YAML configuration
-h, --help Display this screen
-v, --version Display version information
--changes Display the changelog (release notes)
If your Snippets folder is set in the config, simply running
snibbets [search query] will perform the search and output
the code blocks, presenting a menu if more than one match is
found or the target file contains more than one snippet.
Selected contents are output raw to STDOUT.
If you have fzf or gum installed, snibbets will use those for menus, providing fuzzy filtering of options.
JSON output
An undocumented output option is -o json, which will
output all of the matches and their code blocks as a JSON
string that can be incorporated into other scripts. It’s
similar to the -o launchbar option, but doesn’t contain
the extra keys required for the LaunchBar action.
Open snippets in your editor
Use the --edit flag on any search to open the found
snippet file in your editor. Configure your default editor
in the config file. snibbets configure will open that, but
if you don’t have an editor set, it might have strange
results. To edit manually, open
~/.config/snibbets/snibbets.yml in your text editor of
choice.
Creating new snippets
From clipboard
I do most of my snippet editing in nvUltra, but sometimes
I have a function in my clipboard that just needs quick
saving and there are so few moving parts to creating a
snippet that it just feels like they could be
automated/simplified. That’s why I added the --paste flag.
If you have a code snippet in your clipboard, you can just
run snibbets --paste (or just -p) and you’ll get a
prompt asking you to describe the snippet (used for
filename) and one asking what language(s) are represented.
You can input the languages as names, e.g. rust,
typescript, or scala, or you can just add file
extensions that represent the language. If I say ts to
that prompt, it will generate an extension of .ts.md and
then add a metadata tag of typescript to the file. The
code from the clipboard goes into a fenced code block in the
document. You can always go add notes to it later, but it’s
a great way to save snippets as you come across them (or
solutions you figure out after a week of banging your head).
This command requires that a clipboard utility be available.
On macOS, you have pbpaste by default and don’t need to do
anything. On Windows and Linux, you’ll need to
install either xclip or xsel.
With editor
You can also create new snippets by opening a skeleton file
in your editor with --edit-new. This will prompt for a
title and languages, create the new file, and open it in
your editor (or in nvUltra with the --nvultra flag). If
you use --edit-new-titled TITLE, the new snippet will get
a filename from TITLE and languages will be determined
from any extension added to the title, or prompted for if
none are found.
Saving Settings When Running
Any time you specify things like a source folder with the
--source flag, or turn on highlighting or name-only
search, you can add the flag --save to write those to your
config and make them the default options.
LaunchBar Action
I’m currently reworking the LaunchBar action, and it doesn’t function very well at this time. I’ll update when I have a chance.
Changelog
Click to expand
2.0.38
2024-08-21 08:54
NEW
--edit-new will create a new snippet and open it in configured editor, prompting for title and language
--edit-new-titled FILENAME will create and edit a new snippet with title, language determined by filename extension or prompted for if missing
2.0.36
2024-04-08 14:25
IMPROVED
Use name: instead of filename: for limiting by extension,
Remove tag: from searches when resorting to find or grep