我有以下目录结构:
/home/tichy/xxx/yyy/aaa
/home/tichy/xxx/yyy/aab
/home/tichy/xxx/yyy/aac
我想输入 cdw y< TAB> 并获取 cdw yyy /< CURSOR> ,因此我可以添加 cdw yyy / a< TAB> 并获取 cdw yyy / aa< CURSOR>
我想出的解决方案给了我以下内容:
cdw y< TAB> => cdw yyy< SPACE>< CURSOR>
以下代码我到目前为止:
_cdw () {
local cur prev dirs
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
COMPREPLY=($(compgen -d -- /home/tichy/xxx/${cur}|perl -pe 's{^/home/tichy/xxx/}{}'))
# no difference, a bit more logical:
dirs=$(compgen -o nospace -d /home/tichy/xxx/${cur}|perl -pe 's/{^/home/tichy/xxx/}{}')
COMPREPLY=($(compgen -d -W ${dir} ${cur}|perl -pe 's{^/home/tichy/xxx/}{}'))
return 0
}
complete -F _cdw cdw
cdw () {
cd /home/tichy/xxx/$@
}
任何想法有什么不对?在我看来,完成过程似乎已经完成,并且不期待任何更多的输入。
答案 0 :(得分:7)
到目前为止,我发现的最简单的解决方案是生成如下所示的完成:
COMPREPLY=$( compgen -W "file1 file2 file3 dir1/ dir2/ dir3/" )
并在返回
之前添加此行[[ $COMPREPLY = */ ]] && compopt -o nospace
每当完成可以填写直到斜杠时设置nospace选项,以便用户最终得到:
cmd dir1/<cursorhere>
而不是:
cmd dir1/ <cursorhere>
并且只要完成可以填写直到完整文件名以便用户最终得到:
,它就不会设置nospace选项cmd file1 <cursorhere>
而不是:
cmd file1<cursorhere>
答案 1 :(得分:5)
如果我理解正确,你想要bash-autocomplete一个目录名,而不是有额外的空间? (当我到达这个页面时,这就是我想要的)。
如果是这样,当您注册完成功能时,请使用“-o nospace”。
complete -o nospace -F _cdw cdw
我不知道nospace是否适用于compgen。
答案 2 :(得分:2)
这样的事情怎么样:
COMPREPLY=( $(cdw; compgen -W "$(for d in ${cur}* ${cur}*/*; do [[ -d "$d" ]] && echo $d/; done)" -- ${cur}) )
(我不确定你是否可以从这里调用你的shell函数,否则你可能需要复制一下。)
这也消除了你的perl hack: - )
答案 3 :(得分:0)
完成为此提供了一个解决方案,没有任何解决方法:在/ etc / bash_completion中定义了funciton _filedir:
626 # This function performs file and directory completion. It's better than
627 # simply using 'compgen -f', because it honours spaces in filenames.
628 # @param $1 If `-d', complete only on directories. Otherwise filter/pick only
629 # completions with `.$1' and the uppercase version of it as file
630 # extension.
631 #
632 _filedir()
然后,指定以下内容就足够了:
_cdw () {
local cur prev dirs
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
_filedir # add -d at the end to complete only dirs, no files
return 0
}