Skip to content

Commit

Permalink
fix(completions): improve correctness of completions when whitespace …
Browse files Browse the repository at this point in the history
…is involved

compgen takes exactly one "word" argument; if multiple are passed, it
will ignore all but the first. If `$cur` is not quoted and contains
whitespace, it will be expanded into multiple words, so the completions
will be based only on the first word of `$cur`, which is clearly not
correct.

To fix this, quote `$cur` to prevent word splitting, where necessary
(Bash does not perform word splitting inside the extended test command
`[[`, so quotes aren't necessary there).
  • Loading branch information
sersorrel committed Mar 31, 2019
1 parent 0083d8b commit 5a08ff2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 25 deletions.
12 changes: 6 additions & 6 deletions src/completions/bash.rs
Expand Up @@ -44,7 +44,7 @@ impl<'a, 'b> BashGen<'a, 'b> {
{name})
opts="{name_opts}"
if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${{opts}}" -- ${{cur}}) )
COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
return 0
fi
case "${{prev}}" in
Expand All @@ -53,7 +53,7 @@ impl<'a, 'b> BashGen<'a, 'b> {
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${{opts}}" -- ${{cur}}) )
COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
return 0
;;
{subcmd_details}
Expand Down Expand Up @@ -105,7 +105,7 @@ complete -F _{name} -o bashdefault -o default {name}
{subcmd})
opts="{sc_opts}"
if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then
COMPREPLY=( $(compgen -W "${{opts}}" -- ${{cur}}) )
COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
return 0
fi
case "${{prev}}" in
Expand All @@ -114,7 +114,7 @@ complete -F _{name} -o bashdefault -o default {name}
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${{opts}}" -- ${{cur}}) )
COMPREPLY=( $(compgen -W "${{opts}}" -- "${{cur}}") )
return 0
;;"#,
subcmd_dets,
Expand Down Expand Up @@ -169,9 +169,9 @@ complete -F _{name} -o bashdefault -o default {name}
debugln!("BashGen::vals_for: o={}", o.b.name);
use args::AnyArg;
if let Some(vals) = o.possible_vals() {
format!(r#"$(compgen -W "{}" -- ${{cur}})"#, vals.join(" "))
format!(r#"$(compgen -W "{}" -- "${{cur}}")"#, vals.join(" "))
} else {
String::from("$(compgen -f ${cur})")
String::from(r#"$(compgen -f "${cur}")"#)
}
}

Expand Down
38 changes: 19 additions & 19 deletions tests/completions.rs
Expand Up @@ -34,7 +34,7 @@ static BASH: &'static str = r#"_myapp() {
myapp)
opts=" -h -V --help --version <file> test help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
Expand All @@ -43,14 +43,14 @@ static BASH: &'static str = r#"_myapp() {
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
myapp__help)
opts=" -h -V --help --version "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
Expand All @@ -59,26 +59,26 @@ static BASH: &'static str = r#"_myapp() {
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
myapp__test)
opts=" -h -V --help --version --case "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--case)
COMPREPLY=($(compgen -f ${cur}))
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
Expand Down Expand Up @@ -561,7 +561,7 @@ static BASH_SPECIAL_CMDS: &'static str = r#"_my_app() {
my_app)
opts=" -h -V --help --version <file> test some_cmd some-cmd-with-hypens help"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
Expand All @@ -570,14 +570,14 @@ static BASH_SPECIAL_CMDS: &'static str = r#"_my_app() {
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__help)
opts=" -h -V --help --version "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
Expand All @@ -586,13 +586,13 @@ static BASH_SPECIAL_CMDS: &'static str = r#"_my_app() {
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__some__cmd__with__hypens)
opts=" -h -V --help --version "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
Expand All @@ -601,45 +601,45 @@ static BASH_SPECIAL_CMDS: &'static str = r#"_my_app() {
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__some_cmd)
opts=" -h -V --help --version --config "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--config)
COMPREPLY=($(compgen -f ${cur}))
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
my_app__test)
opts=" -h -V --help --version --case "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--case)
COMPREPLY=($(compgen -f ${cur}))
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
;;
esac
Expand Down

0 comments on commit 5a08ff2

Please sign in to comment.