
Представьте, что у меня есть команда «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'
Когда вы печатаете, command
tabвы можете получить список первого уровня foo: bar:
, а когда вы печатаете, f
tabtabвы получаете список завершения для второго уровня baz qux
. Затем вы можете ввести, q
tabчтобы получить полную командную строку command foo:qux
.
Надеюсь, поможет.