Как заставить bash завершить работу с частично заданным аргументом и предоставить больше подсказок?

Как заставить bash завершить работу с частично заданным аргументом и предоставить больше подсказок?

Представьте, что у меня есть команда «command», которая принимает аргументы foo:bar foo:foo bar:bar или bar:foo. Я могу написать скрипт завершения командной строки, который я могу передать в свою среду для получения завершения, которое выглядит следующим образом:

function _command_opt()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="foo:bar foo:foo bar:bar bar:foo"
    if [[ ${prev: -7} == 'command' ]]
    then
        COMPREPLY=( $(compgen -W "${opts}"  -- ${cur}) );
        return 0;
    fi
}
complete -F _command_opt -o bashdefault -o default 'command'

Однако если я ввожу, command f[tab][tab]то получаю foo:bar и foo:foo в списке, но ни одна из них не завершается в моей командной строке (потому что они еще не различимы). Чего я хотел бы добиться, так это того, чтобы это создавало command foo:и оставляло мой курсор в конце текущего слова (вместо добавления пробела), чтобы я мог затем ввести bили f, а затем снова нажать Tab, чтобы завершить команду. Задача примера нужна только для того, чтобы показать, что я имею в виду... в реальном случае комбинации префикс:суффикс довольно длинные, поэтому частичное завершение было бы действительно полезным. Например, 25 различных команд, которые все начинаются с префикса translationupdateprocess: и translationupdateprocess — один из 25 различных одинаково длинных префиксов с таким количеством опций.

Кто-нибудь знает способ заставить bash работать таким образом?

решение1

Вы можете использовать следующий код (я заменил ваши варианты на foo:baz foo:qux bar:eat bar:eggдля ясности):

function _command_opt()
{
  local cur cursec command opts
  COMPREPLY=()

  cur="${COMP_WORDS[COMP_CWORD]}"
  cursec=`echo ${cur} | awk -F ':' '{print $1}'`;

  command="${COMP_WORDS[1]}"
  opts="foo bar"

  case "${command}" in
    foo)
      COMPREPLY=( $(compgen -W "baz qux" -- ${cursec}) ); return 0;;
    bar)
      COMPREPLY=( $(compgen -W "eat egg" -- ${cursec}) ); return 0;;
    *) ;;
  esac

  COMPREPLY=( $(compgen -W "${opts}" -S ":" -- ${cur}) ); compopt -o nospace;
}

complete -F _command_opt -o bashdefault -o default 'command'

Когда вы печатаете, commandtabвы можете получить список первого уровня foo: bar:, а когда вы печатаете, ftabtabвы получаете список завершения для второго уровня baz qux. Затем вы можете ввести, qtabчтобы получить полную командную строку command foo:qux.

Надеюсь, поможет.

Связанный контент