писание специальных переменных для работы с автодополнением. Переменная | Назначение ------------- | ------------- 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 ```