Bash Completion Script Help

Posted by inxilpro on Server Fault See other posts from Server Fault or by inxilpro
Published on 2010-03-19T20:57:51Z Indexed on 2010/03/19 21:01 UTC
Read the original article Hit count: 437

So I'm just starting to learn about bash completion scripts, and I started to work on one for a tool I use all the time. First I built the script using a set list of options:

_zf_comp() 
{
    local cur prev actions
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    actions="change configure create disable enable show"

    COMPREPLY=($(compgen -W "${actions}" -- ${cur}))  
    return 0
}
complete -F _zf_comp zf

This works fine. Next, I decided to dynamically create the list of available actions. I put together the following command:

zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*\033\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\\-", $1); print $1}' | tr \\n " " | sed 's/^ *\(.*\) *$/\1/'

Which basically does the following:

  • Grabs all the text in the "zf" command after "Providers and their actions:"
  • Grabs all the lines that start with "zf" (I had to do some fancy work here 'cause the ZF command prints in color)
  • Grab the second piece of the command and remove any spaces from it (the spaces part is probably not needed any more)
  • Sort the list
  • Get rid of any duplicates
  • Escape dashes (I added this when trying to debug the problem—probably not needed)
  • Trim all new lines
  • Trim all leading and ending spaces

The above command produces:

$ zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*\033\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\\-", $1); print $1}' | tr \\n " " | sed 's/^ *\(.*\) *$/\1/'
change configure create disable enable show 
$

So it looks to me like it's producing the exact same string as I had in my original script. But when I do:

_zf_comp() 
{
    local cur prev actions
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    actions=`zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*\033\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\\-", $1); print $1}' | tr \\n " " | sed 's/^ *\(.*\) *$/\1/'`

    COMPREPLY=($(compgen -W "${actions}" -- ${cur}))  
    return 0
}
complete -F _zf_comp zf

My autocompletion starts acting up. First, it won't autocomplete anything with an "n" in it, and second, when it does autocomplete ("zf create" for example) it won't let me backspace over my completed command.

The first issue I'm completely stumped on. The second I'm thinking might have to do with escape characters from the colored text.

Any ideas? It's driving me crazy!

© Server Fault or respective owner

Related posts about bash

Related posts about tab-completion