30

I'm trying to figure out how to implement tab completion for subcommands in a C++ application. I would like it to function much like Git's tab completion. I'm trolling through Git's source, but it's not jumping out at me.

I've searched for ways to implement tab completion and haven't found a straight-forward answer, so I'm guessing it might not necessarily be a feature each individual application has to implement. Is tab completion a feature of the particular shell the application is being executed from? What are the basics I need to know about getting my application to support tab completion (particularly in C++)?

E-rich
  • 9,243
  • 11
  • 48
  • 79
  • 2
    Tab completion is indeed usually a feature of a shell: you press tab within the shell while entering a command line, and it has some method for generating a list of possible completions, then shows you the list or iterates through them or something. I use zsh which is extremely flexible and has a complex notation for configuring shell completions: you can even have seperate shell scripts run to return the valid completions, or try to parse `--help` results to find out the valid options. Some programs do have an interactive mode though, in which they implement their own tab completion. – Tony Delroy Mar 10 '11 at 04:16
  • You really need to work out which situation you're in (and tell us). If it's a shell situation, then it's not normal to change your C++ program to assist with tab completion, although it is possible to work in with any command-line "discovery" features a particular shell may have (such as --help parsing), and you could have a command line switch to write out commands to configure good completion for a specific shell (much as `tset` returns terminal settings), but it's highly unusual and of dubious value. – Tony Delroy Mar 10 '11 at 04:19
  • If you want completion within your program, you normally have to find matches starting with a particular string. This might be done by populating all possible values in a std::map, then using lower_bound and/or upper_bound to find the currently matching completions. – Tony Delroy Mar 10 '11 at 04:21
  • I'd like to implement it in such a way that it doesn't matter what shell you're in (if that is possible). I'd like to support commands (**git bra** _tabbed_ results in **git branch**) and options (**git config --gl** _tabbed_ results in **git config --global**). – E-rich Mar 10 '11 at 04:32
  • 3
    [git-completion.bash](http://codesearch.google.com/codesearch/p#duvZQlM2HMg/contrib/completion/git-completion.bash) simply extends Bash's own tab completion. If you want to know how Bash implements tab completion, read up on [readline](http://www.gnu.org/software/readline/). – ephemient Mar 10 '11 at 04:35
  • How does the program actually read what has been typed in the command line if it hasn't been executed. Or does pressing _tab_ in certain shells actually execute the program? – E-rich Mar 10 '11 at 04:35
  • 2
    @E-rich: ypically, it's not using the program at all... it's just been told about the program's command line arguments beforehand. For example, my zsh install has a 4373 line scripts just to provide this support for git. And sadly this is about the shells and not your program... you simply can't provide tab completion for shells that don't support it. – Tony Delroy Mar 10 '11 at 04:39
  • @E-rich: imagine you had a Windows program with a nice little icon, and every time the mouse hovered over your icon you wanted Windows to dim the rest of the screen, have translucent stormy clouds float dramatically across the background, lighting flash in towards your icon, and Carmina Burana to play in the background. All nice to want it, but as your programs not running at that stage *it* can't pull it off. You can do something separate - another program, Explorer configuration changes etc - to react to that situation and get the desired effect, but the scope's different. Same for shells. – Tony Delroy Mar 10 '11 at 04:49
  • Btw, I believe you mean you're "trawling" through Git's source, not "trolling". "Trolling" is generally frowned upon :) – David Mar 10 '11 at 04:56
  • @David M: I almost changed it, but I came across: http://dictionary.reference.com/browse/trawl and http://dictionary.reference.com/browse/troll. I think either would work. – E-rich Mar 10 '11 at 22:54

2 Answers2

8

The question was answered in the comments.

Is tab completion a feature of the particular shell the application is being executed from?

yes

What are the basics I need to know about getting my application to support tab completion (particularly in C++)?

basically learn more about bash-completion

E-rich
  • 9,243
  • 11
  • 48
  • 79
2

I've searched for ways to implement tab completion and haven't found a straight-forward answer

Look at the code here. This should give you a pretty good starting point.

What are the basics I need to know about getting my application to support tab completion

You should be familiar with Trie data structure, as this is the common data structure used to implement tab completion. There are lots of tutorials explaining it online, look it up.

Pseudo-code (given a list of strings):

For each string in the list, store its characters in Trie data structure.

when the user hit tab key:

(GeeksForGeeks) Given a query prefix, we search for all words having this query.

  1. Search for given query using standard Trie search algorithm.
  2. If query prefix itself is not present, return -1 to indicate the same.
  3. If query is present and is end of word in Trie, print query. This can quickly checked by seeing if last matching node has isEndWord flag set. We use this flag in Trie to mark end of word nodes for purpose of searching.
  4. If last matching node of query has no children, return.
  5. Else recursively print all nodes under subtree of last matching node.
Community
  • 1
  • 1
SubMachine
  • 487
  • 3
  • 11