Skip to content

Usage#

Basics#

Ensure Tabular is imported into your project:

require "tabular"

Tabular.prompt? is convenience method that checks for the CLI command (__complete by default) the shells will use to retrieve completions:

if Tabular.prompt?
  # do stuff
end

Of course, you can always handle this however you'd like.

Concepts#

Beyond the insanely on-brand synergy of both platform and use-case, so to are the concepts in Tabular. Miraculously.

Habit#

A Habit is the environment in which various features are made available for your completion to take form. This done within the block of the Tabular.form method:

if Tabular.prompt?
  Tabular.form do
    # define your completions
  end
end

Tablets#

A Tablet represents any possible suggestion the end-user will receive, given the current argument. Tabular comes with three built-in Tablet:Tablet] styles:

require "tabular"

if Tabular.prompt?
  Tabular.form do
    option "--opt" "-o", help: "a flag parameter"

    option "--arg" "-a", help: "a option with any argument" { argument }

    option "--file" "-f", help: "a option with file extension-specific argument" {
      argument "yaml", "yml", "json", directives: :filter_ext
    }

    option "--dir" "-d", help: "a option with directory-specific argument" {
      argument directives: :filter_dir
    }

    option "--opt2", help: "a flag with multiple arguments" do
      argument "arg1_choice1", "arg1_choice2", "arg1_choice3"
      argument "arg2_choice1", "arg2_choice2"
    end

    command "cmd1", "cmd1_alias1", "cmd1_alias2", help: "a subcommand"
  end
end

Tip

You can also create you own bespoke Tablets with the base Tablet class.

Dispatch#

When a Command-flavoured Tablet is matched, control is handed back to your CLI via the #dispatch block when defined:

require "tabular"

if Tabular.prompt?
  Tabular.form do
    command "validate", "valid", help: "validate infrastructure"
    command "config", "conf", "c", help: "get/set configs"

    dispatch do |command|
      if command.name == "cmd1"
        Validate.complete
      end
      if command.name == "cmd2"
        Config.complete
      end
  end
end

class Validate
  # ...

  def complete(args = ARGV)
    Tabular.form do
      option "--verbose" "-v"
      option "--dry-run" "-n"

      argument "tf", directive: :filter_ext
    end
  end
end

class Config
  # ...

  def complete(args = ARGV)
    Tabular.form do
      argument "*/config/*", directive: :filter_dir
      argument "json", "ejson", directive: :filter_ext
    end
  end
end

Any unhandled Habit#command Tablets will fallback to default completion behaviour for the given shell; but, you can override this behaviour:

Tabular.form do
  # Globally override default command directives
  directives :command, :no_file

  # Override command deirectives
  command "action1", "act1", help: "A subcommand", directives: :no_file
end

Flow#

sequenceDiagram
  participant Begin as BEGIN
  participant Opts as OPTION[ ARGUMENT][ ...]
  participant Args as ARGUMENT[ ...]

  loop
    Opts-->>Args: followed by
    participant Cmd as COMMAND
    Opts-->>Cmd: followed by
    create participant Sub as ...
    Cmd-->>Sub: followed by
    destroy Sub
    Sub-->>Begin: dispatch
  end

  participant Done as END
  Opts-->>Done: done
  Args-->>Done: done
  Cmd-->>Done: done

While, there is no mineral-based connection, it's important to understand the assumed flow of the built-in Tablets:

  • The flow begins with any Tablet flavour.
    cli {OPTIONS[ ARGUMENTS] ... | ARGUMENTS ... | COMMAND ...}
    
  • A Option (and any required Argument) flavour can appear anywhere in the flow.
  • A Command flavour can only follow an Argument flavour when it a part of an Option.
    cli [OPTIONS[ ARGUMENTS] ...] {ARGUMENTS ... | COMMAND ...}
    
  • Once a Command flavour is matched:
  • The flow resets when #dispatch is defined.
  • Otherwise, the flow ends.
  • Once a final Option or Argument flavour is matched, the flow ends.

Tip

You can leverage the API to create your own bespoke flow.

Installer#

Finally—to allow your users to setup completions in their shell—call Tabular.install! when a subcommand of your choosing is provided to your CLI:

Tip

It's recommended that you use the subcommand completion, as it follows the go-cobra standard.

require "tabular"

if ARGV[0]? == "completion"
  ARGV.shift

  begin
    # Read arguments from `ARGV` or supply your own
    Tabular.install! # ["bash"]
  rescue e : Tabular::Error
    STDERR.puts e
    exit 1
  end
end