Giter Site home page Giter Site logo

clap-help's Introduction

clap-help

MIT Latest Version docs Chat on Miaou

Purpose and Features

clap-help prints the --help message of clap based terminal applications.

Differences with the vanilla help renderer of the clap crate:

  • more readable, thanks to a width aware layout
  • more compact: from 2 to 3 times less lines compared to vanilla
  • options rendered in a balanced table, optimized for the width of the terminal
  • introduction interpreted as Markdown, allowing lists, tables, code blocks, etc.
  • doc of options interpreted as Markdown
  • skin automatically selected for light or dark terminals
  • customizable termimad skin
  • you can customize section templates, remove them, reorder them, add sections

Note: there's no support for subcommands yet.

Example

The bacon programs uses clap-help with an introduction text, a clearer options table, examples, and a skin consistent with the rest of the application:

bacon

How it's done: https://github.com/Canop/bacon/blob/main/src/args.rs.

Usage

Basic usage

Your program needs a clap Command defined.

Here's for example with clap-derive:

#[derive(Parser, Debug)]
#[command(name="area", author, version, about, disable_help_flag = true)]
struct Args {

    /// Print help
    #[arg(long)]
    help: bool,

    /// Height, that is the distance between bottom and top
    #[arg(short, long, default_value = "9")]
    height: u16,

    /// Width, from there, to there, eg `4` or `5`
    #[arg(short, long, default_value = "3")]
    width: u16,

    /// Kill all birds to improve computation
    #[arg(short, long)]
    kill_birds: bool,

    /// Computation strategy
    #[arg(long, default_value = "fast")]
    strategy: Strategy,

    /// Bird separator
    #[arg(short, long, value_name = "SEP")]
    separator: Option<String>,

    /// Root Directory
    pub root: Option<std::path::PathBuf>,
}

Notice

  • the disable_help_flag = true disabling the standard behaviour of clap regarding help.
  • the explicit help argument. Here it's with only #[arg(long)] because -h is used for something more important but you would most often have #[arg(short, long)].

The help introduction (the part before usage) is defined as a string which will be interpreted as Markdown. It can contain tables, lists, bold, italic, inline code, code blocks, etc.

static INTRO: &str = "

Compute `height x width`
*You can do it either precisely (enough) or fast (I mean not too slow)*.
";

On program launch, you should check the value of the help flag and, if necessary, print the help:

let args = Args::parse();
if args.help {
    Printer::new(Args::command())
        .with("introduction", INTRO)
        .without("author")
        .print_help();
    return;
}

Help rendered in a light terminal:

area light

Same help in a dark terminal:

area dark

Complete example is in /examples/area and can be seen with cargo run --example area -- --help

Adding custom sections

Help is usually easier to grasp with a few examples. You can write a few ones in your intro, or you can add them in a later section, after the options.

It's also possible to leverage the template system, which is what is done in the with-examples example, for this result:

with-examples

Here's how it's done:

static EXAMPLES_TEMPLATE: &str = "
**Examples:**

${examples
**${example-number})** ${example-title}: `${example-cmd}`
${example-comments}
}
";
let mut printer = clap_help::Printer::new(Args::command())
    .with("introduction", INTRO_TEMPLATE)
    .without("author");
printer.template_keys_mut().push("examples");
printer.set_template("examples", EXAMPLES_TEMPLATE);
for (i, example) in EXAMPLES.iter().enumerate() {
    printer
        .expander_mut()
        .sub("examples")
        .set("example-number", i + 1)
        .set("example-title", example.title)
        .set("example-cmd", example.cmd)
        .set_md("example-comments", example.comments);
}
printer.print_help();

complete code of the example

Changing the skin

If your program has some kind of graphical identity, you may want to extend it to the help.

You may change colors, preferably with more compatible ansi color codes.

See example in examples/custom mainly features:

custom

The strategy for those changes is

  • to redefine the bold, italic, and inline_code styles to change their foreground color, to remove the background of the code, and to remove the Italic attribute of italic
  • to use the TEMPLATE_OPTIONS_MERGED_VALUE template for options

Here are the relevant parts of the code:

static INTRO: &str = "

Compute `height x width`
More info at *https://dystroy.org*
";

let mut printer = Printer::new(Args::command())
    .without("author")
    .with("introduction", INTRO)
    .with("options", clap_help::TEMPLATE_OPTIONS_MERGED_VALUE);
let skin = printer.skin_mut();
skin.headers[0].compound_style.set_fg(ansi(202));
skin.bold.set_fg(ansi(202));
skin.italic = termimad::CompoundStyle::with_fg(ansi(45));
skin.inline_code = termimad::CompoundStyle::with_fg(ansi(223));
skin.table_border_chars = termimad::ROUNDED_TABLE_BORDER_CHARS;
printer.print_help();

Complete example is in /examples/custom and can be seen with cargo run --example custom -- --help

Please note that not every customization is possible or easy. And some may be easy but not obvious. Come to the chat and ask if needed.

clap-help's People

Contributors

canop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

clap-help's Issues

Support subcommands

From readme:

Note: there's no support for subcommands, create an issue if you need it.

So, here we go, creaing an issue :)

This is a very valuable crate since clap v4 has degraded help screen aesthetics compared to v3. Thanks for publishing!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.