Fixed `quote_readline'.
This fixes completing filenames containing single quote (') on bash-4. Also added emulation of `-o filenames' to _filedir. Added tests for _filedir. Fixed array assignment within __reassemble_comp_words_by_ref().
This commit is contained in:
parent
f9db6abdc1
commit
c9c98da36e
129
bash_completion
129
bash_completion
@ -188,19 +188,14 @@ quote()
|
||||
echo \'${1//\'/\'\\\'\'}\' #'# Help vim syntax highlighting
|
||||
}
|
||||
|
||||
# This function quotes the argument in a way so that readline dequoting
|
||||
# results in the original argument
|
||||
# @see _quote_readline_by_ref()
|
||||
quote_readline()
|
||||
{
|
||||
if [ ${BASH_VERSINFO[0]} -ge 4 ]; then
|
||||
# This function isn't really necessary on bash 4
|
||||
# See: http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html
|
||||
echo "${1}"
|
||||
return
|
||||
fi
|
||||
local t="${1//\\/\\\\}"
|
||||
echo \'${t//\'/\'\\\'\'}\' #'# Help vim syntax highlighting
|
||||
}
|
||||
local quoted
|
||||
_quote_readline_by_ref "$1" ret
|
||||
printf %s "$ret"
|
||||
} # quote_readline()
|
||||
|
||||
|
||||
# This function shell-dequotes the argument
|
||||
dequote()
|
||||
@ -224,8 +219,6 @@ __reassemble_comp_words_by_ref() {
|
||||
if [[ $1 ]]; then
|
||||
# Yes, exclude word separator characters;
|
||||
# Exclude only those characters, which were really included
|
||||
# NOTE: On bash-3, `COMP_WORDBREAKS' is empty which is ok; no
|
||||
# additional word breaking is done on bash-3.
|
||||
exclude="${1//[^$COMP_WORDBREAKS]}"
|
||||
fi
|
||||
|
||||
@ -240,7 +233,7 @@ __reassemble_comp_words_by_ref() {
|
||||
[ $j -ge 2 ] && ((j--))
|
||||
# Append word separator to current word
|
||||
ref="$2[$j]"
|
||||
eval $2[$j]=\""${!ref}${COMP_WORDS[$i]}"\"
|
||||
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
|
||||
# Indicate new cword
|
||||
[ $i = $COMP_CWORD ] && eval $3=$j
|
||||
# Indicate next word if available, else end *both* while and for loop
|
||||
@ -248,7 +241,7 @@ __reassemble_comp_words_by_ref() {
|
||||
done
|
||||
# Append word to current word
|
||||
ref="$2[$j]"
|
||||
eval $2[$j]=\""${!ref}${COMP_WORDS[$i]}"\"
|
||||
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
|
||||
# Indicate new cword
|
||||
[ $i = $COMP_CWORD ] && eval $3=$j
|
||||
done
|
||||
@ -369,6 +362,46 @@ __ltrim_colon_completions() {
|
||||
} # __ltrim_colon_completions()
|
||||
|
||||
|
||||
# This function quotes the argument in a way so that readline dequoting
|
||||
# results in the original argument. This is necessary for at least
|
||||
# `compgen' which requires its arguments quoted/escaped:
|
||||
#
|
||||
# $ ls "a'b/"
|
||||
# c
|
||||
# $ compgen -f "a'b/" # Wrong, doesn't return output
|
||||
# $ compgen -f "a\'b/" # Good (bash-4)
|
||||
# a\'b/c
|
||||
# $ compgen -f "a\\\\\'b/" # Good (bash-3)
|
||||
# a\'b/c
|
||||
#
|
||||
# See also: http://lists.gnu.org/archive/html/bug-bash/2009-03/msg00155.html
|
||||
# @param $1 Argument to quote
|
||||
# @param $2 Name of variable to return result to
|
||||
_quote_readline_by_ref()
|
||||
{
|
||||
# If bash <= 3 and argument starts with single quote ('), double-escape
|
||||
# if [[ ${BASH_VERSINFO[0]} -le 3 && ${1:0:1} == "'" ]]; then
|
||||
# local t
|
||||
# printf -v t %q "${1:1}"
|
||||
# printf -v $2 %q "$t"
|
||||
# else
|
||||
# printf -v $2 %q "$1"
|
||||
# fi
|
||||
if [[ ${1:0:1} == "'" ]]; then
|
||||
# Quote word, leaving out first character
|
||||
printf -v $2 %q "${1:1}"
|
||||
if [[ ${BASH_VERSINFO[0]} -le 3 ]]; then
|
||||
# Double-quote word on bash-3
|
||||
printf -v $2 %q ${!2}
|
||||
fi
|
||||
elif [[ ${BASH_VERSINFO[0]} -le 3 && ${1:0:1} == '"' ]]; then
|
||||
printf -v $2 %q "${1:1}"
|
||||
else
|
||||
printf -v $2 %q "$1"
|
||||
fi
|
||||
} # _quote_readline_by_ref()
|
||||
|
||||
|
||||
# This function performs file and directory completion. It's better than
|
||||
# simply using 'compgen -f', because it honours spaces in filenames.
|
||||
# If passed -d, it completes only on directories. If passed anything else,
|
||||
@ -376,12 +409,12 @@ __ltrim_colon_completions() {
|
||||
#
|
||||
_filedir()
|
||||
{
|
||||
local IFS=$'\t\n' xspec
|
||||
local i IFS=$'\t\n' xspec
|
||||
|
||||
_expand || return 0
|
||||
__expand_tilde_by_ref cur
|
||||
|
||||
local -a toks
|
||||
local tmp
|
||||
local quoted tmp
|
||||
|
||||
# TODO: I've removed a "[ -n $tmp ] &&" before `printf '%s\n' $tmp',
|
||||
# and everything works again. If this bug
|
||||
@ -393,28 +426,74 @@ _filedir()
|
||||
# because quotes-in-comments-in-a-subshell cause errors on
|
||||
# bash-3.1. See also:
|
||||
# http://www.mail-archive.com/bug-bash@gnu.org/msg01667.html
|
||||
_quote_readline_by_ref "$cur" quoted
|
||||
toks=( ${toks[@]-} $(
|
||||
compgen -d -- "$(quote_readline "$cur")" | {
|
||||
compgen -d -- "$quoted" | {
|
||||
while read -r tmp; do
|
||||
printf '%s\n' $tmp
|
||||
done
|
||||
}
|
||||
))
|
||||
|
||||
# On bash-3, special characters need to be escaped extra. This is
|
||||
# unless the first character is a single quote ('). If the single
|
||||
# quote appears further down the string, bash default completion also
|
||||
# fails, e.g.:
|
||||
#
|
||||
# $ ls 'a&b/'
|
||||
# f
|
||||
# $ foo 'a&b/<TAB> # Becomes: foo 'a&b/f'
|
||||
# $ foo a'&b/<TAB> # Nothing happens
|
||||
#
|
||||
if [[ "$1" != -d ]]; then
|
||||
xspec=${1:+"!*.$1"}
|
||||
if [[ ${cur:0:1} == "'" && ${BASH_VERSINFO[0]} -ge 4 ]]; then
|
||||
toks=( ${toks[@]-} $(
|
||||
compgen -f -X "$xspec" -- "$(quote_readline "$cur")" | {
|
||||
while read -r tmp; do
|
||||
[ -n $tmp ] && printf '%s\n' $tmp
|
||||
eval compgen -f -X \"\$xspec\" -- $quoted
|
||||
) )
|
||||
else
|
||||
toks=( ${toks[@]-} $(
|
||||
compgen -f -X "$xspec" -- $quoted
|
||||
) )
|
||||
fi
|
||||
if [ ${#toks[@]} -ne 0 ]; then
|
||||
# If `compopt' is available, set `-o filenames'
|
||||
compopt &>/dev/null && compopt -o filenames ||
|
||||
# No, `compopt' isn't available;
|
||||
# Is `-o filenames' set?
|
||||
[[ "$(complete -p ${COMP_WORDS[0]})" == *"-o filenames"* ]] || {
|
||||
# No, `-o filenames' isn't set;
|
||||
# Emulate `-o filenames'
|
||||
# NOTE: A side-effect of emulating `-o filenames' is that backslash escape
|
||||
# characters are visible within the list of presented completions, e.g.
|
||||
# the completions look like:
|
||||
#
|
||||
# $ foo a<TAB>
|
||||
# a\ b/ a\$b/
|
||||
#
|
||||
# whereas with `-o filenames' active the completions look like:
|
||||
#
|
||||
# $ ls a<TAB>
|
||||
# a b/ a$b/
|
||||
#
|
||||
for ((i=0; i < ${#toks[@]}; i++)); do
|
||||
# If directory exists, append slash (/)
|
||||
if [[ ${cur:0:1} != "'" ]]; then
|
||||
[[ -d ${toks[i]} ]] && toks[i]="${toks[i]}"/
|
||||
if [[ ${cur:0:1} == '"' ]]; then
|
||||
toks[i]=${toks[i]//\\/\\\\}
|
||||
toks[i]=${toks[i]//\"/\\\"}
|
||||
toks[i]=${toks[i]//\$/\\\$}
|
||||
else
|
||||
toks[i]=$(printf %q ${toks[i]})
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
))
|
||||
fi
|
||||
fi
|
||||
|
||||
COMPREPLY=( "${COMPREPLY[@]}" "${toks[@]}" )
|
||||
[ ${#COMPREPLY[@]} -ne 0 ] && type compopt &>/dev/null && \
|
||||
compopt -o filenames
|
||||
} # _filedir()
|
||||
|
||||
|
||||
|
0
test/fixtures/_filedir/a b/i
vendored
Normal file
0
test/fixtures/_filedir/a b/i
vendored
Normal file
0
test/fixtures/_filedir/a"b/d
vendored
Normal file
0
test/fixtures/_filedir/a"b/d
vendored
Normal file
0
test/fixtures/_filedir/a$b/h
vendored
Normal file
0
test/fixtures/_filedir/a$b/h
vendored
Normal file
0
test/fixtures/_filedir/a&b/f
vendored
Normal file
0
test/fixtures/_filedir/a&b/f
vendored
Normal file
0
test/fixtures/_filedir/a'b/c
vendored
Normal file
0
test/fixtures/_filedir/a'b/c
vendored
Normal file
0
test/fixtures/_filedir/a\b/g
vendored
Normal file
0
test/fixtures/_filedir/a\b/g
vendored
Normal file
0
test/fixtures/_filedir/ab/e
vendored
Normal file
0
test/fixtures/_filedir/ab/e
vendored
Normal file
0
test/fixtures/compgen/a'b/c
vendored
Normal file
0
test/fixtures/compgen/a'b/c
vendored
Normal file
121
test/fixtures/compgen/t1.txt
vendored
Normal file
121
test/fixtures/compgen/t1.txt
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
BASH=/bin/bash
|
||||
BASH_ARGC=()
|
||||
BASH_ARGV=()
|
||||
BASH_LINENO=()
|
||||
BASH_SOURCE=()
|
||||
BASH_VERSINFO=([0]="3" [1]="2" [2]="39" [3]="1" [4]="release" [5]="i486-pc-linux-gnu")
|
||||
BASH_VERSION='3.2.39(1)-release'
|
||||
CDPL_DIRS=([0]="/home/freddy/proj")
|
||||
CDPM_DIRS=
|
||||
CDP_DIRS=([0]="/home/freddy/proj" [1]="")
|
||||
COLUMNS=130
|
||||
COMP_CACHE=/home/freddy/.bash_completion_lib.d/cache~
|
||||
COMP_DIR=/etc/bash_completion_lib
|
||||
COMP_PATH=/home/freddy/.bash_completion_lib.d:/etc/bash_completion_lib
|
||||
COMP_RESTRICT_BY_EXTENSION=0
|
||||
COMP_VERSION=bash_completion_lib-1.3.1
|
||||
DIRSTACK=()
|
||||
EDITOR=/usr/bin/vim
|
||||
EUID=1000
|
||||
GPGKEY=10A575C3
|
||||
GPG_AGENT_INFO=/tmp/gpg-Pg6JXR/S.gpg-agent:4129:1
|
||||
GPG_TTY=/dev/pts/0
|
||||
GREP_OPTIONS='--exclude '\''distrib/*'\'' --exclude tags'
|
||||
GROUPS=()
|
||||
HISTCONTROL=ignoreboth
|
||||
HISTFILE=/home/freddy/.bash_history
|
||||
HISTFILESIZE=500
|
||||
HISTIGNORE=exit
|
||||
HISTSIZE=500
|
||||
HOME=/home/freddy
|
||||
HOSTNAME=blondy
|
||||
HOSTTYPE=i486
|
||||
IFS=$' \t\n'
|
||||
LANG=en_US
|
||||
LANGUAGE=en_NL:en_US:en_GB:en
|
||||
LINES=49
|
||||
LOGNAME=freddy
|
||||
MACHTYPE=i486-pc-linux-gnu
|
||||
MAIL=/var/mail/freddy
|
||||
MAILCHECK=60
|
||||
OLDPWD=/home/freddy/.bash_completion_lib.d
|
||||
OPTERR=1
|
||||
OPTIND=1
|
||||
OSTYPE=linux-gnu
|
||||
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/freddy/proj/rc/bin
|
||||
PIPESTATUS=([0]="0")
|
||||
PPID=29352
|
||||
PS1=$'\\[\E[0;34m\\]\\!\\[\E[0m\\]\\[\E[1;32m\\]$(stoppedjobs)\\[\E[0m\\]:\\u@\\h:\\w> \\[\E[m\\]'
|
||||
PS2='> '
|
||||
PS4='+ '
|
||||
PWD=/home/freddy/proj/bashCompletion/bash-completion.git/test/fixtures/compgen
|
||||
SHELL=/bin/bash
|
||||
SHELLOPTS=braceexpand:hashall:histexpand:interactive-comments:monitor:vi
|
||||
SHLVL=1
|
||||
SSH_AUTH_SOCK=/tmp/ssh-xhQbo29352/agent.29352
|
||||
SSH_CLIENT='192.168.123.143 37670 4822'
|
||||
SSH_CONNECTION='192.168.123.143 37670 192.168.123.8 4822'
|
||||
SSH_TTY=/dev/pts/0
|
||||
TERM=xterm
|
||||
UID=1000
|
||||
USER=freddy
|
||||
VIM=/home/freddy/.vim
|
||||
VIMRUNTIME=/usr/share/vim/vimcurrent
|
||||
_=GPG_AGENT_INFO
|
||||
bash205='3.2.39(1)-release'
|
||||
bash205b='3.2.39(1)-release'
|
||||
bash3='3.2.39(1)-release'
|
||||
cdots ()
|
||||
{
|
||||
[ -d "$1$2" ] && cd "$1$2" || eval cd "$1$2"
|
||||
}
|
||||
comp_load ()
|
||||
{
|
||||
local cmd=${COMP_WORDS[0]} dir globs OLDIFS=$IFS;
|
||||
IFS=:;
|
||||
local -a aPaths=($COMP_PATH);
|
||||
IFS='
|
||||
';
|
||||
globs=($(
|
||||
for dir in "${aPaths[@]}"; do
|
||||
echo \"$dir\"/complete\*/\*.$cmd
|
||||
echo \"$dir\"/complete\*/$cmd\!
|
||||
echo \"$dir\"/complete\*/$cmd
|
||||
done
|
||||
));
|
||||
IFS=$OLDIFS;
|
||||
if ! declare -F comp_include >&/dev/null; then
|
||||
for dir in "${aPaths[@]}";
|
||||
do
|
||||
[ -r "$dir/include/comp_include" ] && . "$dir/include/comp_include" && break;
|
||||
done;
|
||||
fi;
|
||||
comp_include comp_load_init;
|
||||
comp_load_init;
|
||||
local script="$(eval find "${globs[@]}" 2> /dev/null | head -1)";
|
||||
local link comp=${script##*/};
|
||||
[[ ${comp: -1:1} == ! ]] || {
|
||||
link=${comp#*.};
|
||||
comp=${comp%.$link}
|
||||
};
|
||||
local path=${script%/*};
|
||||
[ "$script" -a -r "$path/$comp" ] && . "$path/$comp" && declare -F _$comp >&/dev/null && {
|
||||
[ ${COMP_INSTALL:-1} -eq 0 ] || _comp_install $comp "$path"
|
||||
} && _$comp $link;
|
||||
comp_load_deinit
|
||||
}
|
||||
nameTerminal ()
|
||||
{
|
||||
[ "${TERM:0:5}" = "xterm" ] && local ansiNrTab=0;
|
||||
[ "$TERM" = "rxvt" ] && local ansiNrTab=61;
|
||||
[ "$TERM" = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0;
|
||||
[ $ansiNrTab ] && echo -n ''"]$ansiNrTab;$1"'';
|
||||
[ $ansiNrWindow -a "$2" ] && echo -n ''"]$ansiNrWindow;$2"''
|
||||
}
|
||||
stoppedjobs ()
|
||||
{
|
||||
if [ "$(jobs -s)" ]; then
|
||||
echo -n "%";
|
||||
jobs -s | wc -l;
|
||||
fi
|
||||
}
|
121
test/fixtures/compgen/t2.txt
vendored
Normal file
121
test/fixtures/compgen/t2.txt
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
BASH=/bin/bash
|
||||
BASH_ARGC=()
|
||||
BASH_ARGV=()
|
||||
BASH_LINENO=()
|
||||
BASH_SOURCE=()
|
||||
BASH_VERSINFO=([0]="3" [1]="2" [2]="39" [3]="1" [4]="release" [5]="i486-pc-linux-gnu")
|
||||
BASH_VERSION='3.2.39(1)-release'
|
||||
CDPL_DIRS=([0]="/home/freddy/proj")
|
||||
CDPM_DIRS=
|
||||
CDP_DIRS=([0]="/home/freddy/proj" [1]="")
|
||||
COLUMNS=130
|
||||
COMP_CACHE=/home/freddy/.bash_completion_lib.d/cache~
|
||||
COMP_DIR=/etc/bash_completion_lib
|
||||
COMP_PATH=/home/freddy/.bash_completion_lib.d:/etc/bash_completion_lib
|
||||
COMP_RESTRICT_BY_EXTENSION=0
|
||||
COMP_VERSION=bash_completion_lib-1.3.1
|
||||
DIRSTACK=()
|
||||
EDITOR=/usr/bin/vim
|
||||
EUID=1000
|
||||
GPGKEY=10A575C3
|
||||
GPG_AGENT_INFO=/tmp/gpg-Pg6JXR/S.gpg-agent:4129:1
|
||||
GPG_TTY=/dev/pts/0
|
||||
GREP_OPTIONS='--exclude '\''distrib/*'\'' --exclude tags'
|
||||
GROUPS=()
|
||||
HISTCONTROL=ignoreboth
|
||||
HISTFILE=/home/freddy/.bash_history
|
||||
HISTFILESIZE=500
|
||||
HISTIGNORE=exit
|
||||
HISTSIZE=500
|
||||
HOME=/home/freddy
|
||||
HOSTNAME=blondy
|
||||
HOSTTYPE=i486
|
||||
IFS=$' \t\n'
|
||||
LANG=en_US
|
||||
LANGUAGE=en_NL:en_US:en_GB:en
|
||||
LINES=49
|
||||
LOGNAME=freddy
|
||||
MACHTYPE=i486-pc-linux-gnu
|
||||
MAIL=/var/mail/freddy
|
||||
MAILCHECK=60
|
||||
OLDPWD=/home/freddy/.bash_completion_lib.d
|
||||
OPTERR=1
|
||||
OPTIND=1
|
||||
OSTYPE=linux-gnu
|
||||
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/freddy/proj/rc/bin
|
||||
PIPESTATUS=([0]="0")
|
||||
PPID=29352
|
||||
PS1=$'\\[\E[0;34m\\]\\!\\[\E[0m\\]\\[\E[1;32m\\]$(stoppedjobs)\\[\E[0m\\]:\\u@\\h:\\w> \\[\E[m\\]'
|
||||
PS2='> '
|
||||
PS4='+ '
|
||||
PWD=/home/freddy/proj/bashCompletion/bash-completion.git/test/fixtures/compgen
|
||||
SHELL=/bin/bash
|
||||
SHELLOPTS=braceexpand:hashall:histexpand:interactive-comments:monitor:vi
|
||||
SHLVL=1
|
||||
SSH_AUTH_SOCK=/tmp/ssh-xhQbo29352/agent.29352
|
||||
SSH_CLIENT='192.168.123.143 37670 4822'
|
||||
SSH_CONNECTION='192.168.123.143 37670 192.168.123.8 4822'
|
||||
SSH_TTY=/dev/pts/0
|
||||
TERM=xterm
|
||||
UID=1000
|
||||
USER=freddy
|
||||
VIM=/home/freddy/.vim
|
||||
VIMRUNTIME=/usr/share/vim/vimcurrent
|
||||
_='a\\\'\''b/'
|
||||
bash205='3.2.39(1)-release'
|
||||
bash205b='3.2.39(1)-release'
|
||||
bash3='3.2.39(1)-release'
|
||||
cdots ()
|
||||
{
|
||||
[ -d "$1$2" ] && cd "$1$2" || eval cd "$1$2"
|
||||
}
|
||||
comp_load ()
|
||||
{
|
||||
local cmd=${COMP_WORDS[0]} dir globs OLDIFS=$IFS;
|
||||
IFS=:;
|
||||
local -a aPaths=($COMP_PATH);
|
||||
IFS='
|
||||
';
|
||||
globs=($(
|
||||
for dir in "${aPaths[@]}"; do
|
||||
echo \"$dir\"/complete\*/\*.$cmd
|
||||
echo \"$dir\"/complete\*/$cmd\!
|
||||
echo \"$dir\"/complete\*/$cmd
|
||||
done
|
||||
));
|
||||
IFS=$OLDIFS;
|
||||
if ! declare -F comp_include >&/dev/null; then
|
||||
for dir in "${aPaths[@]}";
|
||||
do
|
||||
[ -r "$dir/include/comp_include" ] && . "$dir/include/comp_include" && break;
|
||||
done;
|
||||
fi;
|
||||
comp_include comp_load_init;
|
||||
comp_load_init;
|
||||
local script="$(eval find "${globs[@]}" 2> /dev/null | head -1)";
|
||||
local link comp=${script##*/};
|
||||
[[ ${comp: -1:1} == ! ]] || {
|
||||
link=${comp#*.};
|
||||
comp=${comp%.$link}
|
||||
};
|
||||
local path=${script%/*};
|
||||
[ "$script" -a -r "$path/$comp" ] && . "$path/$comp" && declare -F _$comp >&/dev/null && {
|
||||
[ ${COMP_INSTALL:-1} -eq 0 ] || _comp_install $comp "$path"
|
||||
} && _$comp $link;
|
||||
comp_load_deinit
|
||||
}
|
||||
nameTerminal ()
|
||||
{
|
||||
[ "${TERM:0:5}" = "xterm" ] && local ansiNrTab=0;
|
||||
[ "$TERM" = "rxvt" ] && local ansiNrTab=61;
|
||||
[ "$TERM" = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0;
|
||||
[ $ansiNrTab ] && echo -n ''"]$ansiNrTab;$1"'';
|
||||
[ $ansiNrWindow -a "$2" ] && echo -n ''"]$ansiNrWindow;$2"''
|
||||
}
|
||||
stoppedjobs ()
|
||||
{
|
||||
if [ "$(jobs -s)" ]; then
|
||||
echo -n "%";
|
||||
jobs -s | wc -l;
|
||||
fi
|
||||
}
|
121
test/fixtures/compgen/t3.txt
vendored
Normal file
121
test/fixtures/compgen/t3.txt
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
BASH=/bin/bash
|
||||
BASH_ARGC=()
|
||||
BASH_ARGV=()
|
||||
BASH_LINENO=()
|
||||
BASH_SOURCE=()
|
||||
BASH_VERSINFO=([0]="3" [1]="2" [2]="39" [3]="1" [4]="release" [5]="i486-pc-linux-gnu")
|
||||
BASH_VERSION='3.2.39(1)-release'
|
||||
CDPL_DIRS=([0]="/home/freddy/proj")
|
||||
CDPM_DIRS=
|
||||
CDP_DIRS=([0]="/home/freddy/proj" [1]="")
|
||||
COLUMNS=130
|
||||
COMP_CACHE=/home/freddy/.bash_completion_lib.d/cache~
|
||||
COMP_DIR=/etc/bash_completion_lib
|
||||
COMP_PATH=/home/freddy/.bash_completion_lib.d:/etc/bash_completion_lib
|
||||
COMP_RESTRICT_BY_EXTENSION=0
|
||||
COMP_VERSION=bash_completion_lib-1.3.1
|
||||
DIRSTACK=()
|
||||
EDITOR=/usr/bin/vim
|
||||
EUID=1000
|
||||
GPGKEY=10A575C3
|
||||
GPG_AGENT_INFO=/tmp/gpg-Pg6JXR/S.gpg-agent:4129:1
|
||||
GPG_TTY=/dev/pts/0
|
||||
GREP_OPTIONS='--exclude '\''distrib/*'\'' --exclude tags'
|
||||
GROUPS=()
|
||||
HISTCONTROL=ignoreboth
|
||||
HISTFILE=/home/freddy/.bash_history
|
||||
HISTFILESIZE=500
|
||||
HISTIGNORE=exit
|
||||
HISTSIZE=500
|
||||
HOME=/home/freddy
|
||||
HOSTNAME=blondy
|
||||
HOSTTYPE=i486
|
||||
IFS=$' \t\n'
|
||||
LANG=en_US
|
||||
LANGUAGE=en_NL:en_US:en_GB:en
|
||||
LINES=49
|
||||
LOGNAME=freddy
|
||||
MACHTYPE=i486-pc-linux-gnu
|
||||
MAIL=/var/mail/freddy
|
||||
MAILCHECK=60
|
||||
OLDPWD=/home/freddy/.bash_completion_lib.d
|
||||
OPTERR=1
|
||||
OPTIND=1
|
||||
OSTYPE=linux-gnu
|
||||
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/freddy/proj/rc/bin
|
||||
PIPESTATUS=([0]="0")
|
||||
PPID=29352
|
||||
PS1=$'\\[\E[0;34m\\]\\!\\[\E[0m\\]\\[\E[1;32m\\]$(stoppedjobs)\\[\E[0m\\]:\\u@\\h:\\w> \\[\E[m\\]'
|
||||
PS2='> '
|
||||
PS4='+ '
|
||||
PWD=/home/freddy/proj/bashCompletion/bash-completion.git/test/fixtures/compgen
|
||||
SHELL=/bin/bash
|
||||
SHELLOPTS=braceexpand:hashall:histexpand:interactive-comments:monitor:vi
|
||||
SHLVL=1
|
||||
SSH_AUTH_SOCK=/tmp/ssh-xhQbo29352/agent.29352
|
||||
SSH_CLIENT='192.168.123.143 37670 4822'
|
||||
SSH_CONNECTION='192.168.123.143 37670 192.168.123.8 4822'
|
||||
SSH_TTY=/dev/pts/0
|
||||
TERM=xterm
|
||||
UID=1000
|
||||
USER=freddy
|
||||
VIM=/home/freddy/.vim
|
||||
VIMRUNTIME=/usr/share/vim/vimcurrent
|
||||
_='a\\\'\''b/'
|
||||
bash205='3.2.39(1)-release'
|
||||
bash205b='3.2.39(1)-release'
|
||||
bash3='3.2.39(1)-release'
|
||||
cdots ()
|
||||
{
|
||||
[ -d "$1$2" ] && cd "$1$2" || eval cd "$1$2"
|
||||
}
|
||||
comp_load ()
|
||||
{
|
||||
local cmd=${COMP_WORDS[0]} dir globs OLDIFS=$IFS;
|
||||
IFS=:;
|
||||
local -a aPaths=($COMP_PATH);
|
||||
IFS='
|
||||
';
|
||||
globs=($(
|
||||
for dir in "${aPaths[@]}"; do
|
||||
echo \"$dir\"/complete\*/\*.$cmd
|
||||
echo \"$dir\"/complete\*/$cmd\!
|
||||
echo \"$dir\"/complete\*/$cmd
|
||||
done
|
||||
));
|
||||
IFS=$OLDIFS;
|
||||
if ! declare -F comp_include >&/dev/null; then
|
||||
for dir in "${aPaths[@]}";
|
||||
do
|
||||
[ -r "$dir/include/comp_include" ] && . "$dir/include/comp_include" && break;
|
||||
done;
|
||||
fi;
|
||||
comp_include comp_load_init;
|
||||
comp_load_init;
|
||||
local script="$(eval find "${globs[@]}" 2> /dev/null | head -1)";
|
||||
local link comp=${script##*/};
|
||||
[[ ${comp: -1:1} == ! ]] || {
|
||||
link=${comp#*.};
|
||||
comp=${comp%.$link}
|
||||
};
|
||||
local path=${script%/*};
|
||||
[ "$script" -a -r "$path/$comp" ] && . "$path/$comp" && declare -F _$comp >&/dev/null && {
|
||||
[ ${COMP_INSTALL:-1} -eq 0 ] || _comp_install $comp "$path"
|
||||
} && _$comp $link;
|
||||
comp_load_deinit
|
||||
}
|
||||
nameTerminal ()
|
||||
{
|
||||
[ "${TERM:0:5}" = "xterm" ] && local ansiNrTab=0;
|
||||
[ "$TERM" = "rxvt" ] && local ansiNrTab=61;
|
||||
[ "$TERM" = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0;
|
||||
[ $ansiNrTab ] && echo -n ''"]$ansiNrTab;$1"'';
|
||||
[ $ansiNrWindow -a "$2" ] && echo -n ''"]$ansiNrWindow;$2"''
|
||||
}
|
||||
stoppedjobs ()
|
||||
{
|
||||
if [ "$(jobs -s)" ]; then
|
||||
echo -n "%";
|
||||
jobs -s | wc -l;
|
||||
fi
|
||||
}
|
@ -33,6 +33,11 @@ expect {
|
||||
-re "\r\nbar\\s+bar bar.d\\s+foo\\s+foo.d" {
|
||||
if {[lindex $BASH_VERSINFO 0] < 4} {xfail "$test"} {fail "$test"}
|
||||
}
|
||||
-re "\r\nbar\\s+bar\\\\ bar.d/\\s+foo\\s+foo.d/" {
|
||||
# On bash-3, the space in `bar bar.d' is escaped with a backslash
|
||||
# as a side-effect of emulating `-o filenames'.
|
||||
if {[lindex $BASH_VERSINFO 0] <= 3} {pass "$test"} {fail "$test"}
|
||||
}
|
||||
-re $prompt { unresolved "$test at prompt" }
|
||||
default { unresolved "$test" }
|
||||
}; # expect
|
||||
|
234
test/unit/_filedir.exp
Normal file
234
test/unit/_filedir.exp
Normal file
@ -0,0 +1,234 @@
|
||||
proc setup {} {
|
||||
assert_bash_exec {unset COMPREPLY cur}
|
||||
assert_bash_exec {unset -f _f}
|
||||
save_env
|
||||
# Declare bash completion function `_f'
|
||||
assert_bash_exec { \
|
||||
_f() { local cur=$(_get_cword); unset COMPREPLY; _filedir; }; \
|
||||
complete -F _f f \
|
||||
}
|
||||
# Declare bash completion function `_f2' with `-o filenames' active.
|
||||
assert_bash_exec { \
|
||||
complete -F _f -o filenames f2 \
|
||||
}
|
||||
# Create directory `a*b'
|
||||
# NOTE: directory `a*b' isn't included in Git, because a directory
|
||||
# containing an asterisk (*) causes troubles on Cygwin/Windows
|
||||
assert_bash_exec {(cd fixtures/_filedir && [ ! -d a\*b ] && mkdir a\*b && touch a\*b/j || true)}
|
||||
}; # setup()
|
||||
|
||||
|
||||
proc teardown {} {
|
||||
assert_bash_exec {(cd fixtures/_filedir && rm -- a\*b/j && rmdir a\*b/ || true)}
|
||||
assert_bash_exec {unset COMPREPLY cur}
|
||||
assert_bash_exec {unset -f _f}
|
||||
assert_bash_exec {complete -r f}
|
||||
assert_env_unmodified { /OLDPWD/d }
|
||||
}; # teardown()
|
||||
|
||||
|
||||
setup
|
||||
|
||||
|
||||
set test "_filedir should run without errors"
|
||||
assert_bash_exec {_filedir > /dev/null} $test
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
foreach name {f f2} {
|
||||
|
||||
set test "completing $name ab/ should return e"
|
||||
set cmd "$name ab/"
|
||||
assert_complete_dir e $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name a\\ b/ should return i"
|
||||
set cmd "$name a\\ b/"
|
||||
assert_complete_dir i $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name a\\\'b/ should return i"
|
||||
set cmd "$name a\\\'b/"
|
||||
assert_complete_dir c $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name a\\\"b/ should return i"; #"
|
||||
set cmd "$name a\\\"b/"; #"
|
||||
assert_complete_dir d $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name a\\\$b/ should return h"
|
||||
set cmd "$name a\\\$b/"
|
||||
assert_complete_dir "\b\b\b\b\b$::TESTDIR/fixtures/_filedir/a\\\\\$b/h" $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name a\\\\b/ should return g"
|
||||
set cmd "$name a\\\\b/"
|
||||
assert_complete_dir g $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name a\\&b/ should return f"
|
||||
set cmd "$name a\\&b/"
|
||||
assert_complete_dir f $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name a\$ should return a\\\$b/"
|
||||
set cmd "$name a\$"
|
||||
assert_complete_dir "\b\\\\\$b/" $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
# NOTE: Bash versions 4.0.0 up to 4.0.34 contain a bug when completing quoted
|
||||
# words, so tests within this if aren't executed for these bash versions.
|
||||
if {! (
|
||||
[lindex $::BASH_VERSINFO 0] == 4 &&
|
||||
[lindex $::BASH_VERSINFO 1] == 0 &&
|
||||
[lindex $::BASH_VERSINFO 2] < 35
|
||||
)} {
|
||||
set test "completing $name 'ab/ should return e"
|
||||
set cmd "$name 'ab/"
|
||||
assert_complete_dir {e'} $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name 'a b/ should return i"
|
||||
set cmd "$name 'a b/"
|
||||
assert_complete_dir {i'} $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name 'a\"b/ should return d"; #"
|
||||
set cmd "$name 'a\"b/"; #"
|
||||
assert_complete_dir {d'} $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name 'a\$b/ should return h"
|
||||
set cmd "$name 'a\$b/"
|
||||
if {[lindex $::BASH_VERSINFO 0] == 4} {
|
||||
assert_complete_dir {h'} $cmd "fixtures/_filedir"
|
||||
} else {
|
||||
assert_complete_dir "\b\b\b\b$::TESTDIR/fixtures/_filedir/a\$b/h'" $cmd "fixtures/_filedir"
|
||||
}; # if
|
||||
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name 'a\\b/ should return g"
|
||||
set cmd "$name 'a\\b/"
|
||||
assert_complete_dir {g'} $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name 'a&b/ should return f"
|
||||
set cmd "$name 'a&b/"
|
||||
assert_complete_dir {f'} $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"ab/ should return e"; #"
|
||||
set cmd "$name \"ab/"; #"
|
||||
assert_complete_dir {e"} $cmd "fixtures/_filedir"; #"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"a b/ should return i"; #"
|
||||
set cmd "$name \"a b/"; #"
|
||||
assert_complete_dir {i"} $cmd "fixtures/_filedir"; #"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"a'b/ should return c"; #"
|
||||
set cmd "$name \"a'b/"; #"
|
||||
assert_complete_dir {c"} $cmd "fixtures/_filedir"; #"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"a\\\"b/ should return d"; #"
|
||||
set cmd "$name \"a\\\"b/"; #"
|
||||
assert_complete_dir {d"} $cmd "fixtures/_filedir"; #"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"a\\\$b/ should return h"; #"
|
||||
set cmd "$name \"a\\\$b/"; #"
|
||||
assert_complete_dir "\b\b\b\b\b$::TESTDIR/fixtures/_filedir/a\\\\\$b/h\\\"" $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"a\\b/ should return e"; #"
|
||||
set cmd "$name \"a\\b/"; #"
|
||||
assert_complete_dir "\b\b\bb/e\\\"" $cmd "fixtures/_filedir"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"a\\\\b/ should return g"; #"
|
||||
set cmd "$name \"a\\\\b/"; #"
|
||||
assert_complete_dir {g"} $cmd "fixtures/_filedir"; #"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test "completing $name \"a&b/ should return f"; #"
|
||||
set cmd "$name \"a&b/"; #"
|
||||
assert_complete_dir {f"} $cmd "fixtures/_filedir"; #"
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
}; # if
|
||||
}; # for
|
||||
|
||||
|
||||
teardown
|
@ -253,4 +253,32 @@ expect {
|
||||
sync_after_int
|
||||
|
||||
|
||||
set test {a 'b&c| should return 'b&c}; # | = cursor position
|
||||
if {
|
||||
[lindex $::BASH_VERSINFO 0] == 4 &&
|
||||
[lindex $::BASH_VERSINFO 1] == 0 &&
|
||||
[lindex $::BASH_VERSINFO 2] < 35
|
||||
} {
|
||||
set cmd {COMP_WORDS=(a "'" b "&" c); COMP_CWORD=4}
|
||||
} else {
|
||||
set cmd {COMP_WORDS=(a "'b&c"); COMP_CWORD=1}
|
||||
}; # if
|
||||
append cmd {; COMP_LINE="a 'b&c"; COMP_POINT=6; _get_cword}
|
||||
send "$cmd\r"
|
||||
expect -ex "$cmd\r\n"
|
||||
expect {
|
||||
-ex "'b&c/@" { pass "$test" }
|
||||
-ex "c/@" {
|
||||
if {
|
||||
[lindex $::BASH_VERSINFO 0] == 4 &&
|
||||
[lindex $::BASH_VERSINFO 1] == 0 &&
|
||||
[lindex $::BASH_VERSINFO 2] < 35
|
||||
} {xfail "$test"} {fail "$test"}
|
||||
}
|
||||
}; # expect
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
teardown
|
||||
|
52
test/unit/compgen.exp
Normal file
52
test/unit/compgen.exp
Normal file
@ -0,0 +1,52 @@
|
||||
proc setup {} {
|
||||
save_env
|
||||
}; # setup()
|
||||
|
||||
|
||||
proc teardown {} {
|
||||
assert_env_unmodified {/OLDPWD/d}
|
||||
}; # teardown()
|
||||
|
||||
|
||||
setup
|
||||
|
||||
|
||||
if {[lindex $::BASH_VERSINFO 0] <= 3} {
|
||||
set test {compgen -f a\\\\\\\'b/ on bash-3 should return a\'b/c};
|
||||
set cmd {compgen -f a\\\\\\\'b/}
|
||||
} else {
|
||||
set test {compgen -f a\\\'b/ on bash-4 should return a\'b/c};
|
||||
set cmd {compgen -f a\\\'b/}
|
||||
}; # if
|
||||
set dir fixtures/compgen
|
||||
set prompt "/$dir/@"
|
||||
assert_bash_exec "cd $dir" "" $prompt
|
||||
send "$cmd\r"
|
||||
expect -ex "$cmd\r\n"
|
||||
expect {
|
||||
-re {a\\\'b/c} {
|
||||
# On bash-3.2, compgen returns inconsequent output
|
||||
if {
|
||||
[lindex $::BASH_VERSINFO 0] >= 4 || (
|
||||
[lindex $::BASH_VERSINFO 0] == 3 &&
|
||||
[lindex $::BASH_VERSINFO 1] == 2
|
||||
)
|
||||
} {pass $test} else {fail $test}
|
||||
}
|
||||
-re {a'b/c} {
|
||||
if {[lindex $::BASH_VERSINFO 0] <= 3 } \
|
||||
{pass $test} else {fail $test}
|
||||
}
|
||||
-re $prompt { pass "$test" }
|
||||
-re eof { unresolved "eof" }
|
||||
}; # expect
|
||||
sync_after_int $prompt
|
||||
assert_bash_exec "cd \$TESTDIR"
|
||||
|
||||
#assert_bash_list_dir {a\\\'b/c} $cmd fixtures/compgen
|
||||
|
||||
|
||||
sync_after_int
|
||||
|
||||
|
||||
teardown
|
Loading…
x
Reference in New Issue
Block a user