From 85ca69a26397af1e8c9a4abfae636a00f84808f5 Mon Sep 17 00:00:00 2001 From: Denis Isidoro Date: Sun, 8 Aug 2021 08:12:19 -0300 Subject: [PATCH] Add cheats for navi itself (#599) Fixes #380 --- README.md | 1 + docs/cheat_example.cheat | 6 ++++++ docs/config_file.md | 29 +++++++++++++++++++++++++++ docs/navi.cheat | 38 +++++++++++++++++++++++++++++++++++ src/config/cli.rs | 12 ++++------- src/handler/core.rs | 2 +- src/handler/info.rs | 2 ++ src/parser.rs | 4 ++-- src/welcome.rs | 43 ++++++++++++++-------------------------- tests/core.bash | 2 +- 10 files changed, 99 insertions(+), 40 deletions(-) create mode 100644 docs/cheat_example.cheat create mode 100644 docs/config_file.md create mode 100644 docs/navi.cheat diff --git a/README.md b/README.md index 1765238..fa0b980 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Customization ------------- You can: +- [setup your own config file](docs/config_file.md) - [change colors](docs/customization.md#changing-colors) - [resize columns](docs/customization.md#resizing-columns) - [change how search is performed](docs/customization.md#overriding-fzf-options) diff --git a/docs/cheat_example.cheat b/docs/cheat_example.cheat new file mode 100644 index 0000000..972e0d6 --- /dev/null +++ b/docs/cheat_example.cheat @@ -0,0 +1,6 @@ +% first cheat + +# print something +echo "My name is !" + +$ name: whoami \ No newline at end of file diff --git a/docs/config_file.md b/docs/config_file.md new file mode 100644 index 0000000..5c64447 --- /dev/null +++ b/docs/config_file.md @@ -0,0 +1,29 @@ +Config file +----------------- + +* [Example](#example) +* [Location](#location) +* [Creating the file](#creating-the-file) + +### Example + +An example config can be found by running: +```sh +navi info config-example +``` + +You can also read it online by clicking [here](./config_file_example.yaml). + +### Location + +Run the following command to check where the config file is/should be located: +```sh +navi info config-path +``` + +### Creating the file + +Run the following command to generate a config file with the default parameters: +```sh +navi info config-example > "$(navi info config-path)" +``` diff --git a/docs/navi.cheat b/docs/navi.cheat new file mode 100644 index 0000000..f83b3e2 --- /dev/null +++ b/docs/navi.cheat @@ -0,0 +1,38 @@ +% cheatsheets + +# Download default cheatsheets +navi repo add denisidoro/cheats + +# Browse for cheatsheet repos +navi repo browse + +# Edit main local cheatsheets +f="$(navi info cheats-path)/main.cheat" +[ -f "$f" ] || navi info cheats-example > "$f" +$EDITOR "$f" + + +% config + +# Edit config file +f="$(navi info config-path)" +[ -f "$f" ] || navi info config-example > "$f" +$EDITOR "$f" + + +% 3rd-party + +# Search using tldr +navi --tldr "" + +# Search using cheatsh +navi --cheatsh "" + + +% help + +# Read command-line help text +navi --help + +# Read project README.md +navi fn url::open "https://github.com/denisidoro/navi" diff --git a/src/config/cli.rs b/src/config/cli.rs index 433c71a..50c47c7 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -11,7 +11,7 @@ use std::str::FromStr; const FINDER_POSSIBLE_VALUES: &[&str] = &["fzf", "skim"]; const WIDGET_POSSIBLE_VALUES: &[&str] = &["bash", "zsh", "fish"]; const FUNC_POSSIBLE_VALUES: &[&str] = &["url::open", "welcome", "widget::last_command", "map::expand"]; -const INFO_POSSIBLE_VALUES: &[&str] = &["cheats-path", "config-path", "config-example"]; +const INFO_POSSIBLE_VALUES: &[&str] = &["cheats-example", "cheats-path", "config-path", "config-example"]; impl FromStr for Shell { type Err = &'static str; @@ -45,6 +45,7 @@ impl FromStr for Info { fn from_str(s: &str) -> Result { match s { + "cheats-example" => Ok(Info::CheatsExample), "cheats-path" => Ok(Info::CheatsPath), "config-example" => Ok(Info::ConfigExample), "config-path" => Ok(Info::ConfigPath), @@ -62,13 +63,7 @@ MORE ENVIRONMENT VARIABLES: NAVI_CONFIG_YAML # config file content CONFIG FILE: - By default it's located in: - navi info config-path - - You can generate a config file by running: - navi info config-example > "$(navi info config-path)" - - Please check the generated config file for more info + Please check the online documentation or run `navi fn welcome` to setup the file FEATURE STABILITY: experimental # may be removed or changed at any time @@ -76,6 +71,7 @@ FEATURE STABILITY: EXAMPLES: navi # default behavior + navi fn welcome # show cheatsheets for navi itself navi --print # doesn't execute the snippet navi --tldr docker # search for docker cheatsheets using tldr navi --cheatsh docker # search for docker cheatsheets using cheatsh diff --git a/src/handler/core.rs b/src/handler/core.rs index a76daeb..e816aba 100644 --- a/src/handler/core.rs +++ b/src/handler/core.rs @@ -33,7 +33,7 @@ pub fn main() -> Result<()> { if let Some(variables) = res { Ok(Some(variables)) } else { - welcome::populate_cheatsheet(stdin); + welcome::populate_cheatsheet(stdin)?; Ok(Some(VariableMap::new())) } }) diff --git a/src/handler/info.rs b/src/handler/info.rs index 4ace98d..f893178 100644 --- a/src/handler/info.rs +++ b/src/handler/info.rs @@ -4,6 +4,7 @@ use anyhow::Result; #[derive(Debug)] pub enum Info { + CheatsExample, CheatsPath, ConfigPath, ConfigExample, @@ -11,6 +12,7 @@ pub enum Info { pub fn main(info: &Info) -> Result<()> { match info { + Info::CheatsExample => println!("{}", include_str!("../../docs/cheat_example.cheat")), Info::CheatsPath => println!("{}", pathbuf_to_string(&filesystem::default_cheat_pathbuf()?)?), Info::ConfigPath => println!("{}", pathbuf_to_string(&filesystem::default_config_pathbuf()?)?), Info::ConfigExample => println!("{}", include_str!("../../docs/config_file_example.yaml")), diff --git a/src/parser.rs b/src/parser.rs index 3173e45..1aeb9ee 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -115,7 +115,7 @@ fn write_cmd( denylist: Option<&Vec>, visited_lines: &mut HashSet, ) -> Result<()> { - if item.snippet.len() <= 1 { + if item.comment.is_empty() || item.snippet.trim().is_empty() { return Ok(()); } @@ -212,7 +212,7 @@ pub fn read_lines( item.comment = without_prefix(&line); } // variable - else if line.starts_with('$') { + else if line.starts_with('$') && line.contains(':') { should_break = write_cmd(&item, stdin, allowlist, denylist, visited_lines).is_err(); item.snippet = String::from(""); let (variable, command, opts) = parse_variable_line(&line).with_context(|| { diff --git a/src/welcome.rs b/src/welcome.rs index 55d8d50..2363014 100644 --- a/src/welcome.rs +++ b/src/welcome.rs @@ -3,12 +3,10 @@ use crate::config::CONFIG; use crate::extractor; use crate::finder::structures::Opts as FinderOpts; use crate::finder::Finder; +use crate::parser; use crate::structures::cheat::VariableMap; -use crate::structures::item::Item; -use crate::writer; use anyhow::Context; use anyhow::Result; -use std::io::Write; pub fn main() -> Result<()> { let config = &CONFIG; @@ -17,7 +15,7 @@ pub fn main() -> Result<()> { let (raw_selection, variables, files) = config .finder() .call(opts, |stdin, _| { - populate_cheatsheet(stdin); + populate_cheatsheet(stdin)?; Ok(Some(VariableMap::new())) }) .context("Failed getting selection and variables from finder")?; @@ -32,30 +30,19 @@ pub fn main() -> Result<()> { Ok(()) } -fn add_msg(tags: &str, comment: &str, snippet: &str, stdin: &mut std::process::ChildStdin) { - let item = Item { - tags: tags.to_string(), - comment: comment.to_string(), - snippet: snippet.to_string(), - file_index: 0, - }; - stdin - .write_all(writer::write(&item).as_bytes()) - .expect("Could not write to fzf's stdin"); -} +pub fn populate_cheatsheet(stdin: &mut std::process::ChildStdin) -> Result<()> { + let cheatsheet = include_str!("../docs/navi.cheat"); -pub fn populate_cheatsheet(stdin: &mut std::process::ChildStdin) { - add_msg( - "cheatsheets", - "Download default cheatsheets", - "navi repo add denisidoro/cheats", + parser::read_lines( + cheatsheet.split('\n').into_iter().map(|s| Ok(s.to_string())), + "welcome", + 0, + &mut VariableMap::new(), + &mut Default::default(), stdin, - ); - add_msg( - "cheatsheets", - "Browse for cheatsheet repos", - "navi repo browse", - stdin, - ); - add_msg("more info", "Read --help message", "navi --help", stdin); + None, + None, + )?; + + Ok(()) } diff --git a/tests/core.bash b/tests/core.bash index d9fd80b..ae23424 100644 --- a/tests/core.bash +++ b/tests/core.bash @@ -47,7 +47,7 @@ test::_escape() { test::equals() { local -r actual="$(cat)" local -r expected="$(echo "${1:-}")" - + local -r actual2="$(echo "$actual" | test::_escape)" local -r expected2="$(echo "$expected" | test::_escape)"