From e92ee922de9f862c1a2dd4654ea451bb6d1ad156 Mon Sep 17 00:00:00 2001 From: crdx Date: Sat, 27 Jan 2024 22:02:38 +0000 Subject: [PATCH] Support recipe paths containing `::` in Bash completion script (#1863) --- completions/just.bash | 24 +++++++++++++++++++----- src/completions.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/completions/just.bash b/completions/just.bash index 15adcf9..6dca00b 100644 --- a/completions/just.bash +++ b/completions/just.bash @@ -1,12 +1,23 @@ _just() { - local i cur prev opts cmds + local i cur prev words cword opts cmds COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" + + # Modules use "::" as the separator, which is considered a wordbreak character in bash. + # The _get_comp_words_by_ref function is a hack to allow for exceptions to this rule without + # modifying the global COMP_WORDBREAKS environment variable. + if type _get_comp_words_by_ref &>/dev/null; then + _get_comp_words_by_ref -n : cur prev words cword + else + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + words=$COMP_WORDS + cword=$COMP_CWORD + fi + cmd="" opts="" - for i in ${COMP_WORDS[@]} + for i in ${words[@]} do case "${i}" in "$1") @@ -24,7 +35,7 @@ _just() { if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 - elif [[ ${COMP_CWORD} -eq 1 ]]; then + elif [[ ${cword} -eq 1 ]]; then local recipes=$(just --summary 2> /dev/null) if echo "${cur}" | \grep -qF '/'; then @@ -35,6 +46,9 @@ _just() { if [[ $? -eq 0 ]]; then COMPREPLY=( $(compgen -W "${recipes}" -- "${cur}") ) + if type __ltrim_colon_completions &>/dev/null; then + __ltrim_colon_completions "$cur" + fi return 0 fi fi diff --git a/src/completions.rs b/src/completions.rs index 3738288..2964d76 100644 --- a/src/completions.rs +++ b/src/completions.rs @@ -207,4 +207,37 @@ pub(crate) const BASH_COMPLETION_REPLACEMENTS: &[(&str, &str)] = &[ fi"#, ), (r" just)", r#" "$1")"#), + ( + r"local i cur prev opts cmds", + r"local i cur prev words cword opts cmds", + ), + ( + r#" cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}""#, + r#" + # Modules use "::" as the separator, which is considered a wordbreak character in bash. + # The _get_comp_words_by_ref function is a hack to allow for exceptions to this rule without + # modifying the global COMP_WORDBREAKS environment variable. + if type _get_comp_words_by_ref &>/dev/null; then + _get_comp_words_by_ref -n : cur prev words cword + else + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + words=$COMP_WORDS + cword=$COMP_CWORD + fi +"#, + ), + (r"for i in ${COMP_WORDS[@]}", r"for i in ${words[@]}"), + ( + r"elif [[ ${COMP_CWORD} -eq 1 ]]; then", + r"elif [[ ${cword} -eq 1 ]]; then", + ), + ( + r#"COMPREPLY=( $(compgen -W "${recipes}" -- "${cur}") )"#, + r#"COMPREPLY=( $(compgen -W "${recipes}" -- "${cur}") ) + if type __ltrim_colon_completions &>/dev/null; then + __ltrim_colon_completions "$cur" + fi"#, + ), ];