писание специальных переменных для работы с автодополнением.
Переменная | Назначение
------------- | -------------
COMP_CWORD | Указатель в ${COMP_WORDS} для слова, в котором хранится текущая позиция курсора.
COMP_LINE | Текущая командная строка.
COMP_POINT | Указатель текущего положения курсора относительно начала текущей команды. Если текущая позиция курсора находится в конце текущей команды, значение этой переменной равно $ {# COMP_LINE}.
COMP_WORDBREAKS | Устанавливает символы, которые библиотека readline рассматривает в качестве разделителей слов при выполнении завершения слова. Если переменная $COMP_WORDBREAKS удаляется с помощью встроенной командой unset, она теряет свои специальные свойства, даже если в дальнейшем переустанавливается.
COMP_WORDS | Переменная - массив, состоящая из отдельных слов, используемых в текущей командной строке, ${COMP_LINE}.
COMPREPLY | Переменная - массив, из которого Bash считывает возможные варианты завершения строки, сгенерированные функцией командной оболочки, вызванной сервисом, предназначенным для программирования завершений
```shell
# file: UseGetOpt-2
# UseGetOpt-2.sh parameter-completion
_UseGetOpt-2 () # By convention, the function name
{ #+ starts with an underscore.
local cur
# Pointer to current completion word.
# By convention, it's named "cur" but this isn't strictly necessary.
COMPREPLY=() # Array variable storing the possible completions.
cur=${COMP_WORDS[COMP_CWORD]}
case "$cur" in
-*)
COMPREPLY=( $( compgen -W '-a -d -f -l -t -h --aoption --debug \
--file --log --test --help --' -- $cur ) );;
# Generate the completion matches and load them into $COMPREPLY array.
# xx) May add more cases here.
# yy)
# zz)
esac
return 0
}
complete -F _UseGetOpt-2 -o filenames ./UseGetOpt-2.sh
#
```
Как использовать:
```shell
bash$ source UseGetOpt-2
bash$ ./UseGetOpt-2.sh -[Tab]
-- --aoption --debug --file --help --log --test
-a -d -f -h -l -t
bash$ ./UseGetOpt-2.sh --[Tab]
-- --aoption --debug --file --help --log --test
```
Тут мы заполняем список возвращаемых вариантов с помощью встроенной утилиты bash compgen.
```shell
COMPREPLY=( $(compgen -W "${subcommands_1}" -- ${cur}) ) #some magic
```
Данная утилита принимает на вход список всех возможных значений аргумента, а так же текущую введенную часть аргумента, и выбирает те значения, до которых введенную часть можно дополнить. Введенная часть аргумента передается после --, а со списком возможных значений всё интереснее. В приведенном случае, возможные значения берутся (как указывает флаг -W) и данного скрипту списка слов (т.е. в приведенном выше примере — из subcommands_1=«work history help»). Однако там можно указывать и другие флаги — например -d — и тогда compgen будет дополнять исходя из существующих на машине директорий, или -f — тогда он будет дополнять до файлов.
например:
```shell
$ compgen -W "qwerty qweasd asdfgh" -- qwe
qwerty
qweasd
```
Соответственно можно генерировать различные списки кандидатов на автодополнение. Например, для решаемой задачи, нам (для импорта и экспорта истории) нужен список возможных проектов. В моём случае, каждому проекту соответствует директория в "${HOME}/projects", соответственно кандидатов можно подбирать как
```shell
COMPREPLY=($(compgen -W "`ls ${HOME}/projects`" -- ${cur}))
```
Таким образом, автодополнение работает просто: смотрим на аргументы, введённые до текущего, и исходя из соображений синтаксиса вызова нужной команды генерируем список возможных значений текущего аргумента. После чего список претендентов фильтруется по уже введенной части аргумента, и передается башу. Если претендент один, то баш его и подставляет. Всё просто.
```shell
-a means Names of alias
-b means Names of shell builtins
-c means Names of all commands
-d means Names of directory
-e means Names of exported shell variables
-f means Names of file and functions
-g means Names of groups
-j means Names of job
-k means Names of Shell reserved words
-s means Names of service
-u means Names of userAlias names
-v means Names of shell variables
```