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.
Do you really need the quotes?
For example, your command could be:
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.
Look at programmable completion: http://www.faqs.org/docs/bashman/bashref_103.html