SkillAgentSearch skills...

Tabtab

Create and install double-tab (‘tab tab’) auto-completions for any command-line application on any shell (bash, fish, ksh, etc)

Install / Use

/learn @drnic/Tabtab
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

= tabtab

  • http://tabtab.rubyforge.org

== DESCRIPTION:

Create and install double-tab ('tab tab') auto-completions for any command-line application on any shell (bash, fish, ksh, etc).

When you use the command-line, you can double-tab to auto-complete the name of a command-line application or a target file or folder. Its possible to provide your own completions for applications: git comes with bash shell completions, and the fish shell includes a library of completions for many applications.

=== Quick Start/Trial Me:

The tabtab gem comes with some pre-defined completions for some popular applications that benefit from completions: rails, newgem, cucumber, github (and its alias gh). It takes 2 minutes to trial this project and see if you like it:

bash>
sudo gem install tabtab
install_tabtab
source ~/.tabtab.bash

rails -d TABTAB

gem install github

github TABTAB
gh netTAB feTAB
gh netTAB web TABTAB

It just works. Flags. Commands. Intelligent values. Aliases. Ooh yeah.

Now, add 'source ~/.tabtab.bash' to your .bash_profile so you have this awesomeness in all your terminal shells.

Read on to learn how to write your own auto-completions with only a few lines of Ruby...

== FEATURES/PROBLEMS:

  • Completion defintions/recipes are shell agnostic (bash, fish, ksh, etc)
  • Definitions are written in Ruby
  • Can be bundled within RubyGems, explicitly referenced in local files, or automatically generated from -h help output from existing applications.
  • Very easy to use: 'install_tabtab' to find available completions, then 'source ~/.tabtab.bash'

== SAMPLE DEFINITION:

TabTab definitions for auto-completions are very easy to write. Initially you can store them in a normal Ruby file (say ~/.tabtab/myapp.rb) and later, if the application is a Ruby application and distributed as a RubyGem you can bundle it with the distribution.

=== Flags

A sample TabTab definition for the script/server command that is found within all Ruby on Rails applications:

TabTab::Definition.register('script/server') do |c|
  c.flag :debugger, :d
  
  c.flag :environment, :e do
    Dir['config/environments/*.rb'].map { |env| env.gsub(/^.*environments\//,'').gsub(/.rb$/,'') }
  end
  
  # script/server -p TABTAB -> generated first available port 3000, 3001, 3002
  c.flag :port, :p do
    port = 3000
    until `netstat -an | grep "^tcp" | grep #{port}`.strip.empty? || port > 3010
      port += 1
    end
    port > 3010 ? [] : [port.to_s]
  end
end

This definition defines 3 flags (each with short and long names): --debugger, --environment, and --port. The --debugger flag is a simple autocompletion. At the command-line, if you typed "script/server --d" and pressed double-tab it would instantly complete to "script/server --debugger ".

The other two flags can take values (e.g. "--environment development" or "--port 3000") and their definitions are more powerful. If you double-tab after "script/server --environment " you will be presented with options [development, test, production] for completion. If you type the first letter, it will complete to the full value.

Similarly for "--port". The algorithm above will find the first available port number from 3000+. As it only returns a single value in its result array, this value is automatically displayed on the command line. Very tricky indeed.

The #flag method (and its alias #flags) takes 1+ symbols describing the flag names. Its last argument can be a string as a description. This is not used for bash shell users, but is available to ksh/fish users who's autocompletion systems are capable of displaying them inline with the completion options.

The #flag method can also take a block. The result of the block must be an array of strings. These blocks (also available to #command and #default methods below) are called 'value blocks'. They return the complete, or a useful subset, of available values for the flag or command.

=== Commands

Many command-line apps take a command as their first argument. For example, the github CLI has commands such as: info, pull, and network. The latter even has sub-commands. Subsequently, you might run the following at the command line:

github info
github pull drnic
github network commits
github network web drnic

The following sample of the tabtab definition for the github command shows how tabtab can provide autocompletions for every example above, including the user values for the 'github pull' and 'github network web' commands.

TabTab::Definition.register('github') do |c|
  def users
    `github info | grep "^ -" | sed -e "s/ - //" | sed -e "s/ .*$//"`.split("\n")
  end
  
  c.command :info, "Show info"
  
  c.command :pull, "Pull from a remote." do |pull|
    pull.default { users }
    pull.flag :merge
  end
  
  c.command :network, "Project network tools" do |network|
    network.command(:web) { users }
    network.command :commits
  end
end

The #command method requires a symbol for the name, and can take a string for the command description (see Flags section above).

The #command method can also take a value block, like #flag above. It must return an array of strings.

The above example shows the behaviour of the 'github network web' command being abstracted into a separate method. Similarly, this method could be defined in an external Module, and included as necessary.

Note that 'pull.flag :merge' defines that 'github pull' can complete to 'github pull --merge' as well as the list of values returned from the #default value block.

=== Default value blocks

In the sample github definition above, the 'c.command :pull' value block is not the immediate block passed to the #command method. Instead the value block is defined via 'pull.default { }' This is an alternate syntax to the earlier value block, and is used where your command can autocomplete to various flags, sub-commands or other from within a generated list of values (via the #default value block).

=== Value block syntax

Value blocks are normal Ruby blocks that return an array of Strings.

The following syntax options for the 'run' command are functionally equivalent:

TabTab::Definition.register('myapp') do |c|
  c.command :run do
    %w[things to run]
  end

  c.command :run, "A description" do
    %w[things to run]
  end

  c.command :run do |run|
    run.default do
      %w[things to run]
    end
  end

  c.command(:run, "A description") { %w[things to run] }

  def things_to_run
    $[things to run]
  end
  c.command(:run) { things_to_run }
end

=== Application name aliases

I don't ever type 'script/generate', rather I have an alias 'gen' for it.

TabTab supports user-defined aliases (you might have an alias 'g' for 'script/generate') via its ~/.tabtab.yml configuration file. See Aliases section below.

== INSTALL:

  • sudo gem install tabtab

== SETUP:

Run install_tabtab to install the completions that come built-in with the tabtab RubyGem, and within any other RubyGem, at the time of execution.

In your .bash_profile add:

source ~/.tabtab.bash

=== Future shells:

In your .fish_profile add:

source ~/.tabtab.fish

In your .ksh_profile add:

source ~/.tabtab.ksh

=== Re-running install_tabtab

You never need to run this command again after new RubyGem updates, but you do need to re-run this command each time you:

  • install a RubyGem that contains a tabtab_definitions.rb file for the first time (once install_tabtab has discovered the gem it will automatically pick up changes to the definitions in future gem versions)
  • want to add completions defined in a local file, rather than bundled in a gem (see Local Files below)
  • want to add completions for 'external' apps (see External below)

Each time you run install_tabtab the above ~/.tabtab.sh file(s) will be updated. You then need to restart your shell(s) to load the new completions, or run the above command explicitly.

=== RubyGems: Completion Definitions in RubyGems

By default, install_tabtab automatically finds any completion definitions bundled in RubyGems. The tabtab gem itself includes lots of definitions for applications such as rails, script/server, rake, gem, cucumber, github, and others.

In time, the development and deployment of each script may be adopted by the relevant project owners and bundled in their RubyGems rather than the tabtab gem itself.

You can bundle tabtab defintions for 1 or more applications in your own RubyGems. Typically, you will include tabtab defintions for the applications that you bundle with your gem. For example, the global 'rails' app and the per-rails project 'script/server' applications are bundled in the 'railties' gem. Rails would ideally include its tabtab definitions in this railties gem and the core Rails team would maintain/update the tabtab definition whenever the actual applications are updated. This way the application and the tabtab defintions will be consistent.

To include tabtab definitions in a RubyGem, you need to add a 'tabtab_definitions.rb' file somewhere in your gem. The suggested location is 'lib/tabtab_definitions.rb'.

=== Local Files: Completion Definitions in Local Files

You can create and develop your own tabtab definitions for your apps or other people's apps. Its really simple. Really easy.

  1. Create a file

  2. Include the definition code:

    TabTab::Definition.register('TARGET_APP_NAME') do |c| ... end

  3. Create a ~/.tabtab.yml file

  4. Add file configuration:

    files: "/Users/drnic/.tabtab_definitions/TARGET_APP_NAME.rb": TARGET_APP_NAME

You can include multiple definitions in a single file (using multiple 'register(app_name)' calls) and including a list of file names:

files:
  "/Users/drnic/.tabtab_definitions/my_definitions.rb": curl, mongrel_rails

Related Skills

View on GitHub
GitHub Stars91
CategoryDevelopment
Updated5mo ago
Forks6

Languages

Ruby

Security Score

77/100

Audited on Oct 23, 2025

No findings