This PR makes navi stop bundling `.cheat` files and makes it able to download from repos on GitHub, using a standardized config directory. - it fixes #233 and #237 - it makes #52, #256 and #257 much easier to implement - it makes #40 harder to implement - it's an alternate solution to #140 - it's influenced by #238 and #254. This PR ended up being much bigger than I would like so if you could review only this description it would be already very nice! When navi is started for the first time, a welcome cheatsheet is shown: ![Screenshot at 2020-03-15 10-20-04](https://user-images.githubusercontent.com/3226564/76702240-19fffd80-66a7-11ea-884f-97c565bc1ead.png) If the user selects the first option, the user is prompted to download `.cheat`s from https://github.com/denisidoro/cheats: ![Screenshot at 2020-03-15 10-20-35](https://user-images.githubusercontent.com/3226564/76702239-19fffd80-66a7-11ea-8f69-324f669b1e01.png) ![Screenshot at 2020-03-15 10-22-59](https://user-images.githubusercontent.com/3226564/76702236-18363a00-66a7-11ea-8ff4-53b497f85888.png) The config folder is populated: ![Screenshot at 2020-03-15 10-21-11](https://user-images.githubusercontent.com/3226564/76702238-19676700-66a7-11ea-8367-3e7b5733f2b4.png) When run again, cheats are available: ![Screenshot at 2020-03-15 10-21-34](https://user-images.githubusercontent.com/3226564/76702237-19676700-66a7-11ea-9c2a-d8829340f3e9.png) ### Breaking changes In order to make navi stop bundling shell widgets as well, a breaking change has been introduced: `source $(navi widget bash)` won't work anymore. It should be `source <(navi widget bash)` now. Any ideas on how to make this transition more graceful?
8.8 KiB
navi
ℹ️ If you're here because you upgraded navi and are having some issues, please check this thread.
An interactive cheatsheet tool for the command-line.
navi allows you to browse through cheatsheets (that you may write yourself or download from maintainers) and execute commands, with argument values prompted to you. It uses fzf under the hood.
It can be either used as a command or as a shell widget (à la Ctrl-R).
Table of contents
- Installation
- Usage
- Trying out online
- Cheatsheets
- Cheatsheet syntax
- List customization
- Motivation
- Related projects
- Etymology
Installation
Using Homebrew or Linuxbrew
brew install denisidoro/tools/navi
Alternatively, you can use the official formula (but it will install a very old version of navi):
brew install navi
Using one-liner script
bash <(curl -sL https://raw.githubusercontent.com/denisidoro/navi/master/scripts/install)
Downloading pre-compiled binaries
You can download binaries here.
Building from source
git clone https://github.com/denisidoro/navi ~/.navi
cd ~/.navi
make install # or make SOURCE_DIR=/opt/navi BIN_DIR=/usr/local/bin install
Usage
By simply running navi
you will be prompted with the default cheatsheets.
Preventing execution
If you run navi --print
, the selected snippet won't be executed. It will be printed to stdout instead.
Pre-filtering
If you run navi query <cmd>
, the results will be pre-filtered.
Shell widget
You can use navi as a widget to your shell. This way, your history is correctly populated and you can edit the command as you wish before executing it.
In order to use it, add this line to your .bashrc
-like file:
# bash
source <(navi widget bash)
# zsh
source <(navi widget zsh)
# fish
navi widget fish | source
By default, Ctrl+G
is assigned to launching navi. If you want to change the keybinding, replace the argument of bind
or bindkey
in the widget file.
More options
Please refer to navi --help
for more details.
Trying out online
If you don't have access to bash at the moment and you want to live preview navi, head to this playground. It'll start a docker container with instructions for you to install and use the tool. Note: login required.
Cheatsheets
Using your own custom cheatsheets
In this case, you need to pass a :
-separated list of separated directories which contain .cheat
files:
navi --path "/folder/with/cheats"
Alternatively, you can set an environment variable in your .bashrc
-like file:
export NAVI_PATH="/folder/with/cheats:/another/folder"
Submitting cheatsheets
Feel free to open a PR on https://github.com/denisidoro/cheats for me to include your contributions.
Cheatsheet syntax
Cheatsheets are described in .cheat
files.
Syntax overview
- lines starting with
%
determine the start of a new cheatsheet and should contain tags; - lines starting with
#
should be descriptions of commands; - lines starting with
;
are ignored. You can use them for metacomments; - lines starting with
$
should contain commands that generate a list of possible values for a given argument; - all the other non-empty lines are considered as executable commands.
For example, this is a valid .cheat
file:
% git, code
# Change branch
git checkout <branch>
$ branch: git branch | awk '{print $NF}'
It's irrelevant how many files are used to store cheatsheets. They can be all in a single file if you wish, as long as you split them accordingly with lines starting with %
.
Commands may be multiline:
# This will output "foo\nyes"
echo foo
true \
&& echo yes \
|| echo no
Variables
The interface prompts for variable names inside brackets (eg <branch>
).
Variable names should only include alphanumeric characters and _
.
Variable dependency
The command for generating possible inputs can refer other variables:
# If you select 2 for x, the possible values of y will be 12 and 22
echo <x> <y>
$ x: echo -e '1\n2\n3'
$ y: echo -e "$((x+10))\n$((x+20))"
Variable options
For lines starting with $
you can add use---
to parse parameters to fzf
.
--allow-extra
(experimental): handlesfzf
option--print-query
.enter
will prefer a selection,tab
will prefer the query typed.--multi
: forwarded option tofzf
.--header-lines
: forwarded option tofzf
--column
: forwarded option tofzf
.--delimiter
: forwarded option tofzf
.
Table formatting
You can pick a specific column of a selection and set the number of lines considered as headers via --column
, --delimiter
and --header-lines
:
# This will pick the 3rd column and use the first line as header
docker rmi <image_id>
$ image_id: docker images --- --column 3 --header-lines 1 --delimiter '\s\s+'
Multiple choice
You can select multiple values via --multi
and hitting <TAB>
:
# The resulting command will be something like: cat "a.txt" "b.txt"
cat <files>
$ files: ls --- --multi
List customization
Lists can be stylized with the $FZF_DEFAULT_OPTS environment variable or --fzf-overrides
. This way, you can change the color scheme, for example.
Motivation
The main objectives are:
- to increase discoverability, by finding snippets given keywords or descriptions;
- to prevent you from running auxiliar commands, copying the result into the clipboard and then pasting into the original command;
- to easily share one-liners with others so that they don't need to figure out how to write the commands;
- to improve terminal usage as a whole.
Sure, you can find autocompleters out there for all your favorite commands. However, they are very specific and each one may offer a different learning curve.
Or you can launch a browser and search for instructions on Google, but that takes some time.
navi, on the other hand, intends to be a general purpose platform for bookmarking any snippet at a very low cost.
Related projects
There are many similar projects out there (bro, eg, cheat.sh, tldr, cmdmenu, cheat, beavr, how2 and howdoi, to name a few).
Most of them provide excellent cheatsheet repositories, but lack a nice UI and argument suggestions.
Etymology
In The Legend of Zelda Ocarina of Time, navi is a character that provides Link with a variety of clues to help him solve puzzles and progress in his quest.