arikast / askbash

An intuitive yaml-driven bash auto-completion framework
MIT License
97 stars 3 forks source link

About

Version: 0.6.4

Askbash makes it easy to define your own bash autocompletions (that thing that happens when you type a command and hit the tab key once or twice) using an intuitive yaml syntax. It also comes with a number of autocompletions pre-installed, which you can find in the completions/ directory.

This means when you type a program name which matches one of the completers, such as "mvn", that you can tab-complete arguments to the program on the command line based on the definitions found in the corresponding completion file (in this case mvn.yml).

How to install and use

Note: these instructions are written using markdown. If you are reading this file "raw" then you'll see backtick markings around the code snippets -- these backticks are formatting and are not part of the code!

   # export ASKBASH_DEBUG=1
   export ASKBASH_HOME=/your-actual-path/askbash
   source $ASKBASH_HOME/bashrc-generator.bash
   ~/.askbash/completions/*.yml
   $ASKBASH_HOME/completions/*.yml

That's it, you now have the full existing library of bash autocompletions working for you, and an easy way to write your own additional completions as needed.

Writing your own static completer

Your custom autocompletions are driven from a set of yaml files. For example, suppose you have a fictitious command called "food". You might create this completion in a file called food.yml:

   'food ':
       'fruit ':
           'orange ':
           'banana ':
       'veg ':
           'broccoli ':

After adding this file in ~/.askbash/completions/ and restarting your shell, you would now have autocompletion of "food " according to the static hierarchy defined in food.yml. You could now type "food f" and hit tab to complete the text to "food fruit ". You could then hit tab twice to get your next set of options, which would be "orange " and "banana ".

Here we explicitly add spaces to our choices because we want a space to be added when these words complete, but you don't have to do this. You could also have a "multi-part" completion by not putting a space at the end:

   'food ':
       'fruit ':
           'orange ':
           'banana ':
           '--seedless':
               '=true ':
               '=false ':
       'veg ':
           'broccoli ':

Here the --seedless does not end with a space because the intention is to continue with =true or =false without any spaces in between.

Sometimes our intent is to select many options, for example "food fruit orange --seedless=true banana". In this case, we use yaml's "reference" syntax to loop back to another node like this:

   'food ':
       'fruit ': &fruit
           'orange ': *fruit
           'banana ': *fruit
           '--seedless':
               '=true ': *fruit
               '=false ': *fruit
       'veg ':
           'broccoli ':

This "reference" syntax consists of an arbitrarily named anchor (here it is &fruit) followed by one or more references to it (in this case *fruit). Note how all nodes end with colons, but references occur after the colon.

Dynamic completers

Sometimes aspects of your completion hierarchy might be dynamic. For instance, perhaps in addition to =true and =false we also want to allow an arbitrary value here. In this case you'd use a Regex completer like this:

   'food ':
       'fruit ': &fruit
           'orange ':
           'banana ':
           '--seedless':
               '=true ': *fruit
               '=false ': *fruit
               '<Regex>.+ ': *fruit
       'veg ':
           'broccoli ':

There are many dynamic completers to do all sorts of things such as fill in a filename or list a running proc or execute an arbitrary bash command. Take a look at the $ASKBASH_HOME/lib/completers/ to see the available completers. Any of these completers can be used in your yml configuration; to use one, just use it in your .yml in the same way we've used the Regex above and drop the "Completer.rb" suffix when refering to it. So to use FileCompleter.rb for instance, you would specify <File> in your .yml config.

You can also of course easily write your own completer; just place it in lib/completers and then use it like any other, and make sure its name ends in "Config.rb".

Writing your own dynamic completer

See lib/completers/*.rb for examples of writing your own dynamic completer. You basically just need to extend a class and implement a few methods. You will also likely find it useful to enable debugging output, which can be done by setting an environment variable in your .bashrc (or .bash_profile as the case may be) like this:

   export ASKBASH_DEBUG=1

Then after restarting the shell, you'll find copious debugging info logged to $ASKBASH_HOME/askbash.log

Some nit-picky syntax/naming rules which MUST be followed

Examples

See completions/*.yml as well as test/completions/*.yml for examples