Merge pull request #3448 from akinomyoga/bash-fullquote

Use `-o fullquote` and `-o noquote` for more robust escaping in Bash completions
This commit is contained in:
Keith Hall authored and GitHub committed 2025-10-20 19:55:56 +03:00
commit 7c3fa7e1ce
2 files changed
+24 -4

No files matched your search

+2
View File
@@ -8,6 +8,8 @@
## Other ## Other
- Use more robust approach to escaping in Bash completions, see #3448 (@akinomyoga)
## Syntaxes ## Syntaxes
## Themes ## Themes
+22 -4
View File
@@ -14,18 +14,36 @@ __bat_escape_completions()
{ {
# Do not escape if completing a quoted value. # Do not escape if completing a quoted value.
[[ $cur == [\"\']* ]] && return 0 [[ $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 (( if ((
BASH_VERSINFO[0] > 5 || \
BASH_VERSINFO[0] == 5 && BASH_VERSINFO[1] >= 3
)); then
# bash >= 5.3 has "compopt -o fullquote", which exactly does
# what this function tries to do.
compopt -o fullquote
elif ((
BASH_VERSINFO[0] > 4 || \ BASH_VERSINFO[0] > 4 || \
BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] > 0 BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] > 0
)); then )); then
# 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).
local i local i
for i in ${!COMPREPLY[*]}; do for i in ${!COMPREPLY[*]}; do
printf -v "COMPREPLY[i]" %q "${COMPREPLY[i]}" printf -v "COMPREPLY[i]" %q "${COMPREPLY[i]}"
done done
# We can use "compopt -o noquote" available in bash >= 4.3 to
# prevent further quoting by the shell, which would be
# unexpectedly applied when a quoted result matches a filename.
if ((
BASH_VERSINFO[0] > 4 || \
BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 3
)); then
compopt -o noquote
fi
else else
compopt -o filenames compopt -o filenames
fi fi