Пример программируемой автодополнения
Наиболее распространённый способ получения дополнительных функций автодополнения помимо стандартных действий complete и compgen – использование функции оболочки и её привязка к конкретной команде с помощью complete -F.
Следующая функция обеспечивает автодополнение для встроенной команды cd. Это достаточно хороший пример того, что должны делать функции оболочки, используемые для автодополнения. Эта функция использует слово, переданное как $2, для определения имени каталога, который необходимо дополнить. Также можно использовать переменную массива COMP_WORDS; текущее слово индексируется переменной COMP_CWORD.
Функция полагается на встроенные команды complete и compgen для выполнения большей части работы, добавляя только то, что оболочка Bash cd делает сверх принятия основных имён каталогов: расширение тильды (см. Расширение тильды), поиск каталогов в $CDPATH, что описано выше (см. Встроенные команды Bourne Shell), и базовая поддержка параметра оболочки cdable_vars (см. Встроенная команда Shopt). _comp_cd изменяет значение IFS так, что оно содержит только символ новой строки, чтобы учитывать имена файлов, содержащие пробелы и табуляции – compgen выводит возможные дополнения, по одному на строку.
Возможные дополнения добавляются в переменную массива COMPREPLY, по одному дополнению на элемент массива. Система программируемого автодополнения извлекает дополнения из неё, когда функция возвращает значение.
# A completion function for the cd builtin
# based on the cd completion function from the bash_completion package
_comp_cd()
{
local IFS=$' \t\n' # normalize IFS
local cur _skipdot _cdpath
local i j k
# Tilde expansion, which also expands tilde to full pathname
case "$2" in
\~*) eval cur="$2" ;;
*) cur=$2 ;;
esac
# no cdpath or absolute pathname -- straight directory completion
if [[ -z "${CDPATH:-}" ]] || [[ "$cur" == @(./*|../*|/*) ]]; then
# compgen prints paths one per line; could also use while loop
IFS=$'\n'
COMPREPLY=( $(compgen -d -- "$cur") )
IFS=$' \t\n'
# CDPATH+directories in the current directory if not in CDPATH
else
IFS=$'\n'
_skipdot=false
# preprocess CDPATH to convert null directory names to .
_cdpath=${CDPATH/#:/.:}
_cdpath=${_cdpath//::/:.:}
_cdpath=${_cdpath/%:/:.}
for i in ${_cdpath//:/$'\n'}; do
if [[ $i -ef . ]]; then _skipdot=true; fi
k="${#COMPREPLY[@]}"
for j in $( compgen -d -- "$i/$cur" ); do
COMPREPLY[k++]=${j#$i/} # cut off directory
done
done
$_skipdot || COMPREPLY+=( $(compgen -d -- "$cur") )
IFS=$' \t\n'
fi
# variable names if appropriate shell option set and no completions
if shopt -q cdable_vars && [[ ${#COMPREPLY[@]} -eq 0 ]]; then
COMPREPLY=( $(compgen -v -- "$cur") )
fi
return 0
}
Мы устанавливаем функцию автодополнения, используя параметр -F для complete:
# Tell readline to quote appropriate and append slashes to directories; # use the bash default completion for other arguments complete -o filenames -o nospace -o bashdefault -F _comp_cd cd
Поскольку мы хотим, чтобы Bash и Readline позаботились о некоторых других деталях за нас, мы используем несколько других параметров, чтобы сказать Bash и Readline, что делать. Параметр -o filenames сообщает Readline, что возможные дополнения должны обрабатываться как имена файлов и должным образом обрамляться кавычками. Этот параметр также заставит Readline добавлять косые черты к именам файлов, которые могут быть каталогами (поэтому мы можем захотеть расширить _comp_cd для добавления косой черты, если мы используем каталоги, найденные через CDPATH: Readline не может определить, что эти дополнения являются каталогами). Параметр -o nospace сообщает Readline не добавлять пробел к имени каталога, в случае если мы хотим к нему что-то добавить. Параметр -o bashdefault подключает остальную часть "по умолчанию Bash" автодополнений – возможные дополнения, которые Bash добавляет к набору по умолчанию Readline. Это включает такие вещи, как автодополнение имени команды, автодополнение переменных для слов, начинающихся с ‘$’ или ‘${’, дополнения, содержащие шаблоны расширения пути (см. Расширение имён файлов), и так далее.
После установки с помощью complete, _comp_cd будет вызываться каждый раз, когда мы пытаемся выполнить автодополнение слова для команды cd.
Множество других примеров – обширная коллекция автодополнений для большинства распространённых команд GNU, Unix и Linux – доступна как часть проекта bash_completion. Он устанавливается по умолчанию во многих дистрибутивах GNU/Linux. Изначально написанный Ианом Макдональдом, проект теперь находится по адресу https://github.com/scop/bash-completion/. Есть порты для других систем, таких как Solaris и Mac OS X.
Более старая версия пакета bash_completion распространяется с bash в подкаталоге examples/complete.
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/bash/manual/html_node/A-Programmable-Completion-Example.html