Можно ли использовать автозаполнение bash со встроенной командой «источник»?

#bash

Вопрос:

У меня есть проект, в котором я регулярно меняю разные версии библиотеки. У меня есть сценарий set_lib , который принимает версию библиотеки в качестве входных данных, а затем устанавливает соответствующие переменные среды. Иногда мне хочется создать этот сценарий и создавать/запускать его вручную. Я знаю, как настроить автозаполнение для функций/сценариев, но как насчет сценариев поиска? То есть

 >source set_lib v<tab><tab>
ver1 ver2 ver3
 

Кроме того, я хотел бы, чтобы автозаполнение работало как обычно, source когда оно не связано с set_lib .

ИЗМЕНИТЬ: Как и предлагалось, я попробовал следующее

 _comp_set_lib() {
    if [ ${COMP_WORDS[1]} == 'set_lib' ]; then
        COMPREPLY=( "set_lib ver1" "set_lib ver2" )
    fi
}
complete -o bashdefault -F _comp_set_lib source
 

$COMP_CWORD быть вторым-это создает мне проблемы. Вышесказанное работает не так, как ожидалось, и дает мне

 >source set_lib <tab>
source set_lib ver
 

Комментарии:

1. Какие проблемы вызывает у вас COMP_CWORD 2? Чего именно ты хочешь?

Ответ №1:

Я думаю, что наиболее удобный подход-определить функцию, которая обертывает source set_lib ... :

 function set_lib() {
  source set_lib "$@"
}
 

а затем настройте автозаполнение для этой функции.

Но если вы предпочитаете вводить source set_lib и не просто set_lib , то вы можете прикрепить функцию автоматического заполнения к source встроенному элементу и проверить, равен ли "${COMP_WORDS[1]}" (имеется в виду первый аргумент source ) set_lib , прежде чем решить, возвращать ли какие-либо пользовательские соответствия. (При использовании complete встроенного модуля для настройки автозаполнения используйте -o bashdefault флаг, чтобы сообщить ему, что если ваша функция не возвращает никаких совпадений, то вы хотите, чтобы Bash вернулся к своей логике по умолчанию для предложений.)

Комментарии:

1. Для маршрута поиска у меня возникли проблемы с индексом аргументов. Я бы хотел увеличить $COMP_CWORD, но я считаю, что он предназначен только для чтения. Просто установка COMPREPLY=( «set_lib ver1» «set_lib ver2» ) не сработала так, как я ожидал.

2. @roro: Я не совсем понимаю, чего вы ожидали, извините. Я бы обновил свой ответ, чтобы привести конкретный пример, но в основном это будет то, что опубликовал pynexj, поэтому я рекомендую просто попробовать его/ее ответ.

Ответ №2:

Обычно вам нужно вызвать compgen спецификацию пользовательского завершения. См. Следующий пример:

 _comp_set_lib()
{
    local cur=$2
    local versions=(v1 ver2 version3)

    if [[ ${COMP_WORDS[1]} == set_lib ]]; then
        COMPREPLY=( $( compgen -W "${versions[*]}" -- "$cur" ) )
        return
    fi
}
complete -o default -o bashdefault -F _comp_set_lib source