From 5c70e1a01bc977e44c10015d18bb8e215c32dfc8 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Sun, 30 Oct 2016 19:18:13 -0400 Subject: [PATCH] fix(ZSH Completions): fixes bug that caused panic on subcommands with aliases ZSH completions now fully support subcommands with aliases. Only visible aliases will be displayed in the completions. Closes #714 --- src/app/parser.rs | 2 +- src/completions/zsh.rs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/app/parser.rs b/src/app/parser.rs index 3f155dd0164..a3b0abfa767 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -1998,7 +1998,7 @@ impl<'a, 'b> Parser<'a, 'b> debugln!("Looking for sc...{}", sc); debugln!("Currently in Parser...{}", self.meta.bin_name.as_ref().unwrap()); for s in self.subcommands.iter() { - if s.p.meta.bin_name.as_ref().unwrap_or(&String::new()) == sc { + if s.p.meta.bin_name.as_ref().unwrap_or(&String::new()) == sc || (s.p.meta.aliases.is_some() && s.p.meta.aliases.as_ref().unwrap().iter().any(|&(s,_)| s == sc.split(' ').rev().next().expect(INTERNAL_ERROR_MSG))) { return Some(s); } if let Some(app) = s.p.find_subcommand(sc) { diff --git a/src/completions/zsh.rs b/src/completions/zsh.rs index 39e2b405c2c..576f1ce1a79 100644 --- a/src/completions/zsh.rs +++ b/src/completions/zsh.rs @@ -4,6 +4,7 @@ use std::io::Write; use std::ascii::AsciiExt; // Internal +use app::App; use app::parser::Parser; use args::{ArgSettings, AnyArg}; use completions; @@ -127,18 +128,26 @@ _{bin_name_underscore}_commands() {{ fn subcommands_and_args_of(p: &Parser) -> String { debugln!("fn=subcommands_and_args_of;"); let mut ret = vec![]; - - // Firs the subcommands - for sc in p.subcommands() { - debugln!("iter;subcommand={}", sc.p.meta.name); + fn add_sc(sc: &App, n: &str, ret: &mut Vec) { let s = format!("\"{name}:{help}\" \\", - name = sc.p.meta.name, + name = n, help = sc.p.meta.about.unwrap_or("")); if !s.is_empty() { ret.push(s); } } + // First the subcommands + for sc in p.subcommands() { + debugln!("iter;subcommand={}", sc.p.meta.name); + add_sc(sc, &sc.p.meta.name, &mut ret); + if let Some(ref v) = sc.p.meta.aliases { + for alias in v.iter().filter(|&&(_, vis)| vis).map(|&(n,_)| n) { + add_sc(sc, alias, &mut ret); + } + } + } + // Then the positional args for arg in p.positionals() { debugln!("iter;arg={}", arg.name);