mirror of
https://github.com/denisidoro/navi
synced 2024-11-22 03:23:05 +00:00
Add option for searching online repositories (#38)
This commit is contained in:
parent
f853181f83
commit
77acda383d
12 changed files with 261 additions and 80 deletions
146
README.md
146
README.md
|
@ -6,37 +6,91 @@ An interactive cheatsheet tool for the command-line so that you'll never say the
|
||||||
— *Oh, it's not in my bash history*<br>
|
— *Oh, it's not in my bash history*<br>
|
||||||
— *Geez, it's almost what I wanted but I need to change some args*
|
— *Geez, it's almost what I wanted but I need to change some args*
|
||||||
|
|
||||||
![Demo](https://user-images.githubusercontent.com/3226564/65380182-69431380-dcac-11e9-9af8-0f7b3c869d0f.gif)
|
![Demo](https://user-images.githubusercontent.com/3226564/65389667-0181dc80-dd2f-11e9-9fac-c875ed7c7b53.gif)
|
||||||
|
|
||||||
**navi** allows you to browse through cheatsheets (that you may write yourself or download from maintainers) and execute commands, prompting for argument values.
|
**navi** allows you to browse through cheatsheets (that you may write yourself or download from maintainers) and execute commands, prompting for argument values.
|
||||||
|
|
||||||
## Installation
|
Table of Contents
|
||||||
|
-----------------
|
||||||
|
|
||||||
**Using [brew](https://brew.sh/):**
|
* [Installation](#installation)
|
||||||
```sh
|
* [Using Homebrew or Linuxbrew](#using-homebrew-or-linuxbrew)
|
||||||
brew install denisidoro/tools/navi
|
* [Using git](#using-git)
|
||||||
```
|
* [Upgrading](#upgrading)
|
||||||
|
* [Usage](#usage)
|
||||||
|
* [Preventing execution](#preventing-execution)
|
||||||
|
* [Pre-filtering](#pre-filtering)
|
||||||
|
* [Searching online repositories](#searching-online-repositories)
|
||||||
|
* [More options](#more-options)
|
||||||
|
* [Trying out online](#trying-out-online)
|
||||||
|
* [Motivation](#motivation)
|
||||||
|
* [Cheatsheets](#cheatsheets)
|
||||||
|
* [Using your own custom cheatsheets](#using-your-own-custom-cheatsheets)
|
||||||
|
* [Submitting cheatsheets](#submitting-cheatsheets)
|
||||||
|
* [Cheatsheet syntax](#cheatsheet-syntax)
|
||||||
|
* [Syntax overview](#syntax-overview)
|
||||||
|
* [Variables](#variables)
|
||||||
|
* [FZF options](#fzf-options)
|
||||||
|
* [Related projects](#related-projects)
|
||||||
|
* [Etymology](#etymology)
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
### Using Homebrew or Linuxbrew
|
||||||
|
|
||||||
|
You can use [Homebrew](http://brew.sh/) or [Linuxbrew](http://linuxbrew.sh/)
|
||||||
|
to install **navi**.
|
||||||
|
|
||||||
|
### Using git
|
||||||
|
|
||||||
|
Alternatively, you can `git clone` this repository and run `make`:
|
||||||
|
|
||||||
**Without brew:**
|
|
||||||
```sh
|
```sh
|
||||||
git clone http://github.com/denisidoro/navi /opt/navi
|
git clone --depth 1 http://github.com/denisidoro/navi /opt/navi
|
||||||
cd /opt/navi
|
cd /opt/navi
|
||||||
sudo make install
|
sudo make install
|
||||||
# install fzf: https://github.com/junegunn/fzf
|
# install fzf: https://github.com/junegunn/fzf
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
Upgrading
|
||||||
|
---------
|
||||||
|
|
||||||
Simply call:
|
**navi** is being actively developed and you might want to upgrade it once in a while. Please follow the instruction below depending on the installation method used:
|
||||||
```sh
|
|
||||||
navi
|
|
||||||
```
|
|
||||||
|
|
||||||
## Trying it out online
|
- brew: `brew update; brew reinstall navi`
|
||||||
|
- git: `cd /opt/navi && sudo make update`
|
||||||
|
|
||||||
Head to [this playground](https://www.katacoda.com/denisidoro/scenarios/navi) for previewing **navi**.
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
## Motivation
|
By simply running `navi` you will be prompted with the default cheatsheets.
|
||||||
|
|
||||||
|
### Preventing execution
|
||||||
|
|
||||||
|
If you run `navi --print`, the selected command 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.
|
||||||
|
|
||||||
|
### Searching online repositories
|
||||||
|
|
||||||
|
If you run `navi search <cmd>`, **navi** will try to download cheatsheets from online repositories as well.
|
||||||
|
|
||||||
|
Please note that these cheatsheets aren't curated by **navi**'s maintainers and should be taken with a grain of salt. If you're not sure about executing these commands, make sure to check the preview window or use the `--print` option.
|
||||||
|
|
||||||
|
### 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](https://www.katacoda.com/denisidoro/scenarios/navi). It'll start a docker container with instructions for you to install and use the tool. Note: login required.
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
----------
|
||||||
|
|
||||||
The main objectives are:
|
The main objectives are:
|
||||||
- to increase discoverability, by finding commands given keywords or descriptions;
|
- to increase discoverability, by finding commands given keywords or descriptions;
|
||||||
|
@ -50,23 +104,31 @@ Or you can launch a browser and search for instructions on Google, but that take
|
||||||
|
|
||||||
**navi**, on the other hand, intends to be a general purpose platform for bookmarking any command at a very low cost.
|
**navi**, on the other hand, intends to be a general purpose platform for bookmarking any command at a very low cost.
|
||||||
|
|
||||||
## Using your own cheatsheets
|
Cheatsheets
|
||||||
|
-----------
|
||||||
|
|
||||||
In this case, you need to pass the directory which contains `.cheat` files as in:
|
### Using your own custom cheatsheets
|
||||||
|
|
||||||
|
In this case, you need to pass a `:`-separated list of separated directories which contain `.cheat`:
|
||||||
```sh
|
```sh
|
||||||
navi --dir "/folder/with/cheats"
|
navi --path "/folder/with/cheats"
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can set an environment variable in your `.bashrc`-like file:
|
Alternatively, you can set an environment variable in your `.bashrc`-like file:
|
||||||
```sh
|
```sh
|
||||||
export NAVI_DIR="/folder/with/cheats"
|
export NAVI_PATH="/folder/with/cheats:/another/folder"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Submitting cheatsheets
|
### Submitting cheatsheets
|
||||||
|
|
||||||
Feel free to fork this project and open a PR for me to include your contributions.
|
Feel free to fork this project and open a PR for me to include your contributions.
|
||||||
|
|
||||||
## .cheat syntax
|
Cheatsheet syntax
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Cheatsheets are describe in `.cheat` files.
|
||||||
|
|
||||||
|
### Syntax overview
|
||||||
|
|
||||||
- lines starting with `%` should contain tags which will be added to any command in a given file;
|
- lines starting with `%` should contain tags which will be added to any command in a given file;
|
||||||
- lines starting with `#` should be descriptions of commands;
|
- lines starting with `#` should be descriptions of commands;
|
||||||
|
@ -83,16 +145,40 @@ git checkout <branch>
|
||||||
$ branch: git branch | awk '{print $NF}'
|
$ branch: git branch | awk '{print $NF}'
|
||||||
```
|
```
|
||||||
|
|
||||||
For advanced usage, please refer to the files in [/cheats](https://github.com/denisidoro/navi/tree/master/cheats).
|
### Variables
|
||||||
|
|
||||||
## Alternatives
|
The interface prompts for variable names inside brackets (eg `<branch>`).
|
||||||
|
|
||||||
- [cmdmenu](https://github.com/amacfie/cmdmenu);
|
The command for generating possible inputs can refer other variables:
|
||||||
- [denisidoro/beavr](https://github.com/denisidoro/beavr);
|
```sh
|
||||||
- [how2](https://github.com/santinic/how2);
|
# If you select 2 for x, the possible values of y will be 12 and 22
|
||||||
- [howdoi](https://github.com/gleitz/howdoi);
|
echo <x> <y>
|
||||||
- [cheat](https://github.com/cheat/cheat).
|
|
||||||
|
|
||||||
## Etymology
|
$ x: echo -e '1\n2\n3' | tr '\n' ' '
|
||||||
|
$ y: echo "$((x+10))" "$((x+20))" | tr '\n' ' '
|
||||||
|
```
|
||||||
|
|
||||||
|
### FZF options
|
||||||
|
|
||||||
|
You can make pick a specific column of a selection and set the number of lines considered as headers:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# This will pick the 3rd column and use the first line as header
|
||||||
|
docker rmi <image_id>
|
||||||
|
|
||||||
|
$ image_id: docker images --- --headers 1 --column 3
|
||||||
|
```
|
||||||
|
|
||||||
|
Related projects
|
||||||
|
----------------
|
||||||
|
|
||||||
|
There are many similar projects out there ([bro](https://github.com/hubsmoke/bro), [eg](https://github.com/srsudar/eg), [cheat.sh](https://github.com/chubin/cheat.sh), [cmdmenu](https://github.com/amacfie/cmdmenu), [cheat](https://github.com/cheat/cheat), [beavr](https://github.com/denisidoro/beavr), [how2](https://github.com/santinic/how2) and [howdoi](https://github.com/gleitz/howdoi), to name a few).
|
||||||
|
|
||||||
|
Most of them provide excellent cheatsheet repositories, but lack a nice UI.
|
||||||
|
|
||||||
|
In any case, **navi** has the option to [search for some of these repositories](#installation).
|
||||||
|
|
||||||
|
Etymology
|
||||||
|
---------
|
||||||
|
|
||||||
In [The Legend of Zelda Ocarina of Time](https://zelda.gamepedia.com/Ocarina_of_Time), [navi](https://zelda.gamepedia.com/Navi) is a character that provides [Link](https://zelda.gamepedia.com/Link) with a variety of clues to help him solve puzzles and progress in his quest.
|
In [The Legend of Zelda Ocarina of Time](https://zelda.gamepedia.com/Ocarina_of_Time), [navi](https://zelda.gamepedia.com/Navi) is a character that provides [Link](https://zelda.gamepedia.com/Link) with a variety of clues to help him solve puzzles and progress in his quest.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
% awk, text processing, string
|
% awk, string
|
||||||
|
|
||||||
# Print nth column
|
# Print last column
|
||||||
awk '{print $<n>}
|
echo '1 2 3' | awk '{print $NF}'
|
|
@ -10,4 +10,4 @@ netstat -tn 2>/dev/null | grep :<port> | awk '{print $5}' | cut -d: -f1 | sort |
|
||||||
dig +short myip.opendns.com @resolver1.opendns.com
|
dig +short myip.opendns.com @resolver1.opendns.com
|
||||||
|
|
||||||
# Find primary, local IP address
|
# Find primary, local IP address
|
||||||
ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'
|
ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | tail -n1
|
34
navi
34
navi
|
@ -5,17 +5,37 @@ export SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
source "${SCRIPT_DIR}/src/main.sh"
|
source "${SCRIPT_DIR}/src/main.sh"
|
||||||
|
|
||||||
##? Command cheatsheet tool
|
##? An interactive cheatsheet tool for the command-line
|
||||||
##?
|
##?
|
||||||
##? Usage:
|
##? Usage:
|
||||||
##? cheats [options]
|
##? cheats [command] [<args>...] [options]
|
||||||
|
##?
|
||||||
|
##? Commands:
|
||||||
|
##? search <cmd> Search for cheatsheets on online repositories
|
||||||
|
##? query <cmd> Pre-filter results
|
||||||
##?
|
##?
|
||||||
##? Options:
|
##? Options:
|
||||||
##? --print Prevent script execution [default: false]
|
##? --print Prevent script execution
|
||||||
##? --no-interpolation Prevent argument interpolation [default: false]
|
##? --path List of paths to look for cheats
|
||||||
##? --no-preview Hide command preview window [default: false]
|
##? --no-interpolation Prevent argument interpolation
|
||||||
|
##? --no-preview Hide command preview window
|
||||||
|
##?
|
||||||
|
##? Examples:
|
||||||
|
##? cheats
|
||||||
|
##? cheats --path '/some/folder:/another/folder'
|
||||||
|
##? cheats search awk
|
||||||
|
##? cheats search docker --print
|
||||||
|
##? cheats query git
|
||||||
|
##?
|
||||||
|
##? More info:
|
||||||
|
##? search
|
||||||
|
##? Queries cheatsheets from http://cheat.sh
|
||||||
|
##? Please note that these cheatsheets may not work out of the box
|
||||||
|
##? Always check the preview window before executing commands!
|
||||||
|
##? full docs
|
||||||
|
##? Please refer to the README at https://github.com/denisidoro/navi
|
||||||
|
|
||||||
VERSION="0.7.0"
|
VERSION="0.8.0"
|
||||||
docs::eval "$@"
|
opts::eval "$@"
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
cheat::find() {
|
cheat::find() {
|
||||||
find "${NAVI_DIR:-"${SCRIPT_DIR}/cheats"}" -iname '*.cheat'
|
for path in $(echo "$NAVI_PATH" | tr ':' '\n'); do
|
||||||
|
find "$path" -iname '*.cheat'
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
cheat::read_many() {
|
cheat::read_many() {
|
||||||
|
|
33
src/docs.sh
33
src/docs.sh
|
@ -1,33 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
docs::extract_help() {
|
|
||||||
local readonly file="$1"
|
|
||||||
grep "^##?" "$file" | cut -c 5-
|
|
||||||
}
|
|
||||||
|
|
||||||
docs::eval() {
|
|
||||||
local wait_for=""
|
|
||||||
|
|
||||||
entry_point="main"
|
|
||||||
print=false
|
|
||||||
interpolation=true
|
|
||||||
preview=true
|
|
||||||
|
|
||||||
for arg in $@; do
|
|
||||||
case $wait_for in
|
|
||||||
dir) NAVI_DIR="$arg"; wait_for="" ;;
|
|
||||||
command-for) query="$(echo "$arg" | tr "^" " ")"; entry_point="preview"; break ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case $arg in
|
|
||||||
--print) print=true ;;
|
|
||||||
--no-interpolation) interpolation=false ;;
|
|
||||||
--version) echo "${VERSION:-unknown}" && exit 0 ;;
|
|
||||||
--help) docs::extract_help "$0" && exit 0 ;;
|
|
||||||
--command-for) wait_for="command-for" ;;
|
|
||||||
--no-preview) preview=false ;;
|
|
||||||
-d|--dir) wait_for="dir" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
20
src/main.sh
20
src/main.sh
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
source "${SCRIPT_DIR}/src/arg.sh"
|
source "${SCRIPT_DIR}/src/arg.sh"
|
||||||
source "${SCRIPT_DIR}/src/cheat.sh"
|
source "${SCRIPT_DIR}/src/cheat.sh"
|
||||||
source "${SCRIPT_DIR}/src/docs.sh"
|
source "${SCRIPT_DIR}/src/health.sh"
|
||||||
source "${SCRIPT_DIR}/src/healthcheck.sh"
|
|
||||||
source "${SCRIPT_DIR}/src/misc.sh"
|
source "${SCRIPT_DIR}/src/misc.sh"
|
||||||
|
source "${SCRIPT_DIR}/src/opts.sh"
|
||||||
|
source "${SCRIPT_DIR}/src/search.sh"
|
||||||
source "${SCRIPT_DIR}/src/selection.sh"
|
source "${SCRIPT_DIR}/src/selection.sh"
|
||||||
source "${SCRIPT_DIR}/src/str.sh"
|
source "${SCRIPT_DIR}/src/str.sh"
|
||||||
source "${SCRIPT_DIR}/src/ui.sh"
|
source "${SCRIPT_DIR}/src/ui.sh"
|
||||||
|
@ -51,7 +52,18 @@ handler::preview() {
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
case ${entry_point:-} in
|
case ${entry_point:-} in
|
||||||
preview) handler::preview "$@" 2>/dev/null || echo "Unable to find command for '${query:-}'" ;;
|
preview)
|
||||||
*) health::fzf && handler::main "$@" ;;
|
handler::preview "$@" \
|
||||||
|
|| echo "Unable to find command for '${query:-}'"
|
||||||
|
;;
|
||||||
|
search)
|
||||||
|
health::fzf
|
||||||
|
search::save "$query" || true
|
||||||
|
handler::main "$@"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
health::fzf
|
||||||
|
handler::main "$@"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
44
src/opts.sh
Normal file
44
src/opts.sh
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
opts::extract_help() {
|
||||||
|
local readonly file="$1"
|
||||||
|
grep "^##?" "$file" | cut -c 5-
|
||||||
|
}
|
||||||
|
|
||||||
|
opts::eval() {
|
||||||
|
local readonly wait_for=""
|
||||||
|
|
||||||
|
entry_point="main"
|
||||||
|
print=false
|
||||||
|
interpolation=true
|
||||||
|
preview=true
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case $wait_for in
|
||||||
|
path) NAVI_PATH="$arg"; wait_for="" ;;
|
||||||
|
preview) query="$(echo "$arg" | tr "^" " ")"; wait_for=""; break ;;
|
||||||
|
search) query="$arg"; wait_for=""; export NAVI_PATH="${NAVI_PATH}:$(search::full_path "$query")"; ;;
|
||||||
|
query) query="$arg"; wait_for="" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case $arg in
|
||||||
|
--print) print=true ;;
|
||||||
|
--no-interpolation) interpolation=false ;;
|
||||||
|
--version) echo "${VERSION:-unknown}" && exit 0 ;;
|
||||||
|
help|--help) opts::extract_help "$0" && exit 0 ;;
|
||||||
|
--command-for) wait_for="command-for" ;;
|
||||||
|
--no-preview) preview=false ;;
|
||||||
|
--path) wait_for="path" ;;
|
||||||
|
search) entry_point="search"; wait_for="search";;
|
||||||
|
preview) entry_point="preview"; wait_for="preview";;
|
||||||
|
q|query) wait_for="query";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
opts::fallback_path() {
|
||||||
|
echo "${NAVI_DIR:-${SCRIPT_DIR}/cheats}"
|
||||||
|
}
|
||||||
|
|
||||||
|
export NAVI_PATH="${NAVI_PATH:-$(opts::fallback_path)}"
|
39
src/search.sh
Normal file
39
src/search.sh
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
search::cheat() {
|
||||||
|
local readonly cmd="$(echo "$1" | str::first_word)"
|
||||||
|
|
||||||
|
echo "% ${cmd}, cheatsh"
|
||||||
|
echo
|
||||||
|
curl -s "${CHTSH_URL:-http://cht.sh}/${cmd}?T"
|
||||||
|
}
|
||||||
|
|
||||||
|
search::filename() {
|
||||||
|
local readonly cmd="$(echo "$1" | str::first_word)"
|
||||||
|
|
||||||
|
echo "${cmd}_cheatsh" \
|
||||||
|
| head -n1 \
|
||||||
|
| awk '{print $NF}' \
|
||||||
|
| xargs \
|
||||||
|
| tr ' ' '_'
|
||||||
|
}
|
||||||
|
|
||||||
|
search::full_path() {
|
||||||
|
local readonly cmd="$(echo "$1" | str::first_word)"
|
||||||
|
|
||||||
|
echo "/tmp/navi/$(search::filename "$cmd").cheat"
|
||||||
|
}
|
||||||
|
|
||||||
|
search::save() {
|
||||||
|
local readonly cmd="$(echo "$1" | str::first_word)"
|
||||||
|
|
||||||
|
local readonly filepath="$(search::full_path "$cmd")"
|
||||||
|
local readonly filedir="$(dirname "$filepath")"
|
||||||
|
|
||||||
|
if [ -f "$filepath" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$filedir" &> /dev/null || true
|
||||||
|
search::cheat "$cmd" > "$filepath"
|
||||||
|
}
|
|
@ -25,3 +25,7 @@ str::last_paragraph_line() {
|
||||||
awk '(!NF) { exit } { print $0 }' \
|
awk '(!NF) { exit } { print $0 }' \
|
||||||
| tail -n1
|
| tail -n1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
str::first_word() {
|
||||||
|
awk '{print $1}'
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ ui::pick() {
|
||||||
ui::select() {
|
ui::select() {
|
||||||
local readonly cheats="$1"
|
local readonly cheats="$1"
|
||||||
local readonly script_path="$(which navi | head -n1 || echo "${SCRIPT_DIR}/navi")"
|
local readonly script_path="$(which navi | head -n1 || echo "${SCRIPT_DIR}/navi")"
|
||||||
local readonly preview_cmd="echo {} | tr ' ' '^' | xargs -I% \"${script_path}\" --command-for %"
|
local readonly preview_cmd="echo \"{}\" | tr ' ' '^' | xargs -I% \"${script_path}\" preview %"
|
||||||
|
|
||||||
local args=()
|
local args=()
|
||||||
args+=("-i")
|
args+=("-i")
|
||||||
|
@ -16,6 +16,13 @@ ui::select() {
|
||||||
args+=("--preview"); args+=("$preview_cmd")
|
args+=("--preview"); args+=("$preview_cmd")
|
||||||
args+=("--preview-window"); args+=("up:1")
|
args+=("--preview-window"); args+=("up:1")
|
||||||
fi
|
fi
|
||||||
|
if [ -n "${query:-}" ]; then
|
||||||
|
args+=("--query=${query} ")
|
||||||
|
fi
|
||||||
|
if [ "${entry_point:-}" = "search" ]; then
|
||||||
|
args+=("--header")
|
||||||
|
args+=("Displaying online results. Please refer to 'navi --help' for details")
|
||||||
|
fi
|
||||||
|
|
||||||
echo "$cheats" \
|
echo "$cheats" \
|
||||||
| cheat::read_many \
|
| cheat::read_many \
|
||||||
|
|
Loading…
Reference in a new issue