24

I am running Ubuntu 13.10 and fish 2.1.0. I want to write myself a Python script to do some tasks from the command line. The script will require command line arguments.

How can I write my script such that fish can request and get possible values for a given argument. The list of potential values is dynamic. That is, it will be determined programatically (e.g. a list of folder names matching some criteria).

The end result I am aiming for is something like:

user@machine ~> myprog argument=fol<TAB>
folder1  folder2  folder3

Where myprog is my script file, argument is the argument name and folder1 etc are valid values generated by some function in my script.

Is this possible, and if so how?

lofidevops
  • 15,528
  • 14
  • 79
  • 119
  • 1
    you should create a fish autocomplete function for your script (http://stackoverflow.com/questions/16657803/creating-autocomplete-script-with-sub-commands) – furins Dec 30 '13 at 11:17
  • @furins so tab-completion can only be provided by writing an additional shell script? there is no way to offer an interface that fish (and other shells) could query in order to extract completions in real-time? – lofidevops Dec 30 '13 at 11:53
  • maybe I'm looking for the fish equivalent of this bash-helper: https://pypi.python.org/pypi/argcomplete/0.6.5 – lofidevops Dec 30 '13 at 12:00
  • please note that `argcomplete` requires you to launch a bash script to work, named `activate-global-python-argcomplete` https://pypi.python.org/pypi/argcomplete/0.6.5#activating-global-completion (then, again, you have to write a shell script if you want to replicate this approach) – furins Dec 30 '13 at 12:02
  • @furins yup, I am discovering that it's shell scripts all the way down :) your comments are pointing me in the right direction, thanks – lofidevops Dec 30 '13 at 12:11
  • 1
    note to self: see also https://github.com/dbarnett/python-selfcompletion and http://furius.ca/optcomplete/ for more attempts on the Python side – lofidevops Dec 30 '13 at 12:20
  • queries/feature requests: https://github.com/kislyuk/argcomplete/issues/68, https://github.com/fish-shell/fish-shell/issues/1217 and https://github.com/dbarnett/python-selfcompletion/issues/2 – lofidevops Dec 31 '13 at 08:09

3 Answers3

21

Adapted from zanchey's comment on GitHub:

If you have a program myprog which takes the --_completion option, you can write a single completion stub for myprog that looks like this:

complete --command myprog --arguments '(myprog --_completion (commandline -cp)'

Your program will then get invoked as myprog --_completion myprog some arguments here, and you can respond with the appropriate completions. It should return only the current token that is being completed (you could also pass this to the program with (commandline -ct), or tokenise it yourself), followed optionally by a tab and a short description. Multiple completions are separated with new lines.

Notes:

For Python scripts specifically, the following libraries may support fish completions at some point in the future (but they don't yet):

faho
  • 14,470
  • 2
  • 37
  • 47
lofidevops
  • 15,528
  • 14
  • 79
  • 119
  • I have tried a similar command. It did work when I execute it in a Fish session, but it didn't work when I put it in `config.fish`. – satoru Nov 26 '20 at 07:50
15

You should create a fish autocomplete function for your script and source it or put it in ~/.config/fish/completions/myprog.fish folder.

reference: fish docs

furins
  • 4,979
  • 1
  • 39
  • 57
1

I would like to complete the answer of @lofidevops in some edge case.

In my case I am using https://pkg.go.dev/github.com/jessevdk/go-flags which works similarly, but expect all arguments to be passed separately, not just a single one with space . (commandline -cp) does not return a list of argument, but a a single string with space.

In my case the following complete function worked like a charm:

complete -c my_prog -f  -a "(GO_FLAGS_COMPLETION=1 my_prog (string split ' ' (commandline -cp)))"