Я пытаюсь настроить завершение каталогов в tcsh и / или bash (оба используются на моем сайте) с небольшим поворотом: для конкретной команды "foo" я хотел бы, чтобы завершение использовало пользовательскую функцию сопоставить первый / -ограниченный термин с фактическим узлом поддерева, а затем следовать обычному завершению каталога для любых последующих терминов. Это своего рода комбинация cdpath и завершения, или я предполагаю форму завершения каталога, где начальная точка контролируется сценарием завершения. Это будет работать следующим образом:
$ foo xxx<TAB>
(custom completion function produces choices it finds at arbitrary levels in the dir tree)
xxxYYY xxxZZZ xxxBLAH ...
foo xxxYYY/<TAB>
(normal directory completion proceeds from this point on, to produce something like:)
foo scene/shot/element/workspace/user/...
Мы хотели бы сделать это, потому что у нас есть большое дерево разработки производства (это производственная база CGI), в котором находчивые в оболочке пользователи постоянно перемещаются и прыгают. Жалоба на то, что верхние уровни дерева громоздки и избыточны; им просто нужен быстрый поиск по первому члену, чтобы найти возможные варианты "заголовка" и выполнить оттуда завершение каталога. Кажется, что программируемое завершение может предложить способ сделать это, но оно оказывается довольно неуловимым.
Я сделал несколько попыток пользовательского завершения bash и tcsh, чтобы сделать это, но ближе всего я получил форму «завершения слова», где пользователь должен обрабатывать уровни каталога как отдельные слова с пробелами (например, foo сцена / выстрел / элемент / рабочее пространство / ...). Я мог бы продолжать взламывать мои текущие сценарии - но мне было интересно, есть ли что-то, чего я не понимаю - это моя первая попытка завершить программирование, а документы и примеры довольно тонкие в книгах по оболочкам и в Интернете , Если есть какой-нибудь гуру-завершитель, который поможет мне выбрать верный путь, я буду признателен.
FWIW: вот что у меня есть (сначала в tcsh, затем в bash). Обратите внимание, что статический корень '/ root / sub1 / sub2 / sub3' является просто заполнителем для функции поиска, которая будет находить разные совпадения на разных уровнях. Если я смогу заставить это работать, я могу добавить в функцию поиска позже. Опять же, оба примера выполняют завершение слов, что требует от пользователя вводить пробел после каждого соответствующего термина (я также должен удалить пробелы в функции, чтобы создать фактический путь, чёрт!)
TCSH EXAMPLE (обратите внимание, что функция на самом деле является скриптом bash):
complete complete_p2 'C@*@`./complete.p2.list.bash $:1 $:2 $:3 $:4 $:5 $:6 $:7 $:8 $:9`@@'
#!/bin/bash --norc
# complete.p2.list.bash - Completion prototype "p2" for shotc command
# Remove spaces from input arguments
ppath=`echo $@ | sed -e 's/ //g'`
# Print basenames (with trailing slashes) of matching dirs for completion
ls -1 -d /root/sub1/sub2/sub3/$ppath* 2>/dev/null | sed -e 's#^.*/##' | awk '{print $1 "/"}'
ПРИМЕР BASH:
_foo()
{
local cur prev opts flist
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
# Get all command words so far (omit command [0] element itself), remove spaces
terms=`echo ${COMP_WORDS[@]:1} | sed -e 's/ //g'`
# Get basenames (with trailing slashes) of matching dirs for completion
flist=`ls -1 -d /root/sub1/sub2/sub3/${terms}* 2>/dev/null | sed -e 's#^.*/##' | awk '{print $1 "/"}' | xargs echo`
COMPREPLY=( $(compgen -W "${flist}" ${cur}) )
return 0
}
complete -F _foo foo