Skip to content

Commit

Permalink
feat(completions/zsh.rs): Implement postional argument possible value…
Browse files Browse the repository at this point in the history
…s completion
segevfiner committed Jan 15, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent a652260 commit f3b0afd
Showing 2 changed files with 22 additions and 8 deletions.
26 changes: 20 additions & 6 deletions src/completions/zsh.rs
Original file line number Diff line number Diff line change
@@ -322,21 +322,31 @@ fn get_args_of(p: &Parser) -> String {
ret.join("\n")
}

// Escape string inside single quotes and brackets
fn escape_string(string: &str) -> String {
// Escape help string inside single quotes and brackets
fn escape_help(string: &str) -> String {
string
.replace("\\", "\\\\")
.replace("'", "'\\''")
.replace("[", "\\[")
.replace("]", "\\]")
}

// Escape value string inside single quotes and parentheses
fn escape_value(string: &str) -> String {
string
.replace("\\", "\\\\")
.replace("'", "'\\''")
.replace("(", "\\(")
.replace(")", "\\)")
.replace(" ", "\\ ")
}

fn write_opts_of(p: &Parser) -> String {
debugln!("write_opts_of;");
let mut ret = vec![];
for o in p.opts() {
debugln!("write_opts_of:iter: o={}", o.name());
let help = o.help().map_or(String::new(), escape_string);
let help = o.help().map_or(String::new(), escape_help);
let mut conflicts = get_zsh_arg_conflicts!(p, o, INTERNAL_ERROR_MSG);
conflicts = if conflicts.is_empty() {
String::new()
@@ -390,7 +400,7 @@ fn write_flags_of(p: &Parser) -> String {
let mut ret = vec![];
for f in p.flags() {
debugln!("write_flags_of:iter: f={}", f.name());
let help = f.help().map_or(String::new(), escape_string);
let help = f.help().map_or(String::new(), escape_help);
let mut conflicts = get_zsh_arg_conflicts!(p, f, INTERNAL_ERROR_MSG);
conflicts = if conflicts.is_empty() {
String::new()
@@ -439,14 +449,18 @@ fn write_positionals_of(p: &Parser) -> String {
for arg in p.positionals() {
debugln!("write_positionals_of:iter: arg={}", arg.b.name);
let a = format!(
"\"{optional}:{name}{help}:_files\" \\",
"'{optional}:{name}{help}:{action}' \\",
optional = if !arg.b.is_set(ArgSettings::Required) { ":" } else { "" },
name = arg.b.name,
help = arg.b
.help
.map_or("".to_owned(), |v| " -- ".to_owned() + v)
.replace("[", "\\[")
.replace("]", "\\]")
.replace("]", "\\]"),
action = arg.possible_vals().map_or("_files".to_owned(), |values| {
format!("({})",
values.iter().map(|v| escape_value(*v)).collect::<Vec<String>>().join(" "))
})
);

debugln!("write_positionals_of:iter: Wrote...{}", a);
4 changes: 2 additions & 2 deletions tests/completions.rs
Original file line number Diff line number Diff line change
@@ -108,7 +108,7 @@ _myapp() {
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
"::file -- some input file:_files" \
'::file -- some input file:_files' \
":: :_myapp_commands" \
"*::: :->myapp" \
&& ret=0
@@ -408,7 +408,7 @@ _my_app() {
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
"::file -- some input file:_files" \
'::file -- some input file:_files' \
":: :_my_app_commands" \
"*::: :->my_app" \
&& ret=0

0 comments on commit f3b0afd

Please sign in to comment.