如何完成相对于另一个目录的文件名?

Håk*_*and 5 bash autocomplete

这是以下讨论的后续问题:

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/da/前缀不应该在那里.它应该是b/ c/ d.

ani*_*ane 6

我会把这个函数写成:

_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个部分,

  1. $cur用你的基目录前缀- 〜/ tmp.
  2. 使用_filedir用于cd/ls等的标准bash完成例程.
  3. ~/tmp从中移除COMPREPLY

仅供记录:您可以使用此逻辑来完成相对于许多其他类型路径的文件名,例如

  1. 我用它来完成perforce路径//....
  2. 您还可以完成http://localhost/*相对于public_html目录的路径.