From 37546c653a77e78ab099b9d3e3483a653398c295 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Tue, 26 Jun 2018 22:03:46 -0400 Subject: [PATCH] fix(Elvish): fixes the porting from v2 to v3 for the Elvish shell completions --- src/build/app/mod.rs | 1 + src/completions/elvish.rs | 53 ++++++++++++++++++++------------------- src/completions/mod.rs | 3 ++- src/completions/shell.rs | 3 +++ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index e02d8765..61b0262e 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -1894,6 +1894,7 @@ impl<'a, 'b> App<'a, 'b> { Shell::Zsh => format!("_{}", name), Shell::PowerShell => format!("_{}.ps1", name), Shell::Elvish => format!("{}.elv", name), + _ => panic!("Unsupported shell type for completion generation") }; let mut file = match File::create(out_dir.join(file_name)) { diff --git a/src/completions/elvish.rs b/src/completions/elvish.rs index 9a5f21a3..ec50479b 100644 --- a/src/completions/elvish.rs +++ b/src/completions/elvish.rs @@ -2,25 +2,26 @@ use std::io::Write; // Internal -use app::parser::Parser; +use build::App; use INTERNAL_ERROR_MSG; -pub struct ElvishGen<'a, 'b> +pub struct ElvishGen<'a, 'b, 'c> where 'a: 'b, + 'b: 'c { - p: &'b Parser<'a, 'b>, + app: &'c App<'a, 'b>, } -impl<'a, 'b> ElvishGen<'a, 'b> { - pub fn new(p: &'b Parser<'a, 'b>) -> Self { ElvishGen { p: p } } +impl<'a, 'b, 'c> ElvishGen<'a, 'b, 'c> { + pub fn new(p: &'c App<'a, 'b>) -> Self { ElvishGen { app: p } } pub fn generate_to(&self, buf: &mut W) { - let bin_name = self.p.meta.bin_name.as_ref().unwrap(); + let bin_name = self.app.bin_name.as_ref().unwrap(); let mut names = vec![]; let subcommands_cases = - generate_inner(self.p, "", &mut names); + generate_inner(self.app, "", &mut names); let result = format!(r#" edit:completion:arg-completer[{bin_name}] = [@words]{{ @@ -60,50 +61,50 @@ fn get_tooltip(help: Option<&str>, data: T) -> String { } } -fn generate_inner<'a, 'b, 'p>( - p: &'p Parser<'a, 'b>, +fn generate_inner<'a, 'b, 'c>( + p: &'c App<'a, 'b>, previous_command_name: &str, - names: &mut Vec<&'p str>, -) -> String { + names: &mut Vec<&'a str>, +) -> String where 'a: 'b, 'b: 'c{ debugln!("ElvishGen::generate_inner;"); let command_name = if previous_command_name.is_empty() { - p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG).clone() + p.bin_name.as_ref().expect(INTERNAL_ERROR_MSG).clone() } else { - format!("{};{}", previous_command_name, &p.meta.name) + format!("{};{}", previous_command_name, &p.name) }; let mut completions = String::new(); let preamble = String::from("\n cand "); - for option in p.opts() { - if let Some(data) = option.s.short { - let tooltip = get_tooltip(option.b.help, data); + for option in opts!(p) { + if let Some(data) = option.short { + let tooltip = get_tooltip(option.help, data); completions.push_str(&preamble); completions.push_str(format!("-{} '{}'", data, tooltip).as_str()); } - if let Some(data) = option.s.long { - let tooltip = get_tooltip(option.b.help, data); + if let Some(data) = option.long { + let tooltip = get_tooltip(option.help, data); completions.push_str(&preamble); completions.push_str(format!("--{} '{}'", data, tooltip).as_str()); } } - for flag in p.flags() { - if let Some(data) = flag.s.short { - let tooltip = get_tooltip(flag.b.help, data); + for flag in flags!(p) { + if let Some(data) = flag.short { + let tooltip = get_tooltip(flag.help, data); completions.push_str(&preamble); completions.push_str(format!("-{} '{}'", data, tooltip).as_str()); } - if let Some(data) = flag.s.long { - let tooltip = get_tooltip(flag.b.help, data); + if let Some(data) = flag.long { + let tooltip = get_tooltip(flag.help, data); completions.push_str(&preamble); completions.push_str(format!("--{} '{}'", data, tooltip).as_str()); } } for subcommand in &p.subcommands { - let data = &subcommand.p.meta.name; - let tooltip = get_tooltip(subcommand.p.meta.about, data); + let data = &subcommand.name; + let tooltip = get_tooltip(subcommand.about, data); completions.push_str(&preamble); completions.push_str(format!("{} '{}'", data, tooltip).as_str()); } @@ -118,7 +119,7 @@ fn generate_inner<'a, 'b, 'p>( for subcommand in &p.subcommands { let subcommand_subcommands_cases = - generate_inner(&subcommand.p, &command_name, names); + generate_inner(&subcommand, &command_name, names); subcommands_cases.push_str(&subcommand_subcommands_cases); } diff --git a/src/completions/mod.rs b/src/completions/mod.rs index 1dd4363e..b08cc266 100644 --- a/src/completions/mod.rs +++ b/src/completions/mod.rs @@ -28,11 +28,12 @@ impl<'a, 'b> ComplGen<'a, 'b> { pub fn generate(&self, for_shell: Shell, buf: &mut W) { match for_shell { - Shell::Elvish => ElvishGen::new(self.p).generate_to(buf), Shell::Bash => BashGen::new(self.0).generate_to(buf), Shell::Fish => FishGen::new(self.0).generate_to(buf), Shell::Zsh => ZshGen::new(self.0).generate_to(buf), Shell::PowerShell => PowerShellGen::new(self.0).generate_to(buf), + Shell::Elvish => ElvishGen::new(self.0).generate_to(buf), + _ => panic!("Unsupported shell type for generating completions") } } } diff --git a/src/completions/shell.rs b/src/completions/shell.rs index c311c722..b1f13167 100644 --- a/src/completions/shell.rs +++ b/src/completions/shell.rs @@ -17,6 +17,8 @@ pub enum Shell { PowerShell, /// Generates a completion file for Elvish Elvish, + #[doc(hidden)] + __Nonexhaustive, } impl Shell { @@ -47,6 +49,7 @@ impl fmt::Display for Shell { Shell::Zsh => write!(f, "ZSH"), Shell::PowerShell => write!(f, "POWERSHELL"), Shell::Elvish => write!(f, "ELVISH"), + _ => panic!("Unsupported shell type for completion generation") } } }