6

我有以下目录结构:

/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/$@
}

有什么想法有什么问题吗?在我看来,完成过程似乎已经完成,并且不再期待任何输入。

4

4 回答 4

9

到目前为止,我发现的最简单的解决方案是生成如下所示的完成:

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>
于 2012-08-29T19:51:57.860 回答
5

如果我理解正确,您想要 bash-autocomplete 目录名称,并且没有多余的空间?(这就是我在访问此页面时正在寻找的内容)。

如果是这样,当您注册完成功能时,请使用“-o nospace”。

complete -o nospace -F _cdw cdw

我不知道 nospace 是否适用于 compgen。

于 2012-03-16T20:22:29.483 回答
2

像这样的东西怎么样:

COMPREPLY=( $(cdw; compgen -W "$(for d in ${cur}* ${cur}*/*; do [[ -d "$d" ]] && echo $d/; done)" -- ${cur}) )

(我不确定你是否可以从这里调用你的 shell 函数,否则你可能需要复制一下。)

这也摆脱了你的 perl hack :-)

于 2011-12-14T21:55:07.200 回答
1

完成为此提供了一个解决方案,无需任何解决方法:在 /etc/bash_completion 中定义的函数 _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
}
于 2013-05-09T14:23:26.850 回答