Bash TAB-completion inside double-quoted string

浪子不回头ぞ 提交于 2019-12-07 15:39:18

问题


Problem

I'm writing a Twitter client for the command line (in C). I'm currently working on doing TAB-completion for Twitter screen names, like so:

tweet "@s<TAB>
@sourcebits @spolsky

However, I can't get it to work mid-string, e.g.:

tweet "Foo bar @s<TAB>

since Bash treats the string as one word. I couldn't find anything in the Bash man page suggesting a simple fix, so I decided to hack around it. Below is my half-done solution to the problem. I simply split the incoming string by spaces, take the last word (simplification, for now) and send it to compgen (the variable $last_word below). However, I need to append $prefix to the beginning of the string that the TAB-completion produces, as it replaces the whole input string (remember: it's treated as one word). That's where I'm stuck.

Question

How can this be done?

Code etc.

__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

Relevant section from the Bash man page:

COMP_WORDS

An array variable (see Arrays below) consisting of the individual words in the current command line. The words are split on shell metacharacters as the shell parser would separate them. This variable is available only in shell functions invoked by the programmable completion facilities.


回答1:


Look at programmable completion: http://www.faqs.org/docs/bashman/bashref_103.html




回答2:


Do you really need the quotes?

For example, your command could be:

tweet Foo bar @s<TAB>

Then @s would simply be the word you are trying to complete, and you can search for that. Inside the script, you can still get at the entire string with $*.

You'll have to be more careful invoking now, though, as you can't use special characters such as ! and ( ) anymore without having to escape them with a backslash.



来源:https://stackoverflow.com/questions/731219/bash-tab-completion-inside-double-quoted-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!