Initial cheat repo support (#258)

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?
This commit is contained in:
Denis Isidoro 2020-03-15 13:46:58 -03:00 committed by GitHub
parent f8e5ec844a
commit de16846aba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 617 additions and 1640 deletions

325
Cargo.lock generated
View file

@ -16,6 +16,16 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
version = "0.2.14"
@ -26,11 +36,44 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "base64"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2b_simd"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clap"
version = "2.33.0"
@ -45,6 +88,21 @@ dependencies = [
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "derive_more"
version = "0.14.1"
@ -56,6 +114,50 @@ dependencies = [
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dirs"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dirs-sys"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "git2"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libgit2-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)",
"url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "heck"
version = "0.3.1"
@ -72,6 +174,24 @@ dependencies = [
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "idna"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "jobserver"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -82,6 +202,56 @@ name = "libc"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libgit2-sys"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libssh2-sys 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libssh2-sys"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libz-sys"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
version = "2.3.3"
@ -89,14 +259,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "navi"
version = "2.0.11"
version = "2.1.0"
dependencies = [
"dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"git2 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw_tty 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"terminal_size 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -104,6 +277,33 @@ name = "numtoa"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl-probe"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "openssl-sys"
version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pkg-config"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro-error"
version = "0.4.9"
@ -182,6 +382,16 @@ dependencies = [
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_users"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "1.3.4"
@ -198,6 +408,17 @@ name = "regex-syntax"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rust-argon2"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
@ -216,6 +437,14 @@ dependencies = [
"syn 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver"
version = "0.9.0"
@ -229,6 +458,11 @@ name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.8.0"
@ -322,6 +556,22 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-segmentation"
version = "1.6.0"
@ -342,11 +592,41 @@ name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vcpkg"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.8"
@ -361,6 +641,14 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@ -369,16 +657,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum arrayref 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum blake2b_simd 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
"checksum cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)" = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839"
"checksum dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
"checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum git2 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c1af51ea8a906616af45a4ce78eacf25860f7a13ae7bf8a814693f0f4037a26"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hermit-abi 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
"checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
"checksum libgit2-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4870c781f6063efb83150cd22c1ddf6ecf58531419e7570cdcced46970f64a16"
"checksum libssh2-sys 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7bb70f29dc7c31d32c97577f13f41221af981b31248083e347b7f2c39225a6bc"
"checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
"checksum openssl-sys 0.9.54 (registry+https://github.com/rust-lang/crates.io-index)" = "1024c0a59774200a555087a6da3f253a9095a5f344e353b212ac4c8b8e450986"
"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum proc-macro-error 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242"
"checksum proc-macro-error-attr 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
@ -388,12 +700,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum raw_tty 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51f512d7504049ef0d3f5d48d8aa5129beaea4fccfaf5c500c9b60101394f8b1"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum redox_users 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
"checksum regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8"
"checksum regex-syntax 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06"
"checksum rust-argon2 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rustversion 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98"
"checksum structopt-derive 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64"
@ -404,11 +720,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
"checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View file

@ -1,6 +1,6 @@
[package]
name = "navi"
version = "2.0.11"
version = "2.1.0"
authors = ["Denis Isidoro <denis_isidoro@live.com>"]
edition = "2018"
@ -12,4 +12,7 @@ structopt = "0.3"
termion = "1.5.5"
raw_tty = "0.1.0"
lazy_static = "1.4.0"
dirs = "2.0.0"
terminal_size = "0.1.10"
git2 = "0.10.0"
walkdir = "2"

View file

@ -91,19 +91,17 @@ You can use **navi** as a widget to your shell. This way, your history is correc
In order to use it, add this line to your `.bashrc`-like file:
```sh
# bash
source "$(navi widget bash)"
source <(navi widget bash)
# zsh
source "$(navi widget zsh)"
source <(navi widget zsh)
# fish
source (navi widget 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](https://github.com/denisidoro/navi/search?q=filename%3Anavi.plugin.*&unscoped_q=filename%3Anavi.plugin.*).
If you want a widget for other shells, please upvote [this issue](https://github.com/denisidoro/navi/issues/37).
### More options
Please refer to `navi --help` for more details.
@ -130,7 +128,7 @@ export NAVI_PATH="/folder/with/cheats:/another/folder"
### Submitting cheatsheets
Feel free to fork this project and open a PR for me to include your contributions.
Feel free to open a PR on https://github.com/denisidoro/cheats for me to include your contributions.
Cheatsheet syntax
-----------------
@ -139,7 +137,7 @@ Cheatsheets are described in `.cheat` files.
### Syntax overview
- lines starting with `%` determine the start of a new cheatsheet. They should contain tags which will be added to any command in a given file;
- 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;
@ -159,7 +157,7 @@ It's irrelevant how many files are used to store cheatsheets. They can be all in
Commands may be multiline:
```sh
# This will output foo\nyes
# This will output "foo\nyes"
echo foo
true \
&& echo yes \

View file

@ -1,27 +0,0 @@
% android, device
# Get property
adb -s <device> shell getprop <property>
# Install APK
adb -s <device> install -r <path>
# Uninstall package
adb -s <device> uninstall -r <package>
# Clear user data for package
adb -s <device> shell pm clear <package>
# Dispatch a deep-link / open URI
adb -s <device> shell am start <uri>
$ device: adb devices --- --headers 1 --column 1
% android, emulator
# Start emulator
"$ANDROID_HOME/tools/emulator" -avd <emulator> -netdelay none -netspeed full
$ emulator: "$ANDROID_HOME/tools/emulator" -list-avds

View file

@ -1,55 +0,0 @@
% apt
# Update content listings from package repositories
apt update
# List all available packages
apt list
# List all installed packages
apt list --installed
# Info about package (including description)
apt show -a <package-name>
# Show versions and archive areas of available package
apt list -a <package-name>
# Search in repository (packages and description)
apt search <query>
# Check updates for installed packages
apt list --upgradeable
# Update all installed packages
apt upgrade
# Upgrade all installed packages (add/remove dependencies)
apt full-upgrade
# Update specific/individual package
apt install --only-upgrade <package-name>
# Downgrade package to a specific version
apt install <package-name>=<package-version>
# Install a package from repository
apt install <package-name>
# Remove/delete package
apt remove <package-name>
# Remove/delete package (with config files)
apt purge <package-name>
# Install local dpkg package
apt install <filepath-deb>
# List dependencies of package
apt depends <package-name>
# List reverse dependencies of package
apt rdepends <package-name>
# Remove un-needed packages and dependencies
apt autoremove

View file

@ -1,36 +0,0 @@
% brew, cask
# update brew
brew update
# upgrade brew
brew upgrade
# get info for a package
brew info <package>
# get info for a cask
brew cask info <casks>
# install a package
brew install <package>
# install a cask
brew cask install <casks>
# uninstall a package
brew uninstall <installed>
# uninstall a cask
brew cask uninstall <caskinstalled>
# edit package
brew edit <package>
# edit cask
brew cask edit <casks>
$ package: brew search
$ casks: brew search --casks
$ installed: brew list
$ caskinstalled: brew cask list

View file

@ -1,130 +0,0 @@
% cf, pcf, pivotal cloud foundry, paas
### Information
# Get the extended list of help
cf help -a
# Get current version of cf
cf version
# Get information about current org
cf org
# Get information about current space
cf space
# Get information about current target
cf target
# Get list of all apps
cf apps
# Get list of all services
cf services
# Get list of all routes
cf routes
# Get list of all network policies
cf network-policies
### Login
# Login to your CF/PCF instance
cf login -a <API_URL>
# Login to your CF/PCF instance with username and password
cf login -a <API_URL> -u <USERNAME> -p <PASSWORD>
# Login and specify target directly
cf login -a <API_URL> -u <USERNAME> -p <PASSWORD> -o <ORG> -s <SPACE>
### Target
# Set target org
cf target -o <org>
# Set target space
cf target -o <org> -s <space>
### Application manipulation
## Information
# Get the guid of an app
cf app <app> --guid
# Get the status of an app
cf app <app>
## Status
# Start an app
cf start <app>
# Stop an app
cf stop <app>
# Restart an app
cf restart <app>
# Rebuild the application package and restart
cf restage <app>
## Deletion
# Delete an app
cf delete <app>
# Delete an app no prompt
cf delete <app> -f
# Delete an app and routes
cf delete <app> -r
### Networking - A bit slow due to filtering
# Add network policy
cf add-network-policy <add_network_source> \
--destination-app <add_network_destination> \
--protocol <add_network_protocol> \
--port <add_network_port>
# Remove network-policy
cf remove-network-policy <remove_network_source> \
--destination-app <remove_network_destination> \
--protocol <remove_network_protocol> \
--port <remove_network_port>
### Services
# Bind a service to an application
cf bind-service <app> <service>
# Unbind a service from an application
cf unbind-service <app> <service>
# Share a service between spaces
cf share-service <service> -o <org> -s <space>
# Unshare a service from a spaces
cf unshare-service <service> -o <org> -s <space>
# Autocomplete variables
$ org: cf orgs | awk 'NR>3 {print}'
$ space: cf target -o "$org" > /dev/null && cf spaces | awk 'NR>3 {print $1}'
$ service: cf services | awk 'NR>3 {print $1}' | sed '/TIP:/d'
$ route: cf routes | awk 'NR>3 {if ($4 ~ /^\//){ print $2 "." $3 $4} else {print $2 "." $3}}'
$ app: cf apps | awk 'NR>4 {print $1}'
$ add_network_source: cf apps | awk 'NR>4 {print $1}'
$ add_network_destination: cf apps | awk 'NR>4 {print $1}' | sed "/$add_network_source/d"
$ add_network_protocol: printf "tcp \nudp"
$ remove_network_source: cf network-policies | awk 'NR>3 {print $1}' | uniq
$ remove_network_destination: cf network-policies | grep "^$remove_network_source" | awk '{print $2}' | uniq
$ remove_network_protocol: cf network-policies | grep "^$remove_network_source" | grep "$remove_network_destination" | awk '{print $3}' | uniq
$ remove_network_port: cf network-policies | grep "^$remove_network_source" | grep "$remove_network_destination" | awk '{print $4}' | uniq

View file

@ -1,24 +0,0 @@
% compression
# Create a tar containing files
tar cf <name>.tar <files>
# Extract the files from a tar
tar xf <tar_file>
# Create a tar with Gzip compression
tar czf <name>.tar.gz <files>
# Extract a tar using Gzip
tar xzf <targz_file>
# Compress file and appends .gz to its name
gzip <path>
# Decompress compressed file
gzip -d <gz_file>
$ path: ls
$ tar_file: ls *.tar
$ targz_file: ls *.tar.gz
$ gz_file: ls *.gz

View file

@ -1,7 +0,0 @@
% crontab, schedule
# List cron jobs
crontab -l
# Edit cron job
crontab -e

View file

@ -1,71 +0,0 @@
% docker
# Remove an image
docker image rm <image_id>
# Delete an image from the local image store
docker rmi <image_id>
# List all images that are locally stored with the Docker engine
docker images
# Build an image from the Dockerfile in the current directory and tag the image
docker build -t <image>:<version> .
# Pull an image from a registry
docker pull <image>:<version>
# Stop a running container through SIGTERM
docker stop <container_id>
# Stop a running container through SIGKILL
docker kill <container_id>
# List the networks
docker network ls
# List the running containers
docker ps
# Delete all running and stopped containers
docker rm -f $(docker ps -aq)
# Create a new bash process inside the container and connect it to the terminal
docker exec -it <container_id> bash
# Print the last lines of a containers logs
docker logs --tail 100 <container_id> | less
# Print the last lines of a container's logs and following its logs
docker logs --tail 100 <container_id> -f
# Create new network
docker network create <network_name>
$ image_id: docker images --- --headers 1 --column 3
$ container_id: docker ps --- --headers 1 --column 1
% docker-compose
# Builds, (re)creates, starts, and attaches to containers for all services
docker-compose up
# Builds, (re)creates, starts, and dettaches to containers for all services
docker-compose up -d
# Builds, (re)creates, starts, and attaches to containers for a service
docker-compose up -d <service_name>
# Builds, (re)creates, starts, and dettaches to containers for a service
docker-compose up -d <service_name>
# Print the last lines of a services logs
docker-compose logs --tail 100 <service_name> | less
# Print the last lines of a service's logs and following its logs
docker-compose logs -f --tail 100 <service_name>
# Stops containers and removes containers, networks created by up
docker-compose down

View file

@ -1,47 +0,0 @@
% firebase, account
# Login
firebase login
# Logout
firebase logout
% firebase, local
# Init a new project
firebase init [feature]
# List of projects you have access to
firebase projects:list
# Set current project
firebase use [options] [alias_or_project_id]
# Serve all allowed content
firebase serve
# Serve specific feature
firebase serve --only <feature>
# Serve specific content for feature
firebase serve --only <feature>:<content_folder>
% firebase, remote
# Deploy projects
firebase deploy
# Deploy specific feature
firebase deploy --only <feature>
# Deploy specific content for feature
firebase deploy --only <feature>:<content_folder>
% firebase, ci
# Generate a token for CI
firebase login:ci
# Deploy from CI
firebase deploy --token <token_for_ci>

View file

@ -1,154 +0,0 @@
% fly, concourse, pipeline, ci-cd
# Show Concourse help
fly --help
# List all Concourse target aliases
fly targets
# Delete saved configuration for a target
fly --target <target> delete-target
# Sync concourse version with target
fly --target <target> sync
# Login to a selected target
fly --target <target> login
# List all teams within a Concourse target
fly --target <target> teams
# Show the configuration for a given team
fly --target <target> get-team --team-name <team>
# Delete a team from Concourse installation
fly --target <target> destroy-team -n <team>
# list all pipelines
fly --target <target> pipelines
# Make pipeline public
fly --target <target> expose-pipeline --pipeline <pipeline>
# Make pipeline private
fly --target <target> hide-pipeline --pipeline <pipeline>
# Get pipeline / show pipeline
fly --target <target> get-pipeline --pipeline <pipeline>
# Pause a pipeline
fly --target <target> pause-pipeline --pipeline <pipeline>
# Unpause a pipeline
fly --target <target> unpause-pipeline --pipeline <pipeline>
# Rename a pipeline
fly --target <target> rename-pipeline --old-name <pipeline> \
--new-name <new_pipeline>
# Create pipeline without variables
fly --target <target> set-pipeline --pipeline <new_pipeline> \
--config <pipeline_yaml>
# Create pipeline with variables
fly --target <target> set-pipeline --pipeline <new_pipeline> \
--config <pipeline_yaml> --load-vars-from <pipeline_vars>
# Update pipeline without variables
fly --target <target> set-pipeline --pipeline <pipeline> \
--config <pipeline_yaml>
# Update pipeline with variables
fly --target <target> set-pipeline --pipeline <new_pipeline> \
--config <pipeline_yaml> --load-vars-from <pipeline_vars>
# Validate pipeline without variables
fly validate-pipeline --config <pipeline_yaml>
# Validate pipeline with variables
fly validate-pipeline --config <pipeline_yaml> \
--load-vars-from <pipeline_vars>
# Delete a pipeline
fly --target <target> destroy-pipeline --pipeline <pipeline>
# List the jobs of a pipeline
fly --target <target> jobs --pipeline <pipeline>
# Pause a job on a pipeline
fly --target <target> pause-job --job=<pipeline>/<job>
# Unpause a job on a pipeline
fly --target <target> unpause-job --job=<pipeline>/<job>
# Trigger a job on a pipeline
fly --target <target> trigger-job --job=<pipeline>/<job>
# List the latest builds for a job
fly --target <target> builds --job=<pipeline>/<job> \
--count=<amount>
# Hijack a pipeline job for debugging
fly --target <target> hijack --job=<pipeline>/<job> \
--build <build>
# Watch the log output from a running job
fly --target <target> watch --job=<pipeline>/<job> \
--build <build>
# Abort a running build
fly --target <target> abort-build --job=<pipeline>/<job> \
--build <build>
# List the users who have been active for the past 2 months
fly --target <target> active-users
# List the access of the current user
fly --target <target> userinfo
# List the resources for a pipeline
fly --target <target> resources --pipeline <pipeline>
# Check a resource
fly --target <target> check-resource --resource=<pipeline>/<resource>
# List the versions of a resource
fly --target <target> resource-versions --resource=<pipeline>/<resource>
# Pin a resource version
fly --target <target> pin-resource --resource=<pipeline>/<resource> \
--version <version>
# Unpin a resource version
fly --target <target> unpin-resource --resource=<pipeline>/<resource>
$ target: fly targets --- --column 1
$ team: fly -t "$target" teams
$ job: fly -t "$target" jobs --pipeline "$pipeline" --- --column 1
$ build: fly -t "$target" builds --job="$pipeline"/"$job" --- --column 3
$ resource: fly -t "$target" resources --pipeline "$pipeline" --- --column 1
$ version: fly -t "$target" resource-versions --resource="$pipeline"/"$resource" --- --column 2
$ pipeline: fly -t "$target" pipelines --- --column 1
$ pipeline_yaml: ls *.yml || ls
$ pipeline_vars: ls *.yml || ls

View file

@ -1,108 +0,0 @@
% git
# Set global git user name
git config --global user.name <name>
# Set global git user email
git config --global user.email <email>
# Initializes a git repository
git init
# Clone a git repository
git clone -b <branch_name> <repository> <clone_directory>
# View all available remote for a git repository
git remote --verbose
# Adds a remote for a git repository
git remote add <remote_name> <remote_url>
# Renames a remote for a git repository
git remote rename <old_remote_name> <new_remote_name>
# Remove a remote for a git repository
git remote remove <remote_name>
# Checkout to branch
git checkout <branch>
# Displays the current status of a git repository
git status
# Displays unstaged changes for file
cd <toplevel_directory>; \
git diff <unstaged_files>
# Stage single or multiple files
cd <toplevel_directory>; \
git add <changed_files>;
# Stage all files in project
git add -A
# Saves the changes to a file in a commit
git commit -m <message>
# Pushes committed changes to remote repository
git push -u <remote_name> <branch_name>
# Pushes changes to a remote repository overwriting another branch
git push <remote_name> <branch>:<branch_to_overwrite>
# Overwrites remote branch with local branch changes
git push <remote_name> <branch_name> -f
# Pulls changes to a remote repo to the local repo
git pull --ff-only
# Merges changes on one branch into current branch
git merge <branch_name>
# Abort the current conflict resolution process, and try to reconstruct the pre-merge state.
git merge --abort
# Displays log of commits for a repo
git log
# Displays formatted log of commits for a repo
git log --all --decorate --oneline --graph
# Clear everything
git clean -dxf
# Sign all commits in a branch based on master
git rebase master -S -f
# See all open pull requests of a user on Github
navi fn url::open 'https://github.com/pulls?&q=author:<user>+is:open+is:pr'
# Checkout a branch from a fork
git fetch origin pull/<pr_number>/head:pr/<pr_number> \
&& git checkout pr/<pr_number>
# Add a new module
git submodule add <repository> <path>
# Update module
git submodule update --init
# Update module without init
git submodule update
# Pull all submodules
git submodule foreach git pull origin master
# Update all submodules
git submodule update --init --recursive
# Skip git hooks
git commit --no-verify
# Create new branch from current HEAD
git checkout -b <new_branch_name>
$ branch: git branch | awk '{print $NF}'
$ toplevel_directory: git rev-parse --show-toplevel
$ unstaged_files: git status --untracked-files=no -s --porcelain | awk '{print $NF}' --- --multi true
$ changed_files: git status --untracked-files=all -s --porcelain | awk '{print $NF}' --- --multi true

View file

@ -1,37 +0,0 @@
% gpg
# gpg version
gpg --version
# gpg generate key
gpg --gen-key
# list keys
gpg --list-keys
# distribute public key to key server
gpg --keyserver <key_server> --send-keys <public_key>
# export public key
gpg --output <filename_gpg> --export <key_name>
# import public key
gpg --import <filename_gpg>
# encrypt document
gpg --output <output_filename_gpg> --encrypt --recipient <public_key> <input_filename>
# decrypt document
gpg --output <filename> --decrypt <filename_gpg>
# make a signature
gpg --output <filename_sig> --sign <filename>
# verify signature
gpg --output <filename> <filename> --decrypt <filename_sig>
# clearsign documents
gpg --clearsign <filename>
# detach signature
gpg --output <filename_sig> --detach-sig <filename>

View file

@ -1,28 +0,0 @@
% httpie, http
# send a get http request
http <url>
# send a http request
http <method> <url>
# send an authenticated http request
http -a <username>:<password> <method> <url>
# send a http request with a json body
http <method> <url> <bodykey>=<bodyvalue>
# send a http request with a form body
http -f POST <url> <bodykey>=<bodyvalue>
# send a http request and see the request as well as the response
http -v <url>
# send a post http request wih a body from a file
http <method> <url> < <file>
# send a http request wih a custom header
http <method> <url> <headername>:<headervalue>
$ file: ls
$ method: echo -e 'GET\nPOST\nPUT\nDELETE\nPATCH'

View file

@ -1,70 +0,0 @@
% npm, node, js
# initial new package
npm init
# initial immediately a new package
npm init -y
# install all dependencies packages
npm install
# install all dev dependencies packages
npm install --save-dev
# install a specified package
npm install <package_name>
# install a specified dev package
npm install <package_name> --save-dev
# install globally a specified package
npm install <package_name> -g
# run a script
npm run <script>
$ script: node -p "Object.keys(require('./package.json').scripts).join('\n')"
% yarn, node, js
# initial new package
yarn init
# install all dependencies packages
yarn install
# install all dev dependencies packages
yarn install --save-dev
# install a specified package
yarn add <package_name>
# install a specified dev package
yarn add <package_name> --dev
# install globally a specified package
yarn global add <package_name>
# run a script
yarn run <script>
$ script: node -p "Object.keys(require('./package.json').scripts).join('\n')"
% nvm, node, js
# install a specified version of node
nvm install <version>
# list available versions
nvm ls-remote
# use installed node's version
nvm use <version>
# set a node's version as default
nvm alias default <version>

View file

@ -1,36 +0,0 @@
% k3d
# Check if docker is running
k3d check-tools
# Start a subshell for a cluster
k3d shell
# Create a single k3s cluster in docker containers
k3d create --name <cluster_name>
# Create a multi-node k3s cluster in docker containers
k3d create --name <name> --workers <worker_count>
# Delete cluster
k3d delete --name <cluster_name>
# Stop cluster
k3d stop --name <cluster_name>
# Start a stopped cluster
k3d start --name <cluster_name>
# List all clusters
k3d list
# Get kubeconfig location for cluster
k3d get-kubeconfig --name <cluster_name>
# Import a comma- or space-separated list of container images from your local docker daemon into the cluster
k3d import-images
# Show a list of commands or help for one command
k3d help
$ cluster_name: k3d list |awk '{print $2}' | awk 'NF {print $0}' | tail -n +2

View file

@ -1,58 +0,0 @@
% java keytool, certificate, encryption
## Creating
# Generate a Java keystore and key pair
keytool -genkey -alias <ALIAS> -keyalg RSA -keystore <OUTPUT_JKS> -keysize <RSA_LENGTH>
# Generate a certificate signing request (CSR) for an existing Java keystore
keytool -certreq -alias <ALIAS> -keystore <INPUT_JKS> -file <OUTPUT_CSR>
# Import a root or intermediate CA certificate to an existing Java keystore
keytool -import -trustcacerts -alias root -file <INPUT_CRT> -keystore <INPUT_JKS>
# Import a signed primary certificate to an existing Java keystore
keytool -import -trustcacerts -alias <ALIAS> -file <INPUT_CRT> -keystore <INPUT_JKS>
# Generate a keystore and self-signed certificate
keytool -genkey -keyalg RSA -alias <ALIAS> -keystore <OUTPUT_JKS> -storepass <PASSWORD> -validity <VALIDITY> -keysize <RSA_LENGTH>
## Verifying
# Check a stand-alone certificate
keytool -printcert -v -file <INPUT_CRT>
# Check which certificates are in a Java keystore
keytool -list -v -keystore <INPUT_JKS>
# Check a particular keystore entry using an alias
keytool -list -v -keystore <INPUT_JKS> -alias <ALIAS>
## Other
# Remove a certificate from a keystore
keytool -delete -alias <ALIAS> -keystore <INPUT_JKS>
# Change the password of a keystore
keytool -storepasswd -keystore <INPUT_JKS> -new <NEW_PASSWORD>
# Export a certificate from a keystore
keytool -export -alias <ALIAS> -file <OUTPUT_CRT> -keystore <INPUT_JKS>
# List the trusted CA Certs from the default Java Trusted Certs Keystore
keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts
# Import New Certificate Authority into the default Java Trusted Certs Keystore
keytool -import -trustcacerts -file <INPUT_PEM> -alias <ALIAS> -keystore $JAVA_HOME/jre/lib/security/cacerts
# Sensible/common default alternatives
$ VALIDITY: printf "DAYS\tCOMMENT\n1\ta day\n30\ta month\n365\ta year\n730\ttwo years" --- --column 1 --headers 1
$ RSA_LENGTH: printf "KEY LENGTH\tCOMMENT\n2048\t\tDefault\n4096\t\tBetter\n8192\t\tSlow?" --- --column 1 --headers 1
# Attempt to find files with the appropriate endings, default to everything.
$ INPUT_CRT: ls -a | grep -e "\(.crt\|.cer\|.der\)" || ls -a
$ INPUT_PEM: ls -a | grep -e "\(.pem\)" || ls -a
$ INPUT_JKS: ls -a | grep -e "\(.jks\)" || ls -a

View file

@ -1,52 +0,0 @@
% kubernetes, k8s
# Print all contexts
kubectl config get-contexts
# Print current context of kubeconfig
kubectl config current-context
# Set context of kubeconfig
kubectl config use-context <context>
# Print resource documentation
kubectl explain <resource>
# Get nodes (add option '-o wide' for details)
kubectl get nodes
# Get namespaces
kubectl get namespaces
# Get pods from namespace (add option '-o wide' for details)
kubectl get pods -n <namespace>
# Get pods from all namespace (add option '-o wide' for details)
kubectl get pods --all-namespaces
# Get services from namespace
kubectl get services -n <namespace>
# Get details from resource on namespace
kubectl describe <resource>/<name> -n <namespace>
# Print logs from namespace
kubectl logs -f pods/<name> -n <namespace>
# Get deployments
kubectl get deployments -n <namespace>
# Edit deployments
kubectl edit deployment/<name> -n <namespace>
# Drain node in preparation for maintenance
kubectl drain <name>
# Mark node as schedulable
kubectl uncordon <name>
# Mark node as unschedulable
kubectl cordon <name>
# Display resource (cpu/memory/storage) usage
kubectl top <type>

View file

@ -1,27 +0,0 @@
% weather
# Show weather info for current location
curl -s "wttr.in" \
| grep -v "New feature" \
| grep -v Follow
# Show weather info for a specific location
curl -s "wttr.in/<location>" \
| grep -v "New feature" \
| grep -v Follow
% qr code
# Create a QR code with some content
echo <content> | curl -F-=\<- qrenco.de
% json
# convert JSON to YAML
cat <json_file> | ruby -ryaml -rjson -e 'puts YAML.dump(JSON.load(ARGF))'
$ json_file: find . -name '*.json'

View file

@ -1,10 +0,0 @@
% mysql, database, db
# Create database
mysql -u <user> -p -e "create database <database> character set UTF8mb4 collate utf8mb4_bin"
# Export databse
mysqldump -u <user> -p <database> > <path>
# Import database
mysql -u <user> -p <database> <path>

View file

@ -1,27 +0,0 @@
% network
# Kill a process running on a given port
lsof -i :<port> \
| awk '{l=$2} END {print l}' \
| xargs kill
# List IP addresses connected on a given port
netstat -tn 2>/dev/null \
| grep :<port> \
| awk '{print $5}' \
| cut -d: -f1 \
| sort \
| uniq -c \
| sort -nr \
| head
# 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' \
| tail -n1
# Find external, public IP address
dig +short myip.opendns.com @resolver1.opendns.com

View file

@ -1,81 +0,0 @@
% openssl, certificate, encryption
## General OpenSSL Commands
# Create a new signing request and key
openssl req -new -newkey rsa:<RSA_LENGTH> -nodes -out <OUTPUT_CSR> -keyout <OUTPUT_KEY>
# Create a new self-signed certificate
openssl req -x509 -sha256 -nodes -days <VALIDITY> -newkey rsa:<RSA_LENGTH> -out <OUTPUT_CRT> -keyout <OUTPUT_KEY>
# Create a signing request from existing key
openssl req -out <OUTPUT_CSR> -key <INPUT_KEY> -new
# Create a signing request from existing certificate and key
openssl x509 -x509toreq -out <OUTPUT_CSR> -in <INPUT_CRT> -signkey <INPUT_KEY>
# Remove a passphrase from a private key
openssl rsa -in <INPUT_KEY> -out <OUTPUT_PLAINTEXT_KEY>
## Converting between the different encoding
# Convert a DER encoded file to a PEM encoded file
openssl x509 -inform der -in <INPUT_CRT> -out <OUTPUT_PEM>
# Convert a PEM encoded file to a DER encoded file
openssl x509 -outform der -in <INPUT_PEM> -out <OUTPUT_CRT>
# Convert a PKCS12 encoded file containing a private key and certificates to PEM
openssl pkcs12 -in <INPUT_PKCS12> -out <OUTPUT_PEM> -nodes
# Extract the private key from a PKCS12 encoded file
openssl pkcs12 -in <INPUT_PKCS12> -out <OUTPUT_PEM> -nodes -nocerts
# Extract the certificate from a PKCS12 encoded file
openssl pkcs12 -in <INPUT_PKCS12> -out <OUTPUT_PEM> -nodes -nokeys
# Convert a PEM certificate file and a private key to PKCS12 encoded file
openssl pkcs12 -export -out <OUTPUT_PKCS12> -inkey <INPUT_KEY> -in <INPUT_CRT> -certfile <INPUT_CRT>
## Validating certificates and keys using OpenSSL
# Validate a certificate signing request
openssl req -text -noout -verify -in <OUTPUT_CSR>
# Validate a private key
openssl rsa -in <INPUT_KEY> -check
# Validate a certificate
openssl x509 -in <INPUT_CRT> -text -noout
# Validate a PKCS12 file (.pfx or .p12)
openssl pkcs12 -info -in <INPUT_PKCS12>
## Debugging using OpenSSL
# Compare the MD5 hash of a certificate
openssl x509 -noout -modulus -in <INPUT_CRT> | openssl md5
# Compare the MD5 hash of a private key
openssl rsa -noout -modulus -in <INPUT_KEY> | openssl md5
# Compare the MD5 hash of a certificate signing request
openssl req -noout -modulus -in <INPUT_CSR> | openssl md5
# Display the server certificate chain
openssl s_client -connect <URL>:<PORT>
# Sensible/common default alternatives
$ VALIDITY: printf "DAYS\tCOMMENT\n1\ta day\n30\ta month\n365\ta year\n730\ttwo years" --- --column 1 --headers 1
$ RSA_LENGTH: printf "KEY LENGTH\tCOMMENT\n2048\t\tDefault\n4096\t\tBetter\n8192\t\tSlow?" --- --column 1 --headers 1
# Attempt to find files with the appropriate endings, default to everything.
$ INPUT_PKCS12: ls -a | grep -e "\(.pfx\|.p12\)" || ls -a
$ INPUT_CSR: ls -a | grep -e "\(.csr\)" || ls -a
$ INPUT_KEY: ls -a | grep -e "\(.key\|.pem\)" || ls -a
$ INPUT_CRT: ls -a | grep -e "\(.crt\|.cer\|.der\)" || ls -a
$ INPUT_PEM: ls -a | grep -e "\(.pem\)" || ls -a

View file

@ -1,25 +0,0 @@
% osx, mac os
# Lock system
pmset displaysleepnow
# Show hidden files in Finder
defaults write com.apple.finder AppleShowAllFiles -bool true; \
killall Finder
# Hide hidden files in Finder
defaults write com.apple.finder AppleShowAllFiles -bool false; \
killall Finder
# Show items in desktop
defaults write com.apple.finder CreateDesktop -bool true; \
killall Finder
# Hide items in desktop
defaults write com.apple.finder CreateDesktop -bool false; \
killall Finder
# Set wallpaper
osascript -e 'tell application "Finder" to set desktop picture to POSIX file "<image_path>"'
$ image_path: find $HOME -maxdepth 3 -name "*.jpg" -o -name "*.jpeg" -o -name "*.png"

View file

@ -1,79 +0,0 @@
% rsfetch, information, unixporn
# Disable text bolding
rsfetch -b
# Disable borders
rsfetch -B
# Disable caps (TEXT -> text)
rsfetch -c
# Specify the character for the corners of the borders
rsfetch -C <CHARACTER>
# Display name of distro
rsfetch -d
# Display your $EDITOR
rsfetch -e
# Display help message
rsfetch --help
# Display name of host (the actual device's name, not to be confused with hostname)
rsfetch -h
# Display hostname
rsfetch -H
# Display IP Address
rsfetch -i
# Display kernel version
rsfetch -k
# Enable ascii art (defaults to rsfetch logo, or a penguin with neofetch-style output)
rsfetch -l
# Specify the ascii art to use
rsfetch -L <FILE>
# Display memory info
rsfetch -r
# Display music info (currently only support mpd)
rsfetch -m mpd
# Enable minimal-style output (no borders, no logo, no text effects, no category names)
rsfetch -M
# Enable neofetch-style output
rsfetch -N
# Display package count
rsfetch -p <PKG MNGR>
# Display CPU info
rsfetch -P
# Display the current shell
rsfetch -s
# Display the current terminal
rsfetch -t
# Display the current uptime
rsfetch -u
# Display the username for the current account
rsfetch -U
# Display rsfetch version
rsfetch -V
# Display current WM or DE
rsfetch -w
# Enable user@host output-style (requires -H and -U to be enabled)
rsfetch -@

View file

@ -1,214 +0,0 @@
% Shell Usage
# Re-call last input with sudo
sudo !!
# Help
help cd / help dir (...)
# Finding Help
apropos directory / apropos search (...)
# Define custom startup screen
sudo nano /etc/motd
# Run a script as background process
<process> &
#List all running processes
ps -A
# Kill a running process
killall <Process-name>
% Shell System
# Get the current path
pwd
# Get the current hostname
hostname
# Get the current users
users
# Show calendar
cal
# Show today's date
date
# Exit terminal
exit
% Shell Permissions
# Use -R option to change permissions recursively.
ps -ef | grep apache | grep -v grep
# Change group
chgrp <group-name-from> <group-name-to>
% Shell Directories
# List directory contents
ls
# List all directory contents
ll
# List all directory contents sorted by time edited
ls -alt
# List directory (wildcard matching)
ls *.<txt>
# List all files of type
find . -name *.<txt> -print
# Go back to previous directory
cd -
# Make (empty) directory
mkdir <dirname>
# Remove (empty) directory
rmdir <dirname>
# Remove directory with all contents without prompt
rm -rf <dirname>
# Remove directory contents and keep directory
rm -rf *
# Change directory
cd <dirname>
% shell Symlinks
# Create symlink
ln -s <source-dirname> <destination-dirname>
# Update symlink
ln -sfn <source-dirname> <destination-dirname>
# Remove symlink
unlink <sample-dirname>
% Shell Files
# Make (empty) file
touch <filename-txt>
# Duplicate file
cp <filename> <file-copyname>
# Copy/Page folder with content
cp -a <old-folder>/ <new-folder>
# Move/Rename file
mv <current-filename-path> <new-filename-path>
# Move/Rename file and prompt before overwriting an existing file
mv -i <current-filename> <new-filename>
# Remove file
rm <filename-txt>
# Write to file (will overwrite existing content)
cat > <filename-txt>
# Search for a filename-(not content!) in the current directory
find <filename-txt>
# Search for a string inside all files in the current directory and subdrectories
grep -r <string> *
# Search and replace within file
sed -i s/<original-text>/<new-text>/g <filename-txt>
# MD5 hash for files
md5 <filename-txt>
# MD5 hash for folders
tar c <folder> | md5sum
# Encrypt file
openssl enc -aes-256-cbc -e -in <sample-filename-txt> -out <sample-encrypted-txt>
# Decrypt file
openssl enc -aes-256-cbc -d -in <sample-encrypted> -out <sample-filename>
% Shell Server
# Access via ssh
ssh <username-remote>
# Copy file from server to local
scp <username-remote>:<file-to-send-path> <path-to-recieve>
# Copy file from local to server
scp <file-to-send> <username-remote>:<where-to-put>
# Escape files with spaces in name like this
<path-to-file>\\\ <name-png>
% Shell System
# Show disc space
df -h
# Show disc space (inodes)
df -i
# Show disc space for current directory
du -hs
# Current processes (also CPS usage)
top or htop
# Show running php processes
ps aux | grep php
# Monitor error log (stream as file grows)
tail error.log -f -n 0
% Shell Apps
# Start appliction
xdg-open <programme>
# Open finder with current folder
open .
% Shell Variables
# Register variable
export <TESTING>=<Variable-text>
# Echo variable
echo $<Variable>
# Unset variable
unset <Variable>
% Shell Output & Redirects
# Write to file
echo <Hello> > <hello-txt>
# Append content from a file to another file
cat <file1-txt> >> <file2-txt>
# Add the amount of lines, words, and characters to <file2-txt>
cat <file1-txt> | <word-count> | cat > <file2-txt>
# Sort the content of a file (like cat)
sort <hello-txt>
# Save to sorted content to a new file
cat <file1-txt> | sort > <sorted-file1-txt>
# Sort and remove duplicates and save to a new file
sort <file1-txt> | uniq > <uniq-file1-txt>

View file

@ -1,4 +0,0 @@
% ssh
# Start ssh agent
eval "$(ssh-agent -s)"; ssh-add

View file

@ -1,37 +0,0 @@
% systemctl, service
# Start service
systemctl start <service_inactive>
# Stop service
systemctl stop <service_active>
# Enable service
systemctl enable <service_disabled>
# Disable service
systemctl disable <service_enabled>
# Restart service
systemctl restart <service>
# Reload service
systemctl reload <service_active>
# Service status
systemctl status <service>
# List running services
systemctl list-units --type=service --state=running
# List enabled services
systemctl list-unit-files --type=service --state=enabled
# List disabled services
systemctl list-unit-files --type=service --state=disabled
$ service_inactive: systemctl list-units --type=service --state=inactive | awk '{print $1}' | grep .service | sed 's/.service$//'
$ service_active: systemctl list-units --type=service --state=active | awk '{print $1}' | grep .service | sed 's/.service$//'
$ service_enabled: systemctl list-unit-files --type=service --state=enabled | awk '{print $1}' | grep .service | sed 's/.service$//'
$ service_disabled: systemctl list-unit-files --type=service --state=disabled | awk '{print $1}' | grep .service | sed 's/.service$//'
$ service: systemctl list-units --type=service --all | awk '{print $1}' | grep .service | sed 's/.service$//'

View file

@ -1,52 +0,0 @@
% yum
# List all available packages
yum list available
# List all installed packages
yum list installed
# Info about package
yum info <package-name>
# Search in repository (packages and descriptions)
yum search <query>
# List all history actions (install, update and erase)
yum history list
# Check updates for installed packages
yum check-update
# Update all packages
yum update
# Update spesific/individual package
yum update <package-name>
# Downgrade package
yum downgrade <package-name>
# Install a package from repository
yum install <package-name>
# Remove/delete package
yum remove <package-name>
# Install local rpm package
yum localinstall <filepath-rpm>
# Install security updates
yum update --security
# List dependencies of package
yum deplist <package-name>
# Remove un-needed packages and dependencies
yum autoremove
# Whatprovides package/file/binary
yum whatprovides <query>
# List currently enabled repositories
yum repolist

View file

@ -33,8 +33,6 @@ release() {
chmod +x "$bin_path"
mkdir -p "$TAR_DIR" 2> /dev/null || true
cp -r "${NAVI_HOME}/cheats" "$TAR_DIR"
cp -r "${NAVI_HOME}/shell" "$TAR_DIR"
cp "$bin_path" "$TAR_DIR"
cd "${NAVI_HOME}/target/tar"

View file

@ -1,7 +1,7 @@
use crate::display;
use crate::filesystem;
use crate::option::Config;
use crate::welcome;
use regex::Regex;
use std::collections::HashMap;
use std::fs;
@ -31,7 +31,7 @@ pub enum SuggestionType {
pub type Suggestion = (String, Option<SuggestionOpts>);
fn remove_quote(txt: &str) -> String {
fn remove_quotes(txt: &str) -> String {
txt.replace('"', "").replace('\'', "")
}
@ -49,10 +49,12 @@ fn parse_opts(text: &str) -> SuggestionOpts {
"--multi" => multi = true,
"--allow-extra" => allow_extra = true,
"--header" | "--headers" | "--header-lines" => {
header_lines = remove_quote(parts.next().unwrap()).parse::<u8>().unwrap()
header_lines = remove_quotes(parts.next().unwrap()).parse::<u8>().unwrap()
}
"--column" => column = Some(remove_quote(parts.next().unwrap()).parse::<u8>().unwrap()),
"--delimiter" => delimiter = Some(remove_quote(parts.next().unwrap()).to_string()),
"--column" => {
column = Some(remove_quotes(parts.next().unwrap()).parse::<u8>().unwrap())
}
"--delimiter" => delimiter = Some(remove_quotes(parts.next().unwrap()).to_string()),
_ => (),
}
}
@ -109,7 +111,7 @@ fn read_file(
path: &str,
variables: &mut HashMap<String, Suggestion>,
stdin: &mut std::process::ChildStdin,
) {
) -> bool {
let mut tags = String::from("");
let mut comment = String::from("");
let mut snippet = String::from("");
@ -160,9 +162,11 @@ fn read_file(
snippet.push_str(&line);
}
}
return true;
}
write_cmd(&tags, &comment, &snippet, tag_width, comment_width, stdin);
false
}
pub fn read_all(
@ -170,28 +174,29 @@ pub fn read_all(
stdin: &mut std::process::ChildStdin,
) -> HashMap<String, Suggestion> {
let mut variables: HashMap<String, Suggestion> = HashMap::new();
let mut fallback: String = String::from("");
let folders_str = config.path.as_ref().unwrap_or_else(|| {
if let Some(f) = filesystem::cheat_pathbuf() {
fallback = filesystem::pathbuf_to_string(f);
}
&fallback
});
let folders = folders_str.split(':');
let mut found_something = false;
let paths = filesystem::cheat_paths(config);
let folders = paths.split(':');
for folder in folders {
if let Ok(paths) = fs::read_dir(folder) {
for path in paths {
let path_os_str = path.unwrap().path().into_os_string();
let path_str = path_os_str.to_str().unwrap();
if path_str.ends_with(".cheat") {
read_file(path_str, &mut variables, stdin);
if path_str.ends_with(".cheat")
&& read_file(path_str, &mut variables, stdin)
&& !found_something
{
found_something = true;
}
}
}
}
if !found_something {
welcome::cheatsheet(stdin);
}
variables
}

View file

@ -1,8 +1,7 @@
use std::error::Error;
use crate::cmds;
use crate::cmds::core::Variant;
use crate::option::Config;
use std::error::Error;
pub fn main(query: String, args: Vec<String>, config: Config) -> Result<(), Box<dyn Error>> {
if !args.is_empty() {

View file

@ -1,10 +1,12 @@
use crate::cheat;
use crate::cheat::SuggestionType;
use crate::cmds;
use crate::display;
use crate::filesystem;
use crate::fzf;
use crate::handler;
use crate::option;
use crate::option::Config;
use crate::cheat::SuggestionType;
use regex::Regex;
use std::collections::HashMap;
use std::error::Error;
@ -20,7 +22,11 @@ pub enum Variant {
fn gen_core_fzf_opts(variant: Variant, config: &Config) -> fzf::Opts {
let mut opts = fzf::Opts {
preview: !config.no_preview,
preview: if config.no_preview {
None
} else {
Some(format!("{} preview {{}}", filesystem::exe_string()))
},
autoselect: !config.no_autoselect,
overrides: config.fzf_overrides.as_ref(),
suggestion_type: SuggestionType::SnippetSelection,
@ -79,7 +85,6 @@ fn prompt_with_suggestions(
let suggestions = String::from_utf8(child.wait_with_output().unwrap().stdout).unwrap();
let mut opts = fzf::Opts {
preview: false,
autoselect: !config.no_autoselect,
overrides: config.fzf_overrides_var.as_ref(),
prompt: Some(display::variable_prompt(varname)),
@ -117,7 +122,6 @@ fn prompt_with_suggestions(
fn prompt_without_suggestions(variable_name: &str) -> String {
let opts = fzf::Opts {
preview: false,
autoselect: false,
prompt: Some(display::variable_prompt(variable_name)),
suggestion_type: SuggestionType::Disabled,
@ -185,6 +189,7 @@ pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(),
});
let (key, tags, snippet) = extract_from_selections(&raw_selection[..], contains_key);
let interpolated_snippet = with_new_lines(replace_variables_from_snippet(
snippet,
tags,
@ -192,12 +197,20 @@ pub fn main(variant: Variant, config: Config, contains_key: bool) -> Result<(),
&config,
));
// copy to clipboard
if key == "ctrl-y" {
cmds::aux::abort("copying snippets to the clipboard", 201)?
// print to stdout
} else if config.print {
println!("{}", interpolated_snippet);
// save to file
} else if let Some(s) = config.save {
fs::write(s, interpolated_snippet)?;
// call navi (this prevents "failed to read /dev/tty" from fzf)
} else if interpolated_snippet.starts_with("navi") {
let new_config = option::config_from_iter(interpolated_snippet.split(' ').collect());
handler::handle_config(new_config)?;
// shell out and execute snippet
} else {
Command::new("bash")
.arg("-c")

View file

@ -1,8 +0,0 @@
use std::error::Error;
use crate::filesystem;
pub fn main() -> Result<(), Box<dyn Error>> {
println!("{}", filesystem::exe_parent_string());
Ok(())
}

View file

@ -2,8 +2,8 @@ pub mod aux;
pub mod best;
pub mod core;
pub mod func;
pub mod home;
pub mod preview;
pub mod query;
pub mod repo;
pub mod search;
pub mod shell;

View file

@ -1,8 +1,7 @@
use crate::display;
use std::error::Error;
use std::process;
use crate::display;
fn extract_elements(argstr: &str) -> (&str, &str, &str) {
let mut parts = argstr.split(display::DELIMITER).skip(3);
let tags = parts.next().unwrap();

View file

@ -1,8 +1,7 @@
use std::error::Error;
use crate::cmds;
use crate::cmds::core::Variant;
use crate::option::Config;
use std::error::Error;
pub fn main(query: String, config: Config) -> Result<(), Box<dyn Error>> {
cmds::core::main(Variant::Query(query), config, true)

84
src/cmds/repo.rs Normal file
View file

@ -0,0 +1,84 @@
use crate::cheat::SuggestionType;
use crate::filesystem;
use crate::fzf;
use git2::Repository;
use std::error::Error;
use std::fs;
use std::io::Write;
use walkdir::WalkDir;
fn create_dir(path: &str) {
fs::create_dir_all(path).unwrap_or(());
}
fn remove_dir(path: &str) {
fs::remove_dir_all(path).unwrap_or(());
}
pub fn add(uri: String) -> Result<(), Box<dyn Error>> {
let actual_uri = if uri.contains("://") {
uri
} else {
format!("https://github.com/{}", uri)
};
let parts: Vec<&str> = actual_uri.split('/').collect();
let user = parts[parts.len() - 2];
let repo = parts[parts.len() - 1].replace(".git", "");
let cheat_path_str = filesystem::pathbuf_to_string(filesystem::cheat_pathbuf().unwrap());
let tmp_path_str = format!("{}/tmp", cheat_path_str);
let tmp_path_str_with_trailing_slash = format!("{}/", &tmp_path_str);
remove_dir(&tmp_path_str);
create_dir(&tmp_path_str);
eprintln!("Cloning {} into {}...\n", &actual_uri, &tmp_path_str);
match Repository::clone(actual_uri.as_str(), &tmp_path_str) {
Ok(r) => r,
Err(e) => panic!("failed to clone: {}", e),
};
let all_files = WalkDir::new(&tmp_path_str)
.into_iter()
.filter_map(|e| e.ok())
.map(|e| e.path().to_str().unwrap_or("").to_string())
.filter(|e| e.ends_with(".cheat"))
.map(|e| e.replace(&tmp_path_str_with_trailing_slash, ""))
.collect::<Vec<String>>()
.join("\n");
let overrides = "--preview-window right:30%".to_string();
let opts = fzf::Opts {
suggestion_type: SuggestionType::MultipleSelections,
preview: Some(format!("cat {}/{{}}", tmp_path_str_with_trailing_slash)),
header: Some(
"Select the cheatsheets you want to import with <TAB> then hit <Enter>".to_string(),
),
overrides: Some(&overrides),
..Default::default()
};
let (files, _) = fzf::call(opts, |stdin| {
stdin
.write_all(all_files.as_bytes())
.expect("Unable to prompt cheats to import");
None
});
for f in files.split('\n') {
let from = format!("{}/{}", tmp_path_str, f).replace("./", "");
let to_folder = format!("{}/{}__{}", cheat_path_str, user, repo).replace("./", "");
let filename = f.replace("./", "").replace("/", "__");
let to = format!("{}/{}", to_folder, filename);
fs::create_dir_all(to_folder).unwrap_or(());
fs::copy(from, to)?;
}
remove_dir(&tmp_path_str);
eprintln!("The following .cheat files were imported successfully:\n{}\n\nThey are now located at {}\n\nPlease run navi again to check the results.", files, cheat_path_str);
Ok(())
}

View file

@ -1,7 +1,6 @@
use std::error::Error;
use super::aux;
use crate::option::Config;
use std::error::Error;
pub fn main(_query: String, _config: Config) -> Result<(), Box<dyn Error>> {
aux::abort("searching for cheats online", 201)

View file

@ -1,19 +1,13 @@
use std::error::Error;
use crate::filesystem;
pub fn main(shell: &str) -> Result<(), Box<dyn Error>> {
let file = match shell {
"zsh" => "navi.plugin.zsh",
"fish" => "navi.plugin.fish",
_ => "navi.plugin.bash",
let content = match shell {
"zsh" => include_str!("../../shell/navi.plugin.zsh"),
"fish" => include_str!("../../shell/navi.plugin.fish"),
_ => include_str!("../../shell/navi.plugin.bash"),
};
println!(
"{}/{}",
filesystem::pathbuf_to_string(filesystem::shell_pathbuf()),
file
);
println!("{}", content);
Ok(())
}

View file

@ -1,5 +1,4 @@
use crate::terminal;
use regex::Regex;
use std::cmp::max;
use termion::color;

View file

@ -1,5 +1,5 @@
use crate::option::Config;
use std::fs;
use std::fs::metadata;
use std::fs::File;
use std::io::{self, BufRead, BufReader, Lines};
use std::path::{Path, PathBuf};
@ -16,6 +16,17 @@ pub fn pathbuf_to_string(pathbuf: PathBuf) -> String {
pathbuf.as_os_str().to_str().unwrap().to_string()
}
pub fn cheat_pathbuf() -> Option<PathBuf> {
match dirs::config_dir() {
Some(mut d) => {
d.push("navi");
d.push("cheats");
Some(d)
}
None => None,
}
}
fn follow_symlink(pathbuf: PathBuf) -> PathBuf {
let other = fs::read_link(pathbuf.clone());
match other {
@ -39,38 +50,28 @@ fn exe_pathbuf() -> PathBuf {
follow_symlink(pathbuf)
}
pub fn cheat_pathbuf() -> Option<PathBuf> {
let exe_parent_str = exe_parent_string();
let array = ["cheats", "../libexec/cheats", "../cheats", "../../cheats"];
for elem in &array {
let p = format!("{}/{}", exe_parent_str, elem);
let meta = metadata(&p);
if let Ok(m) = meta {
if m.is_dir() {
return Some(PathBuf::from(p));
}
}
}
None
}
pub fn shell_pathbuf() -> PathBuf {
let cheat_path_str = pathbuf_to_string(cheat_pathbuf().unwrap());
PathBuf::from(format!("{}/../shell", cheat_path_str))
}
pub fn exe_string() -> String {
pathbuf_to_string(exe_pathbuf())
}
pub fn exe_parent_string() -> String {
exe_pathbuf()
.parent()
.unwrap()
.as_os_str()
.to_str()
.unwrap()
.to_string()
fn cheat_paths_from_config_dir() -> String {
let mut paths_str = String::from("");
if let Some(f) = cheat_pathbuf() {
if let Ok(paths) = fs::read_dir(pathbuf_to_string(f)) {
for path in paths {
paths_str.push_str(path.unwrap().path().into_os_string().to_str().unwrap());
paths_str.push_str(":");
}
}
}
paths_str
}
pub fn cheat_paths(config: &Config) -> String {
config
.path
.clone()
.unwrap_or_else(cheat_paths_from_config_dir)
}

View file

@ -1,9 +1,7 @@
use crate::cheat;
use crate::display;
use crate::filesystem;
use crate::cheat::SuggestionType;
use crate::cheat::SuggestionType::SingleSelection;
use crate::display;
use std::collections::HashMap;
use std::process;
use std::process::{Command, Stdio};
@ -12,10 +10,11 @@ pub struct Opts<'a> {
pub query: Option<String>,
pub filter: Option<String>,
pub prompt: Option<String>,
pub preview: bool,
pub preview: Option<String>,
pub autoselect: bool,
pub overrides: Option<&'a String>, // TODO: remove &'a
pub header_lines: u8,
pub header: Option<String>,
pub suggestion_type: SuggestionType,
}
@ -24,10 +23,11 @@ impl Default for Opts<'_> {
Self {
query: None,
filter: None,
preview: true,
autoselect: true,
preview: None,
overrides: None,
header_lines: 0,
header: None,
prompt: None,
suggestion_type: SingleSelection,
}
@ -73,11 +73,8 @@ where
_ => {}
}
if opts.preview {
fzf_command.args(&[
"--preview",
format!("{} preview {{}}", filesystem::exe_string()).as_str(),
]);
if let Some(p) = opts.preview {
fzf_command.args(&["--preview", &p]);
}
if let Some(q) = opts.query {
@ -88,6 +85,10 @@ where
fzf_command.args(&["--filter", &f]);
}
if let Some(h) = opts.header {
fzf_command.args(&["--header", &h]);
}
if let Some(p) = opts.prompt {
fzf_command.args(&["--prompt", &p]);
}
@ -109,7 +110,6 @@ where
let child = fzf_command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.spawn();
let mut child = match child {

27
src/handler.rs Normal file
View file

@ -0,0 +1,27 @@
use crate::cmds;
use crate::cmds::core::Variant;
use crate::option::Command::{Best, Fn, Query, Repo, Search, Widget};
use crate::option::{Config, InternalCommand, RepoCommand};
use std::error::Error;
pub fn handle_config(mut config: Config) -> Result<(), Box<dyn Error>> {
match config.cmd.as_mut() {
None => cmds::core::main(Variant::Core, config, true),
Some(c) => match c {
Query { query } => cmds::query::main(query.clone(), config),
Best { query, args } => cmds::best::main(query.clone(), args.to_vec(), config),
Search { query } => cmds::search::main(query.clone(), config),
Widget { shell } => cmds::shell::main(&shell[..]),
Fn { func, args } => cmds::func::main(func.clone(), args.to_vec()),
Repo { cmd } => match cmd {
RepoCommand::Add { uri } => cmds::repo::add(uri.clone()),
},
},
}
}
pub fn handle_internal_command(cmd: InternalCommand) -> Result<(), Box<dyn Error>> {
match cmd {
InternalCommand::Preview { line } => cmds::preview::main(line),
}
}

View file

@ -1,37 +1,23 @@
#[macro_use]
extern crate lazy_static;
use std::error::Error;
mod cheat;
mod cmds;
mod display;
mod filesystem;
mod fzf;
mod handler;
mod option;
mod terminal;
mod welcome;
use crate::cmds::core::Variant;
use option::{Command, InternalCommand};
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
match option::internal_command() {
Some(InternalCommand::Preview { line }) => cmds::preview::main(line),
_ => {
let mut config = option::parse();
match config.cmd.as_mut() {
None => cmds::core::main(Variant::Core, config, true),
Some(c) => match c {
Command::Query { query } => cmds::query::main(query.clone(), config),
Command::Best { query, args } => {
cmds::best::main(query.clone(), args.to_vec(), config)
}
Command::Search { query } => cmds::search::main(query.clone(), config),
Command::Widget { shell } => cmds::shell::main(&shell[..]),
Command::Fn { func, args } => cmds::func::main(func.clone(), args.to_vec()),
Command::Home => cmds::home::main(),
},
}
}
let internal_cmd = option::internal_command_from_env();
if let Some(cmd) = internal_cmd {
handler::handle_internal_command(cmd)
} else {
handler::handle_config(option::config_from_env())
}
}

View file

@ -2,23 +2,24 @@ use std::env;
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
#[structopt(after_help = "EXAMPLES:
#[structopt(after_help = r#"EXAMPLES:
navi # default behavior
navi --print # doesn't execute the snippet
navi --path '/some/dir:/other/dir' # uses custom cheats
navi search docker # uses online data
navi query git # filters results by \"git\"
navi query git # filters results by "git"
navi best 'sql create db' root mydb # uses a snippet as a CLI
source \"$(navi widget zsh)\" # loads the zsh widget
navi repo add denisidoro/cheats # imports cheats from github.com/denisidoro/cheats
source <(navi widget zsh) # loads the zsh widget
navi --fzf-overrides ' --with-nth 1,2' # shows only the comment and tag columns
navi --fzf-overrides ' --nth 1,2' # search will consider only the first two columns
navi --fzf-overrides ' --no-exact' # looser search algorithm")]
navi --fzf-overrides ' --no-exact' # looser search algorithm"#)]
pub struct Config {
/// List of :-separated paths containing .cheat files
#[structopt(short, long, env = "NAVI_PATH")]
pub path: Option<String>,
/// [alpha] Instead of executing a snippet, saves it to a file
/// [Experimental] Instead of executing a snippet, saves it to a file
#[structopt(short, long)]
pub save: Option<String>,
@ -49,28 +50,63 @@ pub struct Config {
#[derive(Debug, StructOpt)]
pub enum Command {
/// Filters results
Query { query: String },
/// Shows navi's home directory
Home,
Query {
/// String used as filter (example: "git")
query: String,
},
/// Uses online repositories for cheatsheets
Search { query: String },
Search {
/// String used as filter (example: "git")
query: String,
},
/// Autoselects the snippet that best matches the query
Best { query: String, args: Vec<String> },
Best {
/// String used as filter (example: "git remove branch")
query: String,
/// List of arguments (example: "mybranch" "remote")
args: Vec<String>,
},
/// Performs ad-hoc functions provided by navi
Fn { func: String, args: Vec<String> },
Fn {
/// Function name (example: "url::open")
func: String,
/// List of arguments (example: "https://google.com")
args: Vec<String>,
},
/// Manages cheatsheet repositories
Repo {
#[structopt(subcommand)]
cmd: RepoCommand,
},
/// Shows the path for shell widget files
Widget { shell: String },
Widget {
/// bash, zsh or fish
shell: String,
},
}
#[derive(Debug, StructOpt)]
pub enum RepoCommand {
/// Imports cheatsheets from a repo
Add {
/// A URI to a git repository containing .cheat files ("user/repo" will download cheats from github.com/user/repo)
uri: String,
},
}
pub enum InternalCommand {
Preview { line: String },
}
pub fn parse() -> Config {
pub fn config_from_env() -> Config {
Config::from_args()
}
pub fn internal_command() -> Option<InternalCommand> {
pub fn config_from_iter(args: Vec<&str>) -> Config {
Config::from_iter(args)
}
pub fn internal_command_from_env() -> Option<InternalCommand> {
let mut args = env::args();
args.next();
if args.next() == Some(String::from("preview")) {

18
src/welcome.rs Normal file
View file

@ -0,0 +1,18 @@
use crate::display;
use std::io::Write;
fn add_msg(tag: &str, comment: &str, snippet: &str, stdin: &mut std::process::ChildStdin) {
stdin
.write_all(display::format_line(tag, comment, snippet, 20, 60).as_bytes())
.unwrap();
}
pub fn cheatsheet(stdin: &mut std::process::ChildStdin) {
add_msg(
"cheatsheets",
"Download default cheatsheets",
"navi repo add denisidoro/cheats",
stdin,
);
add_msg("more info", "Read --help message", "navi --help", stdin);
}