pistacchio
pistacchio

Reputation: 58883

Line completion with custom commands

my Python program can be launched with a range of different options (or subcommands) like:

$ myProgram doSomething
$ myProgram doSomethingElse
$ myProgram nowDoSomethingDifferent

I want it to use auto-completion with so that if i type "myProgram d" it returns "myProgram doSomething" and if i type "myProgram n" it renders "myProgram nowDoSomethingDifferent". This is similar to the average use of the module rlcompleter, but it does not pick possible completion options from the filesystem (or from history) but from a custom set of strings (that correspond to the available options for my program)

Any idea on how to implement this?

I'm aware of the variable PYTHONSTARTUP (that should point to a file I don't know how to write).

As a working example, django-admin (from the django package) has the same exact feature i'm looking for

Upvotes: 30

Views: 12203

Answers (6)

Scz
Scz

Reputation: 699

As mentioned in other answers, in bash this can be done with the bash-builtin complete. Easier than writing a function (as in richq's answer) is using complete's option -W which lets you specify a list of words. In your example this would be:

complete -W "doSomething doSomethingElse nowDoSomethingDifferent" myProgram

As it is a one-liner you don't have to create a file for this, but you can just put it in your .bashrc.

Upvotes: 13

Peter Hoffmann
Peter Hoffmann

Reputation: 58674

There is the module optcomplete which allows you to write the completion for bash autocompletion in your python program. This is very useful in combination with optparse. You only define your arguments once, add the following to your .bashrc

complete -F _optcomplete <program>

and all your options will be autocompleted.

Upvotes: 15

richq
richq

Reputation: 56448

Create a file "myprog-completion.bash" and source it in your .bashrc file. Something like this to get you started...

_myProgram()
{
  cur=${COMP_WORDS[COMP_CWORD]}
  case "${cur}" in
    d*) use="doSomething" ;;
    n*) use="nowDoSomethingElse" ;;
  esac
  COMPREPLY=( $( compgen -W "$use" -- $cur ) )
}
complete -o default -o nospace -F _myProgram  myProgram

Upvotes: 39

sastanin
sastanin

Reputation: 41511

As well as I know, PYTHONSTARTUP is for commands to be executed when the interpreter starts up [1]. rlcompleter is for autocompletion inside your script, if it is using readline library. Something like this:

$ ./myscript.py
My Script version 3.1415.
Enter your commands:
myscript> B<TAB>egin
myscript> E<TAB>nd

In your example you want to complete on the shell command line. This autocompletion is a shell feature (either bash or zsh, whatever you use). See, for example, an introduction to bash autocompletion (also part 2). For zsh see, for example this guide.

Upvotes: 3

unbeknown
unbeknown

Reputation:

If you want your program to select an command line option even though you only used an abbreviated form of this option you should have a look at the optparse module in the standard library.

Upvotes: 0

Anders Westrup
Anders Westrup

Reputation: 825

If I understand correctly you want line completion on the command line before your python script starts. Then you shouldn't search for a python solution, but look at the shell features.

If you are using bash you can look at /etc/bash_completion, and at least on debian/ubuntu you should create a file in /etc/bash_completion.d/ that specifies the completions for your program.

Upvotes: 6

Related Questions