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 будет просто словом, которое вы пытаетесь завершить, и вы можете искать его. Внутри скрипта вы все равно можете получить всю строку с помощью $*.

Вы должны быть более осторожными, вызывая сейчас, так как вы не можете использовать специальные символы, такие как! и () больше без необходимости избегать их с обратной косой чертой.

Другие вопросы по тегам