From 307f0c11b2df76268e21924546c51ea7c2774010 Mon Sep 17 00:00:00 2001 From: Denis Isidoro Date: Fri, 9 Apr 2021 11:55:44 -0300 Subject: [PATCH] Improve bash and zsh widgets (#486) --- Cargo.lock | 2 +- Cargo.toml | 2 +- docs/installation.md | 2 - shell/navi.plugin.bash | 57 ++++++-------- shell/navi.plugin.zsh | 155 ++++++--------------------------------- src/cmds/func.rs | 40 ++++++++++ src/structures/config.rs | 3 +- 7 files changed, 89 insertions(+), 172 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2f5a70c..74200ea5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -308,7 +308,7 @@ dependencies = [ [[package]] name = "navi" -version = "2.14.0" +version = "2.15.0" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index eea9a57d..8b7da9bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "navi" -version = "2.14.0" +version = "2.15.0" authors = ["Denis Isidoro "] edition = "2018" description = "An interactive cheatsheet tool for the command-line" diff --git a/docs/installation.md b/docs/installation.md index bbb7b8e6..dd23230a 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -75,8 +75,6 @@ Feel free to be the maintainer of **navi** for any package manager you'd like! ### Installing the shell widget -The shell widget maintains your `.history`-like file consistent and allows you to edit commands before executing them. - If you want to install it, add this line to your `.bashrc`-like file: ```sh # bash diff --git a/shell/navi.plugin.bash b/shell/navi.plugin.bash index eeca6cb2..8495bf70 100644 --- a/shell/navi.plugin.bash +++ b/shell/navi.plugin.bash @@ -1,46 +1,35 @@ #!/usr/bin/env bash -_call_navi() { - local selected - - if [ -n "${READLINE_LINE}" ]; then - if selected="$(printf "%s" "$(navi --print --fzf-overrides '--no-select-1' --query "${READLINE_LINE}" ) -> Result<(), Error> { @@ -15,5 +17,43 @@ pub fn main(func: &Func, args: Vec) -> Result<(), Error> { Func::Welcome => handler::handle_config(config::config_from_iter( "navi --path /tmp/navi/irrelevant".split(' ').collect(), )), + Func::WidgetLastCommand => widget_last_command(), } } + +fn widget_last_command() -> Result<(), Error> { + let mut text = String::new(); + io::stdin().read_to_string(&mut text)?; + + let replacements = vec![("|", "ඛ"), ("||", "ග"), ("&&", "ඝ")]; + + let parts = shellwords::split(&text).unwrap_or_else(|_| text.split('|').map(|s| s.to_string()).collect()); + + for p in parts { + for (pattern, escaped) in replacements.clone() { + if p.contains(pattern) && p != pattern { + let replacement = p.replace(pattern, escaped); + text = text.replace(&p, &replacement); + } + } + } + + let mut extracted = text.clone(); + for (pattern, _) in replacements.clone() { + let mut new_parts = text.rsplit(pattern); + if let Some(extracted_attempt) = new_parts.next() { + if extracted_attempt.len() <= extracted.len() { + extracted = extracted_attempt.to_string(); + } + } + } + + for (pattern, escaped) in replacements.clone() { + text = text.replace(&escaped, &pattern); + extracted = extracted.replace(&escaped, &pattern); + } + + println!("{}", extracted.trim_start()); + + Ok(()) +} diff --git a/src/structures/config.rs b/src/structures/config.rs index afb2524a..1380036c 100644 --- a/src/structures/config.rs +++ b/src/structures/config.rs @@ -38,6 +38,7 @@ impl FromStr for Func { match s { "url::open" => Ok(Func::UrlOpen), "welcome" => Ok(Func::Welcome), + "widget::last_command" => Ok(Func::WidgetLastCommand), _ => Err("no match"), } } @@ -147,7 +148,7 @@ pub enum Command { /// Performs ad-hoc functions provided by navi Fn { /// Function name (example: "url::open") - #[clap(possible_values = &["url::welcome", "open"], case_insensitive = true)] + #[clap(possible_values = &["url::welcome", "open", "widget::last_command"], case_insensitive = true)] func: Func, /// List of arguments (example: "https://google.com") args: Vec,