Skip to content

Commit

Permalink
fix(ZSH Completions): fixes bug that caused panic on subcommands with…
Browse files Browse the repository at this point in the history
… aliases

ZSH completions now fully support subcommands with aliases. Only visible aliases will be displayed
in the completions.

Closes #714
  • Loading branch information
kbknapp committed Oct 30, 2016
1 parent 174a577 commit 5c70e1a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/app/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
19 changes: 14 additions & 5 deletions src/completions/zsh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String>) {
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);
Expand Down

0 comments on commit 5c70e1a

Please sign in to comment.