Это не идеально, но с другой стороны, завершение bash довольно сложно ...
Самый простой способ для каждой команды, он немного более гибкий, чем FIGNORE
вы можете сделать:
complete -f -X "/myproject/data/*" vi
Это инструктирует автозаполнение, что завершение для vi
файлов, и удаляет шаблоны, соответствующие -X
фильтру. Недостатком является то, что шаблон не нормализован, поэтому ../data
и варианты не будут совпадать.
Следующая лучшая вещь может быть пользовательской PROMPT_COMMAND
функцией:
# associative arrays of non-autocomplete directories
declare -A noacdirs=([/myproject/data]=1 )
function _myprompt {
[[ -n "${noacdirs[$PWD]}" ]] && {
echo autocomplete off
bind 'set disable-completion on'
} || {
echo autocomplete on
bind 'set disable-completion off'
}
}
PROMPT_COMMAND=_myprompt
Это отключает завершение (полностью), когда вы находитесь в каталоге, но отключает его для каждого пути, а не только для файлов в этом каталоге.
В более общем случае было бы полезно выборочно отключить это для определенных путей, но я считаю, что единственный способ - использовать функцию завершения по умолчанию (bash-4.1 и более поздние версии complete -D
) и много возиться.
Это должно работать для вас, но может иметь непредвиденные побочные эффекты (то есть изменения в ожидаемом завершении в некоторых случаях):
declare -A noacdirs=([/myproject/data]=1 )
_xcomplete() {
local cur=${COMP_WORDS[COMP_CWORD]} # the current token
name=$(readlink -f "${cur:-./}") # poor man's path canonify
dirname=$(dirname "$name/.")
[[ -n "${noacdirs[$dirname]}" ]] && {
COMPREPLY=( "" ) # dummy to prevent completion
return
}
# let default kick in
COMPREPLY=()
}
complete -o bashdefault -o default -F _xcomplete vi
Это работает для завершения vi
, другие команды могут быть добавлены по мере необходимости. Это должно остановить завершение для файлов в названных каталогах независимо от пути или рабочего каталога.
Я считаю, что общий подход complete -D
заключается в динамическом добавлении функций завершения для каждой команды, когда она встречается. Можно также добавить complete -E
(завершение имени команды, когда входной буфер пуст).
Обновление
Вот гибридная версия решения PROMPT_COMMAND
и функции завершения, немного легче понять и взломать, я думаю:
declare -A noacdirs=([/myproject/data]=1 [/project2/bigdata]=1)
_xcomplete() {
local cmd=${COMP_WORDS[0]}
local cur=${COMP_WORDS[COMP_CWORD]} # the current token
[[ -z "$cur" && -n "$nocomplete" ]] && {
printf "\n(restricted completion for $cmd in $nocomplete)\n"
printf "$PS2 $COMP_LINE"
COMPREPLY=( "" ) # dummy to prevent completion
return
}
COMPREPLY=() # let default kick in
}
function _myprompt {
nocomplete=
# uncomment next line for hard-coded list of directories
[[ -n "${noacdirs[$PWD]}" ]] && nocomplete=$PWD
# uncomment next line for per-directory ".noautocomplete"
# [[ -f ./.noautocomplete ]] && nocomplete=$PWD
# uncomment next line for size-based guessing of large directories
# [[ $(stat -c %s .) -gt 512*1024 ]] && nocomplete=$PWD
}
PROMPT_COMMAND=_myprompt
complete -o bashdefault -o default -F _xcomplete vi cp scp diff
Эта функция подсказки устанавливает nocomplete
переменную при вводе одного из настроенных каталогов. Измененное поведение завершения включается только тогда, когда эта переменная непустая, и только когда вы пытаетесь завершить из пустой строки, что позволяет завершить частичные имена (удалите -z "$cur"
условие, чтобы предотвратить полное завершение). Закомментируйте две printf
строки для тихой работы.
Другие варианты включают .noautocomplete
файл флага для каждого каталога, который вы можете touch
в каталоге по мере необходимости; и угадывание размера каталога с использованием GNU stat
. Вы можете использовать любой или все эти три варианта.
( stat
Метод является лишь предположением , размер каталога, о котором сообщается, увеличивается с его содержимым, это «верхний предел», который обычно не уменьшается при удалении файлов без какого-либо административного вмешательства. Это дешевле, чем определение реального содержимого потенциально большого размера каталог. Точное поведение и приращение в расчете на файл зависят от базовой файловой системы. Я считаю это надежным показателем, по крайней мере, в системах linux ext2 / 3/4.)
bash добавляет дополнительный пробел, даже когда возвращается пустое завершение (это происходит только при завершении в конце строки). Вы можете добавить -o nospace
в complete
команду, чтобы предотвратить это.
Остается один недостаток: если вы вернете курсор к началу токена и нажмете на вкладку, то по умолчанию будет снова выполнено завершение. Считайте, что это особенность ;-)
(Или вы можете возиться с этим, ${COMP_LINE:$COMP_POINT-1:1}
если вам нравится чрезмерное проектирование, но я обнаружил, что сам bash не может установить переменные завершения надежно, когда вы выполняете резервное копирование и пытаетесь выполнить завершение в середине команды.)