How to complete filenames relative to another directory?

◇◆丶佛笑我妖孽 提交于 2020-02-02 03:49:21

问题


This is a follow-up question to the discussion in:

https://bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1394920

Suppose I have a folder ~/tmp with some files and directories:

$ mkdir a; touch file1.txt; mkdir a/b; mkdir a/c; touch a/d; mkdir a/b/c

I now try to make a completion script to complete filenames in ~/tmp, but the complete -o filenames option is only working correctly if the current directory is ~/tmp.

See the above link for more background information. This is as far as I got:

$ 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

Then I source it:

$ . setup

and I can then do

$ aaa <tab><tab>
  • Problem 1 : Slashes are not added at the end of directory names in the completion list ( this is desired to easy separate directories from file names in the completion list)

  • Problem 2 : For aaa a/<tab><tab> the completion list is a/b a/c a/d but the a/ prefix should not be there. It should be b/ c/ d instead.


回答1:


I would write this function as:

_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

It has 3 parts,

  1. prefixing the $cur with your base directory - ~/tmp.
  2. Using standard bash completion routine _filedir used for cd/ls etc.
  3. Removing ~/tmp from COMPREPLY

Just for the record: You can use this logic to complete the file names relative to many other types of path, e.g.

  1. I use it to complete perforce paths //....
  2. You can also complete http://localhost/* paths, relative to your public_html directory.


来源:https://stackoverflow.com/questions/27244300/how-to-complete-filenames-relative-to-another-directory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!