From 68d0338ddd2db19402529d792d2d413552f7c426 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Tue, 12 Oct 2021 00:16:56 +0100 Subject: [PATCH 1/2] chore: Minor doc and style changes --- clap_generate/README.md | 4 +--- clap_generate/src/lib.rs | 17 +++++++++-------- clap_generate/src/shell.rs | 29 +++++++++++++++-------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/clap_generate/README.md b/clap_generate/README.md index adf8b47b..51610dae 100644 --- a/clap_generate/README.md +++ b/clap_generate/README.md @@ -7,8 +7,6 @@ Generates completions (and other things) for [`clap`](https://github.com/clap-rs/clap) based CLIs -* [Documentation][docs] +* [Documentation](https://docs.rs/clap_generate) * [Questions & Discussions](https://github.com/clap-rs/clap/discussions) * [Website](https://clap.rs/) - -[docs]: https://docs.rs/clap_generate diff --git a/clap_generate/src/lib.rs b/clap_generate/src/lib.rs index 3e0454b2..d94ff960 100644 --- a/clap_generate/src/lib.rs +++ b/clap_generate/src/lib.rs @@ -5,7 +5,14 @@ // See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files in this repository // for more information. -//! Generates completions (and other things) for [`clap`](https://github.com/clap-rs/clap) based CLIs +#![doc(html_logo_url = "https://clap.rs/images/media/clap.png")] +#![doc(html_root_url = "https://docs.rs/clap_generate/3.0.0-beta.4")] +#![doc = include_str!("../README.md")] +#![deny(missing_docs, trivial_casts, unused_allocation, trivial_numeric_casts)] +#![forbid(unsafe_code)] +#![allow(clippy::needless_doctest_main)] + +//! ## Quick Start //! //! - For generating at compile-time, see [`generate_to`] //! - For generating at runtime, see [`generate`] @@ -13,7 +20,7 @@ //! [`Shell`] is a convenience `enum` for an argument value type that implements `Generator` //! for each natively-supported shell type. //! -//! # Example +//! ## Example //! //! ```rust,no_run //! use clap::{App, AppSettings, Arg, ValueHint}; @@ -48,12 +55,6 @@ //! } //! ``` -#![doc(html_logo_url = "https://clap.rs/images/media/clap.png")] -#![doc(html_root_url = "https://docs.rs/clap_generate/3.0.0-beta.4")] -#![deny(missing_docs, trivial_casts, unused_allocation, trivial_numeric_casts)] -#![forbid(unsafe_code)] -#![allow(clippy::needless_doctest_main)] - const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \ report at https://github.com/clap-rs/clap/issues"; diff --git a/clap_generate/src/shell.rs b/clap_generate/src/shell.rs index 7587d3da..05946979 100644 --- a/clap_generate/src/shell.rs +++ b/clap_generate/src/shell.rs @@ -3,6 +3,8 @@ use std::str::FromStr; use clap::{ArgEnum, ArgValue}; +use crate::{generators, Generator}; + /// Shell with auto-generated completion script available. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[non_exhaustive] @@ -63,35 +65,34 @@ impl ArgEnum for Shell { } fn to_arg_value<'a>(&self) -> Option> { - let value = match self { + Some(match self { Shell::Bash => ArgValue::new("bash"), Shell::Elvish => ArgValue::new("elvish"), Shell::Fish => ArgValue::new("fish"), Shell::PowerShell => ArgValue::new("powershell"), Shell::Zsh => ArgValue::new("zsh"), - }; - Some(value) + }) } } -impl crate::Generator for Shell { +impl Generator for Shell { fn file_name(&self, name: &str) -> String { match self { - Shell::Bash => crate::generators::Bash.file_name(name), - Shell::Elvish => crate::generators::Elvish.file_name(name), - Shell::Fish => crate::generators::Fish.file_name(name), - Shell::PowerShell => crate::generators::PowerShell.file_name(name), - Shell::Zsh => crate::generators::Zsh.file_name(name), + Shell::Bash => generators::Bash.file_name(name), + Shell::Elvish => generators::Elvish.file_name(name), + Shell::Fish => generators::Fish.file_name(name), + Shell::PowerShell => generators::PowerShell.file_name(name), + Shell::Zsh => generators::Zsh.file_name(name), } } fn generate(&self, app: &clap::App, buf: &mut dyn std::io::Write) { match self { - Shell::Bash => crate::generators::Bash.generate(app, buf), - Shell::Elvish => crate::generators::Elvish.generate(app, buf), - Shell::Fish => crate::generators::Fish.generate(app, buf), - Shell::PowerShell => crate::generators::PowerShell.generate(app, buf), - Shell::Zsh => crate::generators::Zsh.generate(app, buf), + Shell::Bash => generators::Bash.generate(app, buf), + Shell::Elvish => generators::Elvish.generate(app, buf), + Shell::Fish => generators::Fish.generate(app, buf), + Shell::PowerShell => generators::PowerShell.generate(app, buf), + Shell::Zsh => generators::Zsh.generate(app, buf), } } } From 0a61c8aa081219f5c00cbfa035463d31e0d7150b Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Tue, 12 Oct 2021 00:17:09 +0100 Subject: [PATCH 2/2] fix: Whitespace in our generators **is** important and we need to fix it --- clap_generate/Cargo.toml | 1 - clap_generate/src/generators/shells/bash.rs | 72 +++++++++------------ clap_generate/src/generators/shells/zsh.rs | 9 ++- clap_generate/tests/completions/bash.rs | 15 ----- clap_generate/tests/completions/mod.rs | 8 +-- clap_generate/tests/completions/zsh.rs | 5 +- clap_generate/tests/value_hints.rs | 1 - 7 files changed, 37 insertions(+), 74 deletions(-) diff --git a/clap_generate/Cargo.toml b/clap_generate/Cargo.toml index 226be76e..801bfe51 100644 --- a/clap_generate/Cargo.toml +++ b/clap_generate/Cargo.toml @@ -35,7 +35,6 @@ clap = { path = "../", version = "=3.0.0-beta.4" } [dev-dependencies] pretty_assertions = "0.7" version-sync = "0.9" -itertools = "0.10" [features] default = [] diff --git a/clap_generate/src/generators/shells/bash.rs b/clap_generate/src/generators/shells/bash.rs index 0f3266a2..bb2689e7 100644 --- a/clap_generate/src/generators/shells/bash.rs +++ b/clap_generate/src/generators/shells/bash.rs @@ -33,8 +33,7 @@ impl Generator for Bash { case \"${{i}}\" in {name}) cmd=\"{cmd}\" - ;; - {subcmds} + ;;{subcmds} *) ;; esac @@ -47,16 +46,14 @@ impl Generator for Bash { COMPREPLY=( $(compgen -W \"${{opts}}\" -- \"${{cur}}\") ) return 0 fi - case \"${{prev}}\" in - {name_opts_details} + case \"${{prev}}\" in{name_opts_details} *) COMPREPLY=() ;; esac COMPREPLY=( $(compgen -W \"${{opts}}\" -- \"${{cur}}\") ) return 0 - ;; - {subcmd_details} + ;;{subcmd_details} esac }} @@ -77,7 +74,7 @@ complete -F _{name} -o bashdefault -o default {name} fn all_subcommands(app: &App) -> String { debug!("all_subcommands"); - let mut subcmds = String::new(); + let mut subcmds = vec![String::new()]; let mut scs = Bash .all_subcommands(app) .iter() @@ -87,25 +84,23 @@ fn all_subcommands(app: &App) -> String { scs.sort(); scs.dedup(); - for sc in &scs { - subcmds = format!( - "{} - {name}) + subcmds.extend(scs.iter().map(|sc| { + format!( + "{name}) cmd+=\"__{fn_name}\" ;;", - subcmds, name = sc, fn_name = sc.replace("-", "__") - ); - } + ) + })); - subcmds + subcmds.join("\n ") } fn subcommand_details(app: &App) -> String { debug!("subcommand_details"); - let mut subcmd_dets = String::new(); + let mut subcmd_dets = vec![String::new()]; let mut scs = Bash .all_subcommands(app) .iter() @@ -114,17 +109,15 @@ fn subcommand_details(app: &App) -> String { scs.sort(); - for sc in &scs { - subcmd_dets = format!( - "{} - {subcmd}) + subcmd_dets.extend(scs.iter().map(|sc| { + format!( + "{subcmd}) opts=\"{sc_opts}\" if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then COMPREPLY=( $(compgen -W \"${{opts}}\" -- \"${{cur}}\") ) return 0 fi - case \"${{prev}}\" in - {opts_details} + case \"${{prev}}\" in{opts_details} *) COMPREPLY=() ;; @@ -132,56 +125,51 @@ fn subcommand_details(app: &App) -> String { COMPREPLY=( $(compgen -W \"${{opts}}\" -- \"${{cur}}\") ) return 0 ;;", - subcmd_dets, subcmd = sc.replace("-", "__"), sc_opts = all_options_for_path(app, &*sc), level = sc.split("__").map(|_| 1).sum::(), opts_details = option_details_for_path(app, &*sc) - ); - } + ) + })); - subcmd_dets + subcmd_dets.join("\n ") } fn option_details_for_path(app: &App, path: &str) -> String { debug!("option_details_for_path: path={}", path); let p = Bash.find_subcommand_with_path(app, path.split("__").skip(1).collect()); - let mut opts = String::new(); + let mut opts = vec![String::new()]; for o in p.get_opts() { if let Some(longs) = o.get_long_and_visible_aliases() { - for long in longs { - opts = format!( - "{} - --{}) + opts.extend(longs.iter().map(|long| { + format!( + "--{}) COMPREPLY=({}) return 0 ;;", - opts, long, vals_for(o) - ); - } + ) + })); } if let Some(shorts) = o.get_short_and_visible_aliases() { - for short in shorts { - opts = format!( - "{} - -{}) + opts.extend(shorts.iter().map(|short| { + format!( + "-{}) COMPREPLY=({}) return 0 ;;", - opts, short, vals_for(o) - ); - } + ) + })); } } - opts + opts.join("\n ") } fn vals_for(o: &Arg) -> String { diff --git a/clap_generate/src/generators/shells/zsh.rs b/clap_generate/src/generators/shells/zsh.rs index dc34b588..99aebb33 100644 --- a/clap_generate/src/generators/shells/zsh.rs +++ b/clap_generate/src/generators/shells/zsh.rs @@ -19,8 +19,7 @@ impl Generator for Zsh { w!( buf, format!( - "\ -#compdef {name} + "#compdef {name} autoload -U is-at-least @@ -36,8 +35,7 @@ _{name}() {{ fi local context curcontext=\"$curcontext\" state line - {initial_args} - {subcommands} + {initial_args}{subcommands} }} {subcommand_details} @@ -250,7 +248,8 @@ fn get_subcommands_of(parent: &App) -> String { } format!( - "case $state in + " + case $state in ({name}) words=($line[{pos}] \"${{words[@]}}\") (( CURRENT += 1 )) diff --git a/clap_generate/tests/completions/bash.rs b/clap_generate/tests/completions/bash.rs index 9b5ce8b2..8f388a80 100644 --- a/clap_generate/tests/completions/bash.rs +++ b/clap_generate/tests/completions/bash.rs @@ -43,7 +43,6 @@ static BASH: &str = r#"_myapp() { myapp) cmd="myapp" ;; - help) cmd+="__help" ;; @@ -63,7 +62,6 @@ static BASH: &str = r#"_myapp() { return 0 fi case "${prev}" in - *) COMPREPLY=() ;; @@ -71,7 +69,6 @@ static BASH: &str = r#"_myapp() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; - myapp__help) opts=" -h -V --help --version " if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -79,7 +76,6 @@ static BASH: &str = r#"_myapp() { return 0 fi case "${prev}" in - *) COMPREPLY=() ;; @@ -94,7 +90,6 @@ static BASH: &str = r#"_myapp() { return 0 fi case "${prev}" in - --case) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -145,7 +140,6 @@ static BASH_SPECIAL_CMDS: &str = r#"_my_app() { my_app) cmd="my_app" ;; - help) cmd+="__help" ;; @@ -171,7 +165,6 @@ static BASH_SPECIAL_CMDS: &str = r#"_my_app() { return 0 fi case "${prev}" in - *) COMPREPLY=() ;; @@ -179,7 +172,6 @@ static BASH_SPECIAL_CMDS: &str = r#"_my_app() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; - my_app__help) opts=" -h -V --help --version " if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then @@ -187,7 +179,6 @@ static BASH_SPECIAL_CMDS: &str = r#"_my_app() { return 0 fi case "${prev}" in - *) COMPREPLY=() ;; @@ -202,7 +193,6 @@ static BASH_SPECIAL_CMDS: &str = r#"_my_app() { return 0 fi case "${prev}" in - *) COMPREPLY=() ;; @@ -217,7 +207,6 @@ static BASH_SPECIAL_CMDS: &str = r#"_my_app() { return 0 fi case "${prev}" in - --config) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -236,7 +225,6 @@ static BASH_SPECIAL_CMDS: &str = r#"_my_app() { return 0 fi case "${prev}" in - --case) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -298,7 +286,6 @@ static BASH_ALIASES: &str = r#"_cmd() { cmd) cmd="cmd" ;; - *) ;; esac @@ -312,7 +299,6 @@ static BASH_ALIASES: &str = r#"_cmd() { return 0 fi case "${prev}" in - --option) COMPREPLY=($(compgen -f "${cur}")) return 0 @@ -336,7 +322,6 @@ static BASH_ALIASES: &str = r#"_cmd() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; - esac } diff --git a/clap_generate/tests/completions/mod.rs b/clap_generate/tests/completions/mod.rs index 4fe41670..5a5dd050 100644 --- a/clap_generate/tests/completions/mod.rs +++ b/clap_generate/tests/completions/mod.rs @@ -28,11 +28,5 @@ pub fn common(gen: G, app: &mut App, name: &str, fixture: &str) { generate(gen, app, name, &mut buf); let string = String::from_utf8(buf).unwrap(); - assert_eq!(&normalize(&string), &normalize(fixture)); -} - -fn normalize(string: &str) -> String { - use itertools::Itertools; - - string.lines().map(|s| s.trim_end()).join("\n") + assert_eq!(&string, fixture); } diff --git a/clap_generate/tests/completions/zsh.rs b/clap_generate/tests/completions/zsh.rs index e257d152..ba1f2726 100644 --- a/clap_generate/tests/completions/zsh.rs +++ b/clap_generate/tests/completions/zsh.rs @@ -308,7 +308,6 @@ _my_app() { '--brackets[List packages \[filter\]]' \ '--expansions[Execute the shell command with $SHELL]' \ && ret=0 - } (( $+functions[_my_app_commands] )) || @@ -370,7 +369,8 @@ _arguments "${_arguments_options[@]}" \ ":: :_my_app__second_commands" \ "*::: :->second" \ && ret=0 -case $state in + + case $state in (second) words=($line[1] "${words[@]}") (( CURRENT += 1 )) @@ -488,7 +488,6 @@ _cmd() { '--flg[cmd flag]' \ '::positional:' \ && ret=0 - } (( $+functions[_cmd_commands] )) || diff --git a/clap_generate/tests/value_hints.rs b/clap_generate/tests/value_hints.rs index bd09581d..3587c865 100644 --- a/clap_generate/tests/value_hints.rs +++ b/clap_generate/tests/value_hints.rs @@ -119,7 +119,6 @@ _my_app() { '--help[Print help information]' \ '*::command_with_args:_cmdambivalent' \ && ret=0 - } (( $+functions[_my_app_commands] )) ||