Chris L. Barnes
Chris L. Barnes

Reputation: 482

How to use bash_autocomplete for the second argument?

Use case: I am trying to get source activate <env> to autocomplete the names of my conda environments (i.e. the list of directories in ~/anaconda3/envs/).

I've managed to get it to work if I didn't need the 'activate' in there using this code:

_source ()
{
    local cur

    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}

    COMPREPLY=($(ls ~/anaconda3/envs | xargs -I dirs bash -c "compgen -W dirs $cur"))

    return 0
}

complete -F _source source

I've tried setting the last argument of complete to source\ activate and 'source activate' but that's not working (it just autocompletes with local files).

The issue seems to be that because source activate is not a function, it doesn't pick it up.

The simple solution is, of course, to make a single-word bash script which just contains source activate $1. But I'd rather do it properly!

Upvotes: 3

Views: 2391

Answers (2)

Fuseteam
Fuseteam

Reputation: 396

getting autocomplete to work for the second argument can be done with a case statement like this

_source()
{
    local cur prev opts
    case $COMP_CWORD in
        1) opts="activate";;
        2)  [ ${COMP_WORDS[COMP_CWORD-1]} = "activate" ] && opts=$(ls ~/anaconda3/envs | xargs -I dirs bash -c "compgen -W dirs $cur");;
        *);;
    esac
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
    return 0
}
complete -F _source source

compgen is build in function of bash which you then give the options you want to complete for with $opts for the first argument it will authocomplete "activate" but that can be adapted to be a more existive list and for the second argument it first checks if the first argument is "activate" before attempting to complete

disclaimer i adapted this from a completion function i wrote for ubports-qa, i haven't been able to test it but it should just work

Upvotes: 0

Chris L. Barnes
Chris L. Barnes

Reputation: 482

My solution was adapted from this conda issue.

It checks that the first argument is activate and then does the compgen using whatever the second word you're typing is.

#!/bin/bash
_complete_source_activate_conda(){
      if [ ${COMP_WORDS[COMP_CWORD-1]} != "activate" ]
      then
          return 0
      fi
      local cur=${COMP_WORDS[COMP_CWORD]}
      COMPREPLY=($(ls ~/anaconda3/envs | xargs -I dirs bash -c "compgen -W dirs $cur"))
      return 0
}

complete -F _complete_source_activate_conda source

Put that script in /etc/bash_completion.d/. Unfortunately it kills the first-word autocompletion - with some more fiddling it would probably be able to handle both.

Upvotes: 2

Related Questions