5.3 KiB
Cheatsheet syntax
- Syntax overview
- Folder structure
- Variables
- Advanced variable options
- Variable dependency
- Multiline snippets
- Variable as multiple arguments
- Aliases
Syntax overview
Cheatsheets are described in .cheat (or .cheat.md) files that look like this:
% git, code
# Change branch
git checkout <branch>
$ branch: git branch | awk '{print $NF}'
Lines starting with:
%: determine the start of a new cheatsheet and should contain tags#: should be descriptions of commands;: are ignored. You can use them for metacomments$: should contain commands that generate a list of possible values for a given argument ℹ️@: should contain tags whose associated cheatsheet you want to base on ℹ️
All the other non-empty lines are considered as executable commands.
Tip
If you are editing cheatsheets in Visual Studio Code, you could enable syntax highlighting by installing this extension: @yanivmo/navi-cheatsheet-language.
You can place commands in code blocks fenced with triple backticks (```).
% git, code
# Change branch
```sh
git checkout <branch>
```
$ branch: git branch | awk '{print $NF}'
Variables
The interface prompts for variable names inside brackets (eg <branch>).
Variable names should only include alphanumeric characters and _.
If there's a corresponding line starting with $ for a variable, suggestions will be displayed. Otherwise, the user will be able to type any value for it.
If you hit <tab> the query typed will be preferred. If you hit <enter> the selection will be preferred.
Advanced variable options
For lines starting with $ you can use --- to customize the behavior of fzf or how the value is going to be used:
# This will pick the 3rd column and use the first line as header
docker rmi <image_id>
# Even though "false/true" is displayed, this will print "0/1"
echo <mapped>
$ image_id: docker images --- --column 3 --header-lines 1 --delimiter '\s\s+'
$ mapped: echo 'false true' | tr ' ' '\n' --- --map "grep -q t && echo 1 || echo 0"
The supported parameters are:
--column <number>: extracts a single column from the selected result--map <bash_code>: (experimental) applies a map function to the selected variable value--prevent-extra: (experimental) limits the user to select one of the suggestions--fzf-overrides <arg>: (experimental) applies arbitraryfzfoverrides--expand: (experimental) converts each line into a separate argument
In addition, it's possible to forward the following parameters to fzf:
--multi--header-lines <number>--delimiter <regex>--query <text>--filter <text>--header <text>--preview <bash_code>--preview-window <text>
Variable dependency
The command for generating possible inputs can implicitly refer other variables by using the <varname> syntax:
# Should print /my/pictures/wallpapers
echo "<wallpaper_folder>"
$ pictures_folder: echo "/my/pictures"
$ wallpaper_folder: echo "<pictures_folder>/wallpapers"
If you want to make dependencies explicit, you can use the $varname syntax:
# If you select "hello" for <x>, the possible values of <y> will be "hello foo" and "hello bar"
echo <x> <y>
# If you want to ignore the contents of <x> and only print <y>
: <x>; echo <y>
$ x: echo "hello hi" | tr ' ' '\n'
$ y: echo "$x foo;$x bar" | tr ';' '\n'
Extending cheatsheets
With the @ same tags from other cheatsheet syntax you can reuse the same variable in multiple cheatsheets.
% dirs, common
$ pictures_folder: echo "/my/pictures"
% wallpapers
@ dirs, common
# Should print /my/pictures/wallpapers
echo "<pictures_folder>/wallpapers"
% screenshots
@ dirs, common
# Should print /my/pictures/screenshots
echo "<pictures_folder>/screenshots"
Multiline snippets
Commands may be multiline:
# This will output "foo\nyes"
echo foo
true \
&& echo yes \
|| echo no
Variable as multiple arguments
# This will result into: cat "file1.json" "file2.json"
cat <jsons>
$ jsons: find . -iname '*.json' -type f -print --- --multi --expand
Aliases
navi doesn't have support for aliases as first-class citizens at the moment.
However, it is trivial to create aliases using navi + a few conventions.
For example, suppose you decide to end some of your commands with :: <some_alias>:
% aliases
# This is one command :: el
echo lorem ipsum
# This is another command :: ef
echo foo bar
Then, if you use navi as a shell scripting tool, you could add something similar to this in your .bashrc-like file:
navialias() {
navi --query ":: $1" --best-match
}
alias el="navialias el"
alias ef="navialias ef"
If you don't want to use these conventions, you can even add full comments in your aliases:
navibestmatch() {
navi --query "$1" --best-match
}
alias el="navibestmatch 'This is one command'"
alias ef="navibestmatch 'This is another command'"