Skip to content

Help and Style

clish generates help text automatically from your command and parameter metadata. This page shows you what the help looks like, how to trigger it, and how to customize the appearance.

Triggering help

Every clish app supports these flags at the application level:

Flag What it does
-h Short help: app name, version, description, and command listing
--help Long help: same as -h plus the long details field if set
--version or -V App name and version
--verbose --version Name, version, description, and target platform

You can also get per-command help:

myapp deploy --help
myapp --help deploy

Both forms work. The command help shows the usage line, arguments, options, and flags with all their metadata.

Example help output

Application-level help looks like this:

myapp 0.1.0
The most elegant CLI framework for Rust

Commands:
  deploy   Deploy the application
  serve    Start the development server
  build    Build the release artifact

Run 'myapp <command> --help' for more information.

Per-command help looks like this:

myapp deploy
Deploy the application

Usage: myapp deploy <HOST> [--port <PORT>] [-l <LEVEL>] [-v]

Arguments:
  <HOST>        Target host  [env: DEPLOY_HOST]

Options:
  -p, --port <PORT>    Port number  [default: 8080]
  -l, --level <LEVEL>  Log level  [choices: debug, info, error]
  -v, --verbose        Verbose output
  -q, --quiet          Suppress output

App metadata

The app!() macro reads CARGO_PKG_NAME, CARGO_PKG_VERSION, and CARGO_PKG_DESCRIPTION from your Cargo.toml at compile time. If CARGO_PKG_DESCRIPTION is not set, it defaults to an empty string. You can override any of these with builder methods:

app!()
    .name("myapp")
    .version("1.2.0")
    .description("Does things.")
    .details("A longer description shown only on --help.")
    .run();

The details field is only shown when the user runs --help, not -h.

Styling

All help text and error output is styled through the AppStyles struct. Each field controls the appearance of a different element. You can use either farben markup strings or anstyle::Style values.

Quick customization

The fastest way to change the look is to override a few fields and use defaults for the rest:

use clish::prelude::*;
use clish::help::{AppStyles, AppStyle};

app!()
    .styles(AppStyles {
        header: AppStyle::Markup("[bold cyan underline]"),
        command: AppStyle::Markup("[bold cyan]"),
        ..Default::default()
    })
    .run();

Using anstyle

If your project already uses anstyle, you can pass anstyle::Style values directly:

use anstyle::{Style, AnsiColor};

app!()
    .styles(AppStyles {
        header: AppStyle::Anstyle(Style::new().fg_color(Some(AnsiColor::Cyan.into()))),
        command: AppStyle::Anstyle(Style::new().bold()),
        ..Default::default()
    })
    .run();

What each field controls

Here is a quick overview of the style fields. The full reference with defaults is in the Cookbook styling page.

Field What it styles
header Section headings like "Commands:", "Arguments:", "Options:"
brand App name and version on --help and --version
command Command and parameter names in listings
command_header Header in per-command help
usage Usage line content
aliases Aliases list in command help
dim Secondary info like defaults, env vars, and choices
deprecated Deprecated command names and banners
error_label The "error" prefix
error_token Problematic tokens in error messages
error_pipes Source line and pipes in error display
error_highlight Caret highlighting in errors
hint Hint messages like "run 'myapp --help'"

Error output

When something goes wrong, clish prints a structured error to stderr:

error: unknown command 'deplyo'
  |
1 | myapp deplyo
  |        ^^^^^^
  |
  = hint: run 'myapp --help' for available commands
error: missing required argument <target>
  |
1 | myapp deploy
  |             ^
  |
  = hint: run 'myapp deploy --help' for more information

Errors are styled using the same AppStyles fields, so your custom colors and formatting apply to errors too.

Custom error handling

Your command function can return Result<(), String> to produce custom errors:

#[command]
fn deploy(target: Pos<String>) -> Result<(), String> {
    if target.0.is_empty() {
        return Err("target cannot be empty".to_string());
    }
    // ... command logic
    Ok(())
}

The error string is printed using the standard error formatting pipeline, so your custom styles apply.

Next step

Curious about how it all works under the hood? Read about the Architecture -- the three-crate design, the parsing pipeline, and the inventory system. Or skip straight to the Cookbook for reference tables.