Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repos:
hooks:
- id: shfmt-docker
types: [text]
files: ^(bash_completion|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
files: ^(bash_completion(\.d/[0-9]{3}_.+)?|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
exclude: ^completions/(\.gitignore|Makefile.*)$

- repo: https://github.com/shellcheck-py/shellcheck-py
Expand All @@ -21,7 +21,7 @@ repos:
- id: shellcheck
args: [-f, gcc]
types: [text]
files: ^(bash_completion|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
files: ^(bash_completion(\.d/[0-9]{3}_.+)?|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
exclude: ^completions/(\.gitignore|Makefile.*)$
require_serial: false # We disable SC1090 anyway, so parallel is ok

Expand Down
54 changes: 20 additions & 34 deletions bash_completion
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,13 @@ _comp_unlocal()

# Assign variables one scope above the caller
# Usage: local varname [varname ...] &&
# _upvars [-v varname value] | [-aN varname [value ...]] ...
# _comp_upvars [-v varname value] | [-aN varname [value ...]] ...
# Available OPTIONS:
# -aN Assign next N values to varname as array
# -v Assign single value to varname
# @return 1 if error occurs
# @see https://fvue.nl/wiki/Bash:_Passing_variables_by_reference
_upvars()
_comp_upvars()
{
if ! (($#)); then
echo "bash_completion: $FUNCNAME: usage: $FUNCNAME" \
Expand Down Expand Up @@ -394,7 +394,7 @@ _comp_looks_like_path()
# @param $2 words Name of variable to return words to
# @param $3 cword Name of variable to return cword to
#
__reassemble_comp_words_by_ref()
_comp__reassemble_words()
{
local exclude i j line ref
# Exclude word separator characters?
Expand Down Expand Up @@ -454,7 +454,7 @@ __reassemble_comp_words_by_ref()
printf -v "$2[i]" %s "${COMP_WORDS[i]}"
done
fi
} # __reassemble_comp_words_by_ref()
} # _comp__reassemble_words()

# @param $1 exclude Characters out of $COMP_WORDBREAKS which should NOT be
# considered word breaks. This is useful for things like scp where
Expand All @@ -463,11 +463,11 @@ __reassemble_comp_words_by_ref()
# @param $2 words Name of variable to return words to
# @param $3 cword Name of variable to return cword to
# @param $4 cur Name of variable to return current word to complete to
# @see __reassemble_comp_words_by_ref()
__get_cword_at_cursor_by_ref()
# @see _comp__reassemble_words()
_comp__get_cword_at_cursor()
{
local cword words=()
__reassemble_comp_words_by_ref "$1" words cword
_comp__reassemble_words "$1" words cword

local i cur="" index=$COMP_POINT lead=${COMP_LINE:0:COMP_POINT}
# Cursor not at position 0 and not led by just space(s)?
Expand Down Expand Up @@ -498,7 +498,7 @@ __get_cword_at_cursor_by_ref()
((index < 0)) && index=0
fi

local "$2" "$3" "$4" && _upvars -a${#words[@]} "$2" ${words+"${words[@]}"} \
local "$2" "$3" "$4" && _comp_upvars -a${#words[@]} "$2" ${words+"${words[@]}"} \
-v "$3" "$cword" -v "$4" "${cur:0:index}"
}

Expand All @@ -508,7 +508,7 @@ __get_cword_at_cursor_by_ref()
# (For example, if the line is "ls foobar",
# and the cursor is here --------> ^
# Also one is able to cross over possible wordbreak characters.
# Usage: _get_comp_words_by_ref [OPTIONS] [VARNAMES]
# Usage: _comp_get_words [OPTIONS] [VARNAMES]
# Available VARNAMES:
# cur Return cur via $cur
# prev Return prev via $prev
Expand All @@ -527,9 +527,9 @@ __get_cword_at_cursor_by_ref()
#
# Example usage:
#
# $ _get_comp_words_by_ref -n : cur prev
# $ _comp_get_words -n : cur prev
#
_get_comp_words_by_ref()
_comp_get_words()
{
local exclude flag i OPTIND=1
local cur cword words=()
Expand Down Expand Up @@ -564,7 +564,7 @@ _get_comp_words_by_ref()
((OPTIND += 1))
done

__get_cword_at_cursor_by_ref "${exclude-}" words cword cur
_comp__get_cword_at_cursor "${exclude-}" words cword cur

[[ -v vcur ]] && {
upvars+=("$vcur")
Expand All @@ -583,21 +583,7 @@ _get_comp_words_by_ref()
upargs+=(-a${#words[@]} $vwords ${words+"${words[@]}"})
}

((${#upvars[@]})) && local "${upvars[@]}" && _upvars "${upargs[@]}"
}

# Get word previous to the current word.
# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4
# will properly return the previous word with respect to any given exclusions to
# COMP_WORDBREAKS.
# @deprecated Use `_get_comp_words_by_ref cur prev' instead
# @see _get_comp_words_by_ref()
#
_get_pword()
{
if ((COMP_CWORD >= 1)); then
_get_cword "${@-}" 1
fi
((${#upvars[@]})) && local "${upvars[@]}" && _comp_upvars "${upargs[@]}"
}

# If the word-to-complete contains a colon (:), left-trim COMPREPLY items with
Expand Down Expand Up @@ -662,7 +648,7 @@ _quote_readline_by_ref()
value=${value//'%'/%%} # Escape % for printf format.
# shellcheck disable=SC2059
printf -v value "$value" # Decode escape sequences of \....
local "$2" && _upvars -v "$2" "$value"
local "$2" && _comp_upvars -v "$2" "$value"
fi
fi
} # _quote_readline_by_ref()
Expand Down Expand Up @@ -909,7 +895,7 @@ _comp_variable_assignments()
# cur, prev, words, and cword are local, ditto split if you use -s.
#
# Options:
# -n EXCLUDE Passed to _get_comp_words_by_ref -n with redirection chars
# -n EXCLUDE Passed to _comp_get_words -n with redirection chars
# -e XSPEC Passed to _filedir as first arg for stderr redirections
# -o XSPEC Passed to _filedir as first arg for other output redirections
# -i XSPEC Passed to _filedir as first arg for stdin redirections
Expand Down Expand Up @@ -957,7 +943,7 @@ _comp_initialize()

COMPREPLY=()
local redir='@(?(+([0-9])|{[a-zA-Z_]*([a-zA-Z_0-9])})@(>?([>|&])|<?([>&])|<<?([-<]))|&>?(>))'
_get_comp_words_by_ref -n "$exclude<>&" cur prev words cword
_comp_get_words -n "$exclude<>&" cur prev words cword

# Complete variable names.
_variables && return 1
Expand Down Expand Up @@ -1696,7 +1682,7 @@ _realcommand()

# This function returns the first argument, excluding options
# @param $1 chars Characters out of $COMP_WORDBREAKS which should
# NOT be considered word breaks. See __reassemble_comp_words_by_ref.
# NOT be considered word breaks. See _comp__reassemble_words.
_get_first_arg()
{
local i
Expand All @@ -1712,13 +1698,13 @@ _get_first_arg()

# This function counts the number of args, excluding options
# @param $1 chars Characters out of $COMP_WORDBREAKS which should
# NOT be considered word breaks. See __reassemble_comp_words_by_ref.
# NOT be considered word breaks. See _comp__reassemble_words.
# @param $2 glob Options whose following argument should not be counted
# @param $3 glob Options that should be counted as args
_count_args()
{
local i cword words
__reassemble_comp_words_by_ref "${1-}" words cword
_comp__reassemble_words "${1-}" words cword

args=1
for ((i = 1; i < cword; i++)); do
Expand Down Expand Up @@ -2177,7 +2163,7 @@ _comp_command_offset()

COMPREPLY=()
local cur
_get_comp_words_by_ref cur
_comp_get_words cur

if ((COMP_CWORD == 0)); then
local IFS=$'\n'
Expand Down
30 changes: 25 additions & 5 deletions bash_completion.d/000_bash_completion_compat
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ _comp_deprecate_func _command_offset _comp_command_offset
_comp_deprecate_func _command _comp_command
_comp_deprecate_func _root_command _comp_root_command
_comp_deprecate_func _xfunc _comp_xfunc
_comp_deprecate_func _upvars _comp_upvars
_comp_deprecate_func __reassemble_comp_words_by_ref _comp__reassemble_words
_comp_deprecate_func __get_cword_at_cursor_by_ref _comp__get_cword_at_cursor
_comp_deprecate_func _get_comp_words_by_ref _comp_get_words

# Backwards compatibility for compat completions that use have().
# @deprecated should no longer be used; generally not needed with dynamically
Expand Down Expand Up @@ -47,14 +51,15 @@ dequote()
# @param $1 Variable name to assign value to
# @param $* Value(s) to assign. If multiple values, an array is
# assigned, otherwise a single value is assigned.
# NOTE: For assigning multiple variables, use '_upvars'. Do NOT
# NOTE: For assigning multiple variables, use '_comp_upvars'. Do NOT
# use multiple '_upvar' calls, since one '_upvar' call might
# reassign a variable to be used by another '_upvar' call.
# @see https://fvue.nl/wiki/Bash:_Passing_variables_by_reference
# @deprecated Use `_comp_upvars' instead
_upvar()
{
echo "bash_completion: $FUNCNAME: deprecated function," \
"use _upvars instead" >&2
"use _comp_upvars instead" >&2
if unset -v "$1"; then # Unset & validate varname
# shellcheck disable=SC2140 # TODO
if (($# == 2)); then
Expand All @@ -78,13 +83,13 @@ _upvar()
# current word (default is 0, previous is 1), respecting the exclusions
# given at $1. For example, `_get_cword "=:" 1' returns the word left of
# the current word, respecting the exclusions "=:".
# @deprecated Use `_get_comp_words_by_ref cur' instead
# @see _get_comp_words_by_ref()
# @deprecated Use `_comp_get_words cur' instead
# @see _comp_get_words()
_get_cword()
{
local LC_CTYPE=C
local cword words
__reassemble_comp_words_by_ref "${1-}" words cword
_comp__reassemble_words "${1-}" words cword

# return previous word offset by $2
if [[ ${2-} && ${2//[^0-9]/} ]]; then
Expand Down Expand Up @@ -125,8 +130,23 @@ _get_cword()
fi
} # _get_cword()

# Get word previous to the current word.
# This is a good alternative to `prev=${COMP_WORDS[COMP_CWORD-1]}' because bash4
# will properly return the previous word with respect to any given exclusions to
# COMP_WORDBREAKS.
# @deprecated Use `_comp_get_words cur prev' instead
# @see _comp_get_words()
#
_get_pword()
{
if ((COMP_CWORD >= 1)); then
_get_cword "${@-}" 1
fi
}

# @deprecated Use the variable `_comp_backup_glob` instead. This is the
# backward-compatibility name.
# shellcheck disable=SC2154 # defined in the main "bash_completion"
_backup_glob=$_comp_backup_glob

# ex: filetype=sh
7 changes: 4 additions & 3 deletions completions/ssh
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,10 @@ _ssh_suboption()
_comp_xfunc_ssh_suboption_check()
{
# Get prev and cur words without splitting on =
local cureq=$(_get_cword :=) preveq=$(_get_pword :=)
if [[ $cureq == *=* && $preveq == -*o ]]; then
_ssh_suboption "$cureq" "${1-}"
local cur prev
_comp_get_words -n := cur prev
if [[ $cur == *=* && $prev == -*o ]]; then
_ssh_suboption "$cur" "${1-}"
return $?
fi
return 1
Expand Down
2 changes: 1 addition & 1 deletion completions/xsltproc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ _xsltproc()
;;
esac

[[ $cword -gt 2 && $(_get_cword '' 2) == --?(string)param ]] && return
[[ $cword -gt 2 && ${words[cword - 2]} == --?(string)param ]] && return

if [[ $cur == -* ]]; then
COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur"))
Expand Down
4 changes: 2 additions & 2 deletions test/t/test_umount.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ def dummy_mnt(self, request, bash):
assert_bash_exec(
bash,
"_mnt_completion() { "
"local cur=$(_get_cword); "
"_comp_cmd_umount__linux_fstab $(_get_pword) < mount/test-fstab; "
"local cur prev;_comp_get_words cur prev; "
'_comp_cmd_umount__linux_fstab "$prev" < mount/test-fstab; '
"} && complete -F _mnt_completion _mnt",
)
request.addfinalizer(
Expand Down
2 changes: 1 addition & 1 deletion test/t/unit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ EXTRA_DIST = \
test_unit_expand_tilde_by_ref.py \
test_unit_filedir.py \
test_unit_find_unique_completion_pair.py \
test_unit_get_comp_words_by_ref.py \
test_unit_get_words.py \
test_unit_get_cword.py \
test_unit_initialize.py \
test_unit_ip_addresses.py \
Expand Down
6 changes: 3 additions & 3 deletions test/t/unit/test_unit_filedir.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ class TestUnitFiledir:
def functions(self, request, bash):
assert_bash_exec(
bash,
"_f() { local cur=$(_get_cword); unset -v COMPREPLY; _filedir; }; "
"_f() { local cur;_comp_get_words cur; unset -v COMPREPLY; _filedir; }; "
"complete -F _f f; "
"complete -F _f -o filenames f2",
)
assert_bash_exec(
bash,
"_g() { local cur=$(_get_cword); unset -v COMPREPLY; _filedir e1; }; "
"_g() { local cur;_comp_get_words cur; unset -v COMPREPLY; _filedir e1; }; "
"complete -F _g g",
)
assert_bash_exec(
bash,
"_fd() { local cur=$(_get_cword); unset -v COMPREPLY; _filedir -d; };"
"_fd() { local cur;_comp_get_words cur; unset -v COMPREPLY; _filedir -d; };"
"complete -F _fd fd",
)

Expand Down
Loading