Spec-Zone.ru › Bash

Пример программируемой автодополнения

Наиболее распространённый способ получения дополнительных функций автодополнения помимо стандартных действий 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API