View Source Tux.Help behaviour (Tux v0.4.0)

Create beautiful looking, well-structured help messages for commands or dispatchers.

Features

  • Elegant layouts
  • Minimal coloring
  • Customizable

Example

Here's an example of a well structured command help message which you can create with tux:

ABOUT
  mng - command for controlling systems

USAGE
  tool mng [OPTS] [ARGS]

OPTIONS
  --upcase, u        Uppercase endpoint name
  --lowercase, l     Lowercase endpoint name

NOTES
  Here are some additional notes to include
  in the help message.

Pipelined Help Messages

The help message above can be created with the following Tux.Help pipeline:

defmodule MngCmd do
  use Tux.Command

  @impl true
  def main(_, _), do: ...

  @impl true
  def help() do
    Help.new()
    |> Help.about("mng", "command for controlling systems")
    |> Help.usage(["tool mng [OPTS] [ARGS]"])
    |> Help.options([
      {"--upcase, u", "Uppercase endpoint name"},
      {"--lowercase, l", "Lowercase endpoint name"},
    ])
    |> Help.section("notes", """
    Here are some additional notes to include
    in the help message.
    """)
    |> Help.ok()
  end
end

Manual Help Messages

If you want complete control over your help messages, you can construct them manually. Here's the code that would render the above help message:

defmodule MngCmd do
  use Tux.Command

  @impl true
  def help() do
    """
    #{bold("ABOUT")}
      mng - command for controlling systems
    #{bold("\nUSAGE")}
      #{green("tool mng [OPTS] [ARGS]")}
    #{bold("\nOPTIONS")}
      #{green("--upcase, u")}        Uppercase endpoint name
      #{green("--lowercase, l")}     Lowercase endpoint name
    #{bold("\nNOTES")}
      Here are some additional notes to include
      in the help message.
    end
    """
    |> Help.ok()
  end

end

Summary

Types

A program description

A program binary name

A command description

A command name

A flag description

A flag name

Options for section creation

A help message section's title

t()

The help struct

Callbacks

One line, command description

Return a help struct for showing help messages

Functions

This is used internally by the Tux.Dispatcher and will inject the help/0 dispatcher callback for returning the help message.

Append the about section which describes the command.

Append the about section which describes the command.

A utility function to align a collection of pair items.

Build the specification for section creation

Append the commands section to the help struct.

Return the string representation of section head

Initialize a new help struct with the given options.

Add one or more newlines.

Return the help struct wrapped in a {:ok, ..} tuple.

Define the options section

Create a custom help section with a given title and body.

Append a new block of text as a new section.

Append a title styled to the help sections.

Append the usage section, where a very short, general structure of the command is presented.

Types

bin_desc()

@type bin_desc() :: String.t()

A program description

bin_name()

@type bin_name() :: String.t()

A program binary name

cmd_desc()

@type cmd_desc() :: String.t()

A command description

cmd_name()

@type cmd_name() :: String.t()

A command name

flg_desc()

@type flg_desc() :: String.t()

A flag description

flg_name()

@type flg_name() :: String.t()

A flag name

sec_opts()

@type sec_opts() :: [{:title, String.t()}]

Options for section creation

sec_title()

@type sec_title() :: String.t()

A help message section's title

t()

@type t() :: %Tux.Help{
  color: boolean(),
  hue: fun(),
  sections: [any()],
  upcase: boolean()
}

The help struct

Callbacks

about()

(optional)
@callback about() :: String.t()

One line, command description

help()

(optional)
@callback help() :: {:ok, t()}

Return a help struct for showing help messages

Functions

__using__(opts)

(macro)

This is used internally by the Tux.Dispatcher and will inject the help/0 dispatcher callback for returning the help message.

about(help, description)

@spec about(t(), bin_desc()) :: t()

Append the about section which describes the command.

iex> Tux.Help.new(color: false)
...> |> Tux.Help.about("this is the one line cmd description")
...> |> String.Chars.to_string()
"ABOUT\n" <>
"  this is the one line cmd description\n"

about(help, name, description)

@spec about(t(), bin_name(), bin_desc()) :: t()

Append the about section which describes the command.

Example

Specifying the command name in the about section

iex> Tux.Help.new(color: false)
...> |> Tux.Help.about("cmd", "this is the one line cmd description")
...> |> String.Chars.to_string()
"ABOUT\n" <>
"  cmd - this is the one line cmd description\n"

add_cmd(cmds, cmd, list)

align_pairs(pairs, left_pad, inter_pad)

A utility function to align a collection of pair items.

Example

iex> Tux.Help.align_pairs([
...>   {"a", "some description"},
...>   {"aaa", "some description"},
...>   {"aaaaa", "some description"},
...> ], 0, 4)
[{"a        ", "some description"},
 {"aaa      ", "some description"},
 {"aaaaa    ", "some description"}]

iex> Tux.Help.align_pairs([
...>   {"a", "some description"},
...>   {"aaa", "some description"},
...>   {"aaaaa", "some description"},
...> ], 2, 1)
[{"  a     ", "some description"},
 {"  aaa   ", "some description"},
 {"  aaaaa ", "some description"}]

build_specs(title, opts)

@spec build_specs(sec_title(), sec_opts()) :: %{color: boolean(), title: String.t()}

Build the specification for section creation

commands(help, options, opts \\ [])

@spec commands(t(), [{cmd_name(), cmd_desc()}], sec_opts()) :: t()

Append the commands section to the help struct.

Example

iex> alias Tux.Help
...> Help.new(color: false)
...> |> Help.commands([
...> {"start", "Start something"},
...> {"stop", "Stop something"},
...> ])
...> |> to_string()
"COMMANDS\n" <>
"  start    Start something\n" <>
"  stop     Stop something\n"

has_module?(cmds, module)

head(help, title)

@spec head(t(), String.t()) :: String.t()

Return the string representation of section head

new(opts \\ [])

@spec new(Keyword.t()) :: t()

Initialize a new help struct with the given options.

Examples

iex> Tux.Help.new()
%Tux.Help{color: true, hue: &Tux.Colors.green/2, sections: [], upcase: true}

iex> Tux.Help.new(color: false)
%Tux.Help{color: false, hue: &Tux.Colors.green/2, sections: [], upcase: true}

Options

When constructing a new help struct you can customize it behaviour with the following options:

  • :hue (fun/2) – function for coloring (default is Tux.Colors.green/2)
  • :color (boolean) – flag to colorize help sections (default is true)
  • :upcase (boolean) – flag to uppercase the section titles (default is true)

newline(help, count \\ 1)

@spec newline(t(), pos_integer()) :: t()

Add one or more newlines.

ok(help)

@spec ok(t()) :: {:ok, t()}

Return the help struct wrapped in a {:ok, ..} tuple.

iex> Tux.Help.new(color: false)
...> |> Tux.Help.about("this is my command")
...> |> String.Chars.to_string()
...> |> Tux.Help.ok()
{:ok, "ABOUT\n" <>
"  this is my command\n"}

options(help, options, opts \\ [])

@spec options(t(), [{flg_name(), flg_desc()}], sec_opts()) :: t()

Define the options section

Example

iex> alias Tux.Help
...> Help.new(color: false)
...> |> Help.options([
...> {"--flag1", "flag1 description"},
...> {"--flag2", "flag2 description"},
...> {"--flag3", "flag3 description"},
...> ])
...> |> to_string()
"OPTIONS\n" <>
"  --flag1    flag1 description\n" <>
"  --flag2    flag2 description\n" <>
"  --flag3    flag3 description\n"

section(help, title, body, opts \\ [])

@spec section(t(), String.t(), String.t(), Keyword.t()) :: t()

Create a custom help section with a given title and body.

Example

iex> alias Tux.Help
...> Help.new(color: false)
...> |> Help.section("notes", "some custom section" <> "\nand more")
...> |> to_string()
"NOTES\n" <>
"  some custom section\n" <>
"  and more"

text(help, section)

@spec text(t(), String.t()) :: t()

Append a new block of text as a new section.

title(help, string)

@spec title(t(), String.t()) :: t()

Append a title styled to the help sections.

usage(help, cmds_or_cmd_desc_pairs, opts \\ [])

@spec usage(t(), [cmd_name() | {cmd_name(), cmd_desc()}], sec_opts()) :: t()

Append the usage section, where a very short, general structure of the command is presented.

Examples

– Populate usage section via plain text

iex> Tux.Help.new(color: false)
...> |> Tux.Help.usage(["cmd [OPTS] [ARGS]"])
...> |> String.Chars.to_string()
"USAGE\n" <>
"  cmd [OPTS] [ARGS]\n"

– Populate usage section using a list of commands:

iex> Tux.Help.new(color: false)
...> |> Tux.Help.usage(["cmd1", "cmd2", "cmd3"])
...> |> String.Chars.to_string()
"USAGE\n"<>
"  cmd1\n" <>
"  cmd2\n" <>
"  cmd3\n"

– Using a list of commands with one line descriptions:

iex> Tux.Help.new(color: false)
...> |> Tux.Help.usage([
...> {"cmd1", "cmd 1 description"},
...> {"cmd2", "cmd 2 description"},
...> ])
...> |> String.Chars.to_string()
"USAGE\n" <>
"  cmd1    cmd 1 description\n" <>
"  cmd2    cmd 2 description\n"

Options for usage/3:

  • :title (string) - overwrite the default usage title with a default one
  • :hued (boolean) - a flag to colorize section body (default is true)