Conditional trailing space with bash programmable completion
Asked Answered
P

1

11

I'm creating a function to provide programmable completion for a command that I use (with much help from http://www.debian-administration.org/articles/317). The shell script usage is as follows:

script.sh command [command options]

where command can be either 'foo' or 'bar' and command options for 'foo' are 'a_foo=value' and 'b_foo=value' and command options for 'bar' are 'a_bar=value' and 'b_bar=value'.

Here's the configuration I'm using:

_script() {
  local cur command all_commands                                                                    
  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  command="${COMP_WORDS[1]}"
  all_commands="foo bar"
  case "${command}" in
    foo)
      COMPREPLY=( $(compgen -W "--a_foo --b_foo" -- ${cur}) ); return 0;;
    bar)
      COMPREPLY=( $(compgen -W "--a_bar --b_bar" -- ${cur}) ); return 0;;
    *) ;;
  esac
  COMPREPLY=( $(compgen -W "${all_commands}" -- ${cur}) )
  return 0
}

complete -F _script script.sh

This mostly works as I'd like:

% script.sh f[TAB]

completes to:

% script.sh foo 

(with a trailing space as desired)

However, this:

% script.sh foo a[TAB]

completes to:

% script.sh foo a_foo 

(also with a trailing space)

I'd like to replace the trailing space with an '='. Alternatively, I'd be willing to change the values passed to compgen to be "--a_foo= --b_foo=", in which case I could just delete the trailing space.

Unfortunately, the command is not under my control, so I can't change the command line options to be of format "--a_foo value" instead of "--a_foo=value".

Propjet answered 12/4, 2012 at 18:40 Comment(0)
S
15

First you need to add = to the COMPREPLY:

COMPREPLY=( $(compgen -W "--a_foo= --b_foo=" -- ${cur}) )

next you need to tell completion not to add space after = with

compopt -o nospace

So, you script lines should be:

foo)
  COMPREPLY=( $(compgen -W "--a_foo= --b_foo=" -- ${cur}) ); compopt -o nospace; return 0;;
bar)
  COMPREPLY=( $(compgen -W "--a_bar= --b_bar=" -- ${cur}) ); compopt -o nospace; return 0;;
Straddle answered 12/4, 2012 at 18:55 Comment(3)
Perfect... thanks. I do see compopt now in the bash man pages. There should probably be a mention of it in the Programmable Completion section!Propjet
I always look at bash-completion.alioth.debian.org if I;m stuck with completions. I guess no feature exists that is not used in this project ;-)Straddle
Is there any way of doing this in bash 3.X? compopt seems only to exist in bash4 and the mac does not yet come with it by default.Punt

© 2022 - 2024 — McMap. All rights reserved.