Bash autocomplete an option without running the application

1.5k Views Asked by At

I have found this code as a bash autocomplete. But, it looks strange to me. What if I do not like to run the code at all. If I would like to type ./a.out then space (without entering) and then by pressing tab, I would like to see only two options apple and cherry and if I type a and press tab, then it autocomplete the option apple and similarly for c. Let's say only one of the two options are acceptable:

./a.out apple
./a.out cherry

where apple and cherry are options and not the name of the files in the directory. In the first case, I would like the program types that your option is apple and in the second case your option is cherry. In any other case, the program should print an error that the option is not valid.

All examples that I find on the internet such as what follows look like that you should run the program first, then it reacts. The while loop inside the main function collides with the normal functionality of the program. Have I misunderstood the readline library? Is the above-described application possible to implement by editing the following code?

// sudo apt-get install libreadline-dev
// g++ -std=c++11 main.cpp -lreadline

#include <iostream>

#include "readline/readline.h"
#include "readline/history.h"

using namespace std;

int main(int argc, char** argv)
{
    const char *line;
    while ((line = readline("? ")) != nullptr) {
        cout << "[" << line << "]" << endl;
        if (*line) add_history(line);
        free(line);
    }
// if(argc!=2)
// {
//  cout<<"<exe> one_parameter"<<endl;
//  return 1;
// }
// string option=argv[1];
// if(option=="apple" || option=="cherry")
//  cout<<"Your option is "<<option<<endl;
// else
// {
//  cout<<"Error: invalid option "<<option<<endl;
//  return 1;
// }

    return 0;
}
2

There are 2 best solutions below

3
On BEST ANSWER

This has nothing to do with your executable. You need to put this in a file and source (source autocomplete_file or . autocomplete_file) it in the bash.

_a_complete_()
{
    local word=${COMP_WORDS[COMP_CWORD]}
    local files='apple cherry'

    COMPREPLY=( $( compgen -W "${files}" -- ${word} ) )
}

complete -F _a_complete_ ./a.out

Here a nice documentation can be found.

1
On

// partial answer - why you may want to invoke the app while doing the autocompletion

One way of implementing the autocomplete for an application is to have the application binary configure it (by having a flag that prints the instructions for autocomplete configuration or by just parsing the --help output of the application).

Schemataically:

complete -F $(./a.out --generate-autocomplete-config) ./a.out

This is why you might see the binary actually invoked as a part of autocomplete implementation.