1

I've just starting using gflags for a couple of C++ projects I'm working on. I find that the --help returns a large amount of flags, and I'm currently using myapp --help | less to find the flags I'm looking for. I would love to have tab completion for this.

Tonight I discovered the files for completion in the git repository of glags. And that the command gflags_completions.sh has been installed in my bash environment with gflags.

Questions

  1. Is there any documentation for gflags_completion.sh and how to use it? Yes, gflags_completions.h.in
  2. How do I use the gflags_completion.sh script to make a completion entry for my own applications? (See answer below)

Minimal example: myapp.cc

To compile this file, run g++ -o myapp myapp.cc -lgflags.

/** GFlags test app for tab completion.
 *  License: Creative Commons 4.0 Attribution
 *  Compile with:
 *  g++ -o myapp myapp.cc -lgflags 
 */
#include <gflags/gflags.h>

int main(int argc, char **argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);
  return 0;
}

What I believe should have worked

After reading up a bit on the complete command, I believe this should work, but I do not succeed.

$ complete -o nospace -C \
  '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
  time env myapp
$ ./myapp -[TAB]

Related question: How does bash tab completion work?

Community
  • 1
  • 1
Trygve
  • 493
  • 3
  • 15
  • 1
    "it's probably some very similar questions on bash auto-completions here on SO" -- if you didn't actually search for duplicates before you posted the question, you should do that yourself and then mark the question as a duplicate yourself, if you feel that its worth having this question. instead of asking others to find the duplicated info for you. – Chris Beck Sep 14 '15 at 00:42
  • 1
    Hi Chris, thank you for pointing this out - and that the language I used is pretty much a provocation. I realize that now :) I have looked through the duplicate candidates, and there is nothing else on gflags_completions AFAIK. I believe we can justify having this question as soon as we get a couple of edits in. – Trygve Sep 14 '15 at 00:50
  • ok, just checking :) – Chris Beck Sep 14 '15 at 00:51
  • Can you have a look again @ChrisBeck, and see if you think this makes more sense? – Trygve Sep 14 '15 at 01:48
  • 1
    it looks like a good question, I don't know the answer but you have my upvote :) – Chris Beck Sep 14 '15 at 01:53

1 Answers1

1

OK, with some help from a friend i found the file gflags_completions.h.in where the documentation for this feature is. I have pasted a part of the header file in the end of this answer.

What was missing from my question above, is the incude statement for gflags_completions.h.

Minimal working example: myapp.cc

/** GFlags test app for tab completion.
 *  License: Creative Commons 4.0 Attribution
 *  Compile with:  g++ -o myapp myapp.cc -lgflags
 */
#include <gflags/gflags.h>
#include <gflags/gflags_completions.h>
int main(int argc, char **argv) {
  gflags::ParseCommandLineFlags(&argc, &argv, true);
  return 0;
}

To test this, go through these steps in a bash terminal:

$ g++ -o myapp myapp.cc -lgflags      # Compile the example.
$ which gflags_completions.sh         # Check the path of gflags_compl...
/usr/local/bin/gflags_completions.sh  # I use this path below.
# Tell bash to use autocomplete for myapp.
$ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS'\
time env myapp

The resulting output is:

$ ./myapp -[TAB]
~
-----------------
--flagfile [''] load flags from file
--fromenv [''] set flags from the environment [use 'export FLAGS_f'...
--help [false] show help on all flags [tip: all flags can have two ...
--helpfull [false] show help on all flags -- same as -help
--helpmatch [''] show help on modules whose name contains the speci...
--helpon [''] show help on the modules named by this flag value
--helppackage [false] show help on all modules in the main package
--helpshort [false] show help on only the main module for this program
--helpxml [false] produce an xml version of help
-* Other flags *-
--tab_completion_columns [80] Number of columns to use in output fo...
--tab_completion_word [''] If non-empty, HandleCommandLineCompletio...
--tryfromenv [''] set flags from the environment if present
--undefok [''] comma-separated list of flag names that it is okay t...
--version [false] show version and build info and exit

Snipplet from gflags_completions.h.in:

How to have bash accept completions from a binary:

Bash requires that it be informed about each command that programmatic completion should be enabled for. Example addition to a .bashrc file would be (your path to gflags_completions.sh file may differ):

$ complete -o bashdefault -o default -o nospace -C                            \
  '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS'\
  time  env  binary_name  another_binary  [...]                            

This would allow the following to work:

$ /path/to/binary_name --vmodule<TAB>                                       

Or:

$ ./bin/path/another_binary --gfs_u<TAB>                                    

(etc)

Sadly, it appears that bash gives no easy way to force this behavior for all commands. That's where the "time" in the above example comes in. If you haven't specifically added a command to the list of completion supported commands, you can still get completions by prefixing the entire command with "env".

$ env /some/brand/new/binary --vmod<TAB>                                    

Assuming that "binary" is a newly compiled binary, this should still
produce the expected completion output.

Trygve
  • 493
  • 3
  • 15