пользовательское завершение каталога добавляет пробел - PullRequest
5 голосов
/ 14 декабря 2011

У меня следующая структура каталогов:

/home/tichy/xxx/yyy/aaa
/home/tichy/xxx/yyy/aab
/home/tichy/xxx/yyy/aac

Я хотел бы ввести cdw y и получить в результате cdw ггг / , чтобы я мог добавить cdw ггг / a и получите cdw гггг / аа

Решение, которое я нашел, дает мне следующее:
cdw y => cdw yyy

следующий код, который у меня есть:

_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 ]

7 голосов
/ 29 августа 2012

Самое простое решение, которое я нашел до сих пор, - это генерировать дополнения, которые выглядят так:

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>
5 голосов
/ 17 марта 2012

Если я правильно понимаю, вы хотите bash-autocomplete имя каталога, а не лишний пробел? (Это то, что я искал, когда попал на эту страницу).

Если это так, когда вы регистрируете функцию завершения, используйте «-o nospace».

complete -o nospace -F _cdw cdw

Я не знаю, работает ли nospace на compgen.

2 голосов
/ 15 декабря 2011

Примерно так:

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

(я не уверен, что вы можете вызывать здесь функцию оболочки или нет, в противном случае вам, возможно, придется немного ее дублировать).

Это также избавляет от вашего хака Perl: -)

0 голосов
/ 09 мая 2013

завершение предоставляет решение для этого без какого-либо обходного пути: funciton _filedir, определенный в / etc / bash_completion:

 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...