Bash TAB-завершение внутри строки в двойных кавычках
проблема
Я пишу Twitter-клиент для командной строки (на С). В настоящее время я работаю над завершением TAB для экранных имен Twitter, например:
твит "@s
@sourcebits @spolsky
Тем не менее, я не могу заставить его работать в середине строки, например:
твит "Foo bar @s
поскольку Bash рассматривает строку как одно слово. На странице руководства Bash я не нашел ничего, что могло бы предложить простое исправление, поэтому я решил взломать его. Ниже приведено мое неполное решение проблемы. Я просто делю входящую строку на пробелы, беру последнее слово (пока упрощенно) и отправляю compgen
(переменная $last_word
ниже). Тем не менее, мне нужно добавить $prefix
в начало строки, которую создает TAB-завершение, поскольку она заменяет всю входную строку (помните: она рассматривается как одно слово). Вот где я застрял.
Вопрос
Как это может быть сделано?
Код и т. Д.
__cltwitter_complete () {
local cache="$HOME/.cltwitter_users.cache"
local string=${COMP_WORDS[COMP_CWORD]}
local last_word=${string##* }
local prefix=${string% *}
COMPREPLY=()
#if [ ! -f ${cache} ] || [ "`find ${cache} -mmin +60`" != "" ]; then
# cltwitter-update-cache
#fi
if [[ "$last_word" == \"@* ]]; then # if word is beginning of a quotation
last_word=${last_word:2}
elif [[ "$last_word" == @* ]]; then # if user put '@' in front
last_word=${last_word:1}
fi
COMPREPLY=( $( compgen -W "`cat $cache`" -P @ -- $last_word ) )
}
complete -F __cltwitter_complete tweet
Соответствующий раздел со страницы руководства Bash:
COMP_WORDS
Переменная массива (см. Массивы ниже), состоящая из отдельных слов в текущей командной строке. Слова разделяются на метасимволы оболочки, так как синтаксический анализатор разделяет их. Эта переменная доступна только в функциях оболочки, вызываемых программируемыми средствами завершения.
2 ответа
Посмотрите на программируемое завершение: http://www.faqs.org/docs/bashman/bashref_103.html
Вам действительно нужны цитаты?
Например, ваша команда может быть:
tweet Foo bar @s<TAB>
Тогда @s будет просто словом, которое вы пытаетесь завершить, и вы можете искать его. Внутри скрипта вы все равно можете получить всю строку с помощью $*.
Вы должны быть более осторожными, вызывая сейчас, так как вы не можете использовать специальные символы, такие как! и () больше без необходимости избегать их с обратной косой чертой.