I'm trying to debug auto completion script located in /usr/share/bash-completion/bash_completion
(bash completion package on every distro)
I did
export PS4='+'$'\t''$LINENO'$'\t # \t for proper indentation
set -x
in the current shell, then typed a command (following by space), and pressed tab to call auto completion.
This is a part of the result:
+ 2205 for dir in "${dirs[@]}"
+ 24 [[ -d /usr/share/bash-completion/completions ]]
+ 2207 for compfile in "$cmd" "$cmd.bash" "_$cmd"
+ 26 compfile=/usr/share/bash-completion/completions/bittch
+ 28 [[ -f /usr/share/bash-completion/completions/bittch ]]
+ 2207 for compfile in "$cmd" "$cmd.bash" "_$cmd"
As you see the first line number is 2205
which is the absolute line number inside the script. Surprisingly, the number of the next line (which is a nested block) is 24
, that is the line number relative to the function itself (see below)
__load_completion()
{
local -a dirs=(${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions)
local ifs=$IFS IFS=: dir cmd="${1##*/}" compfile
[[ -n $cmd ]] || return 1
for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do
dirs+=($dir/bash-completion/completions)
done
IFS=$ifs
if [[ $BASH_SOURCE == */* ]]; then
dirs+=("${BASH_SOURCE%/*}/completions")
else
dirs+=(./completions)
fi
local backslash=
if [[ $cmd == \\* ]]; then
cmd="${cmd:1}"
# If we already have a completion for the "real" command, use it
$(complete -p "$cmd" 2>/dev/null || echo false) "\\$cmd" && return 0
backslash=\\
fi
for dir in "${dirs[@]}"; do
[[ -d $dir ]] || continue
for compfile in "$cmd" "$cmd.bash" "_$cmd"; do
compfile="$dir/$compfile"
# Avoid trying to source dirs; https://bugzilla.redhat.com/903540
if [[ -f $compfile ]] && . "$compfile" &>/dev/null; then
[[ $backslash ]] && $(complete -p "$cmd") "\\$cmd"
return 0
fi
done
done
# Look up simple "xspec" completions
[[ -v _xspecs[$cmd] ]] &&
complete -F _filedir_xspec "$cmd" "$backslash$cmd" && return 0
return 1
}
I know that LINENO
represents The line number in the script or shell function currently executing. But these are in the same function, so either both should be relative (to the beginning of __load_completion()
) or absolute.
Why is this?
for
) get absolute line numbers, ordinary statements get relative.