我正在尝试为我的命令创建一个 bash 完成脚本。ls
有我想要的行为。我需要从我的命令中得到同样的行为。
这就是我得到的ls
$ ls /home/tux/<Tab><Tab>
Downloads Documents Pictures
$ ls /home/tux/Do<Tab><Tab>
Downloads Documents
即 bash 仅显示相对的下一个路径,而不是绝对的(即它确实添加Downloads
到完成列表中,但不是/home/tux/Downloads
)
我想编写一个以相同方式工作的完成脚本。这是我尝试过的。
_testcommand ()
{
local IFS=$'\n'
local cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -o bashdefault -d -- "$cur") )
if [ "${#COMPREPLY[@]}" -ne 1 ]
then
# remove prefix "$cur", so the preview of paths gets shorter
local cur_len=$(echo $cur | sed 's|/[^/]*$||' | wc -c)
for i in ${!COMPREPLY[@]}
do
COMPREPLY[$i]="${COMPREPLY[i]:$cur_len}"
done
fi
return 0
}
complete -o nospace -F _testcommand testcommand
然而结果是这样的:
$ testcommand /home/tux/<Tab><Tab>
Downloads Documents Pictures
$ testcommand /home/tux/Do<Tab>
Downloads Documents
$ testcommand Do
我怎样才能完成我的工作不是/home/tux/
从命令行中删除?
注意:我想我不能在complete
底部的调用中添加“-f”或“-d”等。实际上,在某些情况下,完成还必须完成单词而不是路径。
答案1
您可以通过“ls”检查使用哪个补全函数:complete -p | grep ls
。您可以使用以下命令检查该函数:(type _longopt
上一个命令的结果)。在_longopt
函数中你可以找到该_filedir
函数。
最后是一篇关于完成的有趣文章:https://spin.atomicobject.com/2016/02/14/bash-programmable-completion/
答案2
bash 完成目录 ( pkg-config --variable=completionsdir bash-completion
) 中的大多数程序都使用_filedir
bash-completion 本身提供的功能。重用似乎是合法的_filedir
- 无需担心您自己的实现!
微量元素:
_testcommand()
{
# init bash-completion's stuff
_init_completion || return
# fill COMPREPLY using bash-completion's routine
# in this case, accept only MarkDown and C files
_filedir '@(md|c)'
}
complete -F _testcommand testcommand
当然,您仍然可以在完成非文件时使用它:
if ...
then
# any custom extensions, e.g. words, numbers etc
COMPREPLY=( $(compgen ...) )
else
# fill COMPREPLY using bash-completion's routine
_filedir '@(md|c)'
fi
我是怎么找到它的?
谢谢@csm:使用他们的答案,检查type _longopt
,哪个调用_filedir
。