Skip to content

Commit

Permalink
Improve bash completion escaping
Browse files Browse the repository at this point in the history
`compopt -o filenames` is a cheap way to accomplish mostly wanted
behavior. However it is semantically incorrect when we are not actually
completing filenames, and has side effects -- for example adds a
trailing slash to candidates matching present dirs.

bash >= 4.1 can `printf -v` to an array index, use it instead where
available.
  • Loading branch information
scop authored and sharkdp committed Sep 11, 2022
1 parent 66edfe5 commit 2dbc88d
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions assets/completions/bat.bash.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,27 @@ __bat_init_completion()
_get_comp_words_by_ref "$@" cur prev words cword
}

__bat_escape_completions()
{
# Do not escape if completing a quoted value.
[[ $cur == [\"\']* ]] && return 0
# printf -v to an array index is available in bash >= 4.1.
# Use it if available, as -o filenames is semantically incorrect if
# we are not actually completing filenames, and it has side effects
# (e.g. adds trailing slash to candidates matching present dirs).
if ((
BASH_VERSINFO[0] > 4 || \
BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] > 0
)); then
local i
for i in ${!COMPREPLY[*]}; do
printf -v "COMPREPLY[i]" %q "${COMPREPLY[i]}"
done
else
compopt -o filenames
fi
}

_bat() {
local cur prev words cword split=false
if declare -F _init_completion >/dev/null 2>&1; then
Expand Down Expand Up @@ -45,7 +66,7 @@ _bat() {
printf "%s\n" "$lang"
done
)" -- "$cur"))
compopt -o filenames # for escaping
__bat_escape_completions
return 0
;;
-H | --highlight-line | \
Expand Down Expand Up @@ -92,7 +113,7 @@ _bat() {
--theme)
local IFS=$'\n'
COMPREPLY=($(compgen -W "$("$1" --list-themes)" -- "$cur"))
compopt -o filenames # for escaping
__bat_escape_completions
return 0
;;
--style)
Expand Down

0 comments on commit 2dbc88d

Please sign in to comment.