这是以下讨论的后续问题:
https://bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1394920
假设我有一个~/tmp包含一些文件和目录的文件夹:
$ mkdir a; touch file1.txt; mkdir a/b; mkdir a/c; touch a/d; mkdir a/b/c
Run Code Online (Sandbox Code Playgroud)
我现在尝试制作一个完成脚本来完成文件名~/tmp,但该complete -o filenames选项只有在当前目录下才能正常工作~/tmp.
有关更多背景信息,请参阅上面的链接.这是我得到的:
$ cat setup
_compTest() {
local cur baseFolder
cur="${COMP_WORDS[$COMP_CWORD]}"
baseFolder=~/tmp
compopt -o nospace
COMPREPLY=( $(
cd "$baseFolder"
if [[ ${cur: -1} != "/" && -d $cur ]] ; then
echo "$cur/"
else
compgen -f "$cur"
fi
) )
}
complete -F _compTest aaa
Run Code Online (Sandbox Code Playgroud)
然后我来源:
$ . setup
Run Code Online (Sandbox Code Playgroud)
然后我就可以了
$ aaa <tab><tab>
Run Code Online (Sandbox Code Playgroud)
问题1:完成列表中的目录名称末尾没有添加斜杠(这需要在完成列表中轻松地将目录与文件名分开)
问题2:对于aaa a/<tab><tab>完成列表,a/b a/c a/d但a/前缀不应该在那里.它应该是b/ c/ d.
我会把这个函数写成:
_compTest ()
{
local cur; local tmp; local tmp_escaped; local i;
_get_comp_words_by_ref cur;
local _compreply=()
tmp=~/tmp/
tmp_escaped=${tmp//\//\\\/}
cur=$tmp$cur;
if [ "$1" == "-d" ]; then
_cd
else
_filedir;
fi;
for i in "${COMPREPLY[@]}"; do
[ -d "$i" ] && [ "$i" != "$tmp." ] && [ "$i" != "$tmp.." ] && i="$i/"
_compreply=("${_compreply[@]}" "$i")
done
COMPREPLY=(${_compreply[@]/$tmp_escaped/})
} && complete -o nospace -F _compTest aaa_files
_compTestDir()
{
_compTest -d
} && complete -o nospace -F _compTestDir aaa_directories
Run Code Online (Sandbox Code Playgroud)
它有3个部分,
$cur用你的基目录前缀- 〜/ tmp._filedir用于cd/ls等的标准bash完成例程.~/tmp从中移除COMPREPLY仅供记录:您可以使用此逻辑来完成相对于许多其他类型路径的文件名,例如
//.... http://localhost/*相对于public_html目录的路径.