navi/docs/cheatsheet_syntax.md

5.1 KiB
Raw Permalink Blame History

Cheatsheet syntax

Syntax overview

Cheatsheets are described in .cheat 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.

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 arbitrary fzf overrides
  • --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'"