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.