Repository navigation
Releases: jdx/usage
Release list
v7.1.2: Completion scripts treat candidates as plain text; mounted commands stop inheriting top-level completers
Generated bash, zsh and fish completion scripts no longer expand completion candidates or file extensions as shell code. Mounted commands also stop picking up the mounting spec's top-level completers. The first fix matters for tools like mise, where candidates can come from project files. Regenerate any completion files you've installed to get the script fixes.
Fixed
- (complete) Completion candidates and extension filters are now handled as plain text in every shell (#1581, @jdx):
- bash:
usage generate completion bashused to pass candidates throughcompgen -W, which expands them as shell input. Arun=completer that printed$(touch pwned)ran that command when you pressed Tab, and a*candidate turned into the files in the current directory. Thecompletion-inithandler had the same globbing problem. Both now read one candidate per line without expanding it, so a candidate that contains a space stays one entry instead of splitting in two. - zsh: extension names were inserted directly into the
_files -gpattern, and zsh runs glob qualifiers as code. The pattern is now built only from plain extension names (letters, digits,_ . + -). If no usable names are left, completion falls back to unfiltered_files. This also fixes a single extension, which produced*.(toml)and matched nothing. It now produces*.toml. - fish: extensions are matched as a literal suffix, so a
*or?in an extension no longer matches extra files.
- bash:
Changed
- (complete) A command brought in by
mountnow uses only the completers it declares itself, in its owncompletenodes or inside itsargnodes (#1581, @jdx). Before, a mounted argument that shared a name with a top-level completer (for example<tool>) used the mounting spec's completer, even when the mounted command declared its own. If you type one of the mounting CLI's flags inside a mounted command, its value still completes the same way it does outside the mount. Specs without mounts are unaffected. If a mounted command relied on a top-level completer, declare it in the spec that the mount emits instead, for example withcomplete "tool" run="..."inside thecmd.
Full Changelog: v7.1.1...v7.1.2
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v7.1.1: Fix nushell 0.116 deprecation warning in generated completions
Nushell completion scripts generated by usage-argv and the Go runtime no longer print a deprecation warning on nushell 0.116.
Fixed
- (complete) Nushell 0.116 deprecated external completers that take a positional
spansargument, so the generated script printed anu::shell::deprecatedwarning every time it completed (#1570, @jdx). The completer now uses the{|place|}signature. On 0.116 it reads the tokens from$place.command, and on older nushell releases, which pass the token list directly, it uses that list. If you already had an external completer installed, it still gets called, and it receives the input in the format it expects: the token list for completers written withspans, the original input for everything else. If you saved the script to a file, regenerate it to pick up the fix.
Full Changelog: v7.1.0...v7.1.1
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v7.1.0: Effect v4 CLI exporter and bash completion escaping
This release adds usage-spec-effect, a new npm package that turns Effect v4 effect/cli command trees into usage specs. It also fixes bash completions from usage-argv, which could pass the command a different value than the one offered when a candidate contained quotes, spaces or other shell syntax.
Added
-
(spec)
usage-spec-effectexports a usage spec from an Effect v4effect/clicommand tree (#1564, @jdx). Effect still parses and runs the CLI, and the spec drives shell completions, markdown docs and man pages. It requireseffect4.x.npm install usage-spec-effect
import { generate } from "usage-spec-effect"; if (process.argv.includes("--usage-spec")) { process.stdout.write(generate(app, { version: "1.0.0" })); process.exit(0); }
mycli --usage-spec | usage generate completion bash mycli --file -The exporter handles nested subcommands, aliases, unlisted commands, examples, shared flags (exported as
global), flag aliases, boolean and valued flags, choices, defaults, and optional and variadic args. Some constructs can only be exported approximately:orElsealternatives, file, redacted and key-value types (exported as strings), non-primitive defaults, and flags with an optional value.generateWithReportreturns these in anunsupportedlist so they aren't dropped without notice. Effect's publicCommandtype doesn't expose flags or arguments, so the exporter reads the command's runtime config. If a future Effect release changes that shape,generatethrows an error that names the command. See the Effect integration guide.
Fixed
- (bash)
usage-argvandusage-dynamicnow escape bash completion candidates so the command gets the value that was offered (#1566, @jdx). Before this fix, Readline put candidates on the line unescaped, so a candidate liketasks."hello.sh"reached the command astasks.hello.sh, andit's hereleft an unclosed quote on the line. Candidates are now backslash-escaped. When a quote is already open in the word (',"or$'), each candidate is escaped for that quote style instead. Path completions still use Readline's own filename quoting, and zsh and fish were already correct. Hosts handling__complete_word__should callrender_request(&answer, &request)instead ofrender(&answer, shell)so the open-quote state is used.App::completion_requestinusage-dynamicalready does this. The script-based bash completions behindusage complete-wordare unchanged, sincecompgen -Wcan't carry spaces or quotes in candidates.
Full Changelog: v7.0.2...v7.1.0
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v7.0.2: Completion honors .usage.kdl sidecars and shows help for short flags
Two completion fixes: completing a script now uses the same .<script>.usage.kdl sidecar spec that usage exec runs with, and short flags show their help text in completion menus.
Fixed
- (complete)
usage complete-word -f <script>now reads a.<script>.usage.kdlfile next to the script before falling back to itsUSAGEcomments, the same lookupusage execalready did (#1558, @jdx). Before this, a script with a sidecar completed against the comment spec, or against nothing at all. The bash, zsh and fish scripts fromusage generate completion-initcallcomplete-word, so they get the fix without being regenerated. Otherusage generatesubcommands that take-f <script>, such ascompletionandmarkdown, now prefer the sidecar too. When the sidecar doesn't setnameorbin, the script's basename is used. Inline specs and stdin input work as before. - (complete) Short flags now show their help text in completion menus, as long flags already did (#1561, @Ehsan-hash). For
flag "-v --verbose" help="Verbose output", completing-vused to show no description and now showsVerbose output. If a root command and a subcommand both define the same short flag, the menu shows the help for the flag that actually applies. Bash completions still list flag names only, with no descriptions.
New Contributors
- @Ehsan-hash made their first contribution in #1561
Full Changelog: v7.0.1...v7.0.2
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v7.0.1: Smaller usage-argv help, completion and error rendering code
This release reduces how much code usage-argv adds to CLIs that embed it. Help, -h, version, completion and parse-error output stay byte-for-byte the same, and startup and parse speed are unchanged.
Changed
- (lib) Help, completion and error rendering in
usage-argvproduce less machine code (#1551, #1553, #1554, @jdx). String appends, text wrapping, slicing, searching, completion splitting and error suggestions now go through shared helpers instead of being expanded at every call site. In stripped release builds of oxlint and oxfmt, the three PRs together removed about 85 KB from each binary. That covers most of the size those CLIs gained when they moved from bpaf tousage-rs.
Fixed
- (complete)
Split::walkedandSplit::argvno longer panic whencwordis out of range. They now return the whole word list and an empty slice (#1554, @jdx).
Full Changelog: v7.0.0...v7.0.1
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v7.0.0: Derive macros no longer read Cargo.toml; `usage generate fig` removed
The derive macros now generate code against usage_rs directly instead of reading your Cargo.toml, usage generate fig has been removed, and the fields on argv metadata types are no longer public API. usage exec now accepts interpreter arguments, and this release also fixes how -- is handled by the shell runners and how multi-line examples are indented in help.
Breaking Changes
All of these come from #1532 (@jdx).
- The derive macros always generate paths through
::usage_rs. In 6.12,usage-deriveparsed yourCargo.tomlto work out howusage-rswas imported. That puttomland related crates into every downstream build. The macros no longer read the manifest, sotomlis out of the dependency tree. If a derive can't find the facade crate, compilation fails withunresolved import usage_rs. To upgrade:- Depend on
usage-rsunder its own name:usage-rs = { version = "7" }. - If you import it under another name, such as
usage = { package = "usage-rs", ... }, add#[usage(crate = usage)]to each derive that needs it. The attribute works onCli,Args,Subcommands,ValueEnum,ArgGroupandConfig, and you have to repeat it on every derive.#[derive(usage::Cli)] #[usage(crate = usage, bin = "ex")] struct Ex { /* ... */ }
- If you depend directly on
usage-argv,usage-derive,usage-configorusage-validation, also addusage-rs = { version = "7", default-features = false, features = ["spec"] }. Turn on theconfigorvalidationfeatures if you use those crates, since they're now reached throughusage_rs::configandusage_rs::validation. schema_from = Tnow always generates::schemars. If you renamed theschemarsdependency, change it back to its real name.- The derives no longer look up workspace-inherited or target-specific dependencies.
- Depend on
usage generate figis removed. Fig shut down in 2024. Useusage generate completion <shell>instead.- Fields on
FlagMeta,CommandMetaandArgMetainusage-argvare now#[doc(hidden)]. Their struct layout is no longer covered by semver. Use the existing accessor methods instead, for exampleflag.env_fallback()rather thanflag.env_fallback.
Added
- (cli)
usage exectakes a quoted interpreter followed by its own arguments, and splits them the way a shell would (#1537, @jdx). Before this, there was no shebang form for interpreters that need flags before the script path, such as Deno'srunand its permission flags. Values without whitespace, values that are paths to existing files, and the unquoted form all work as before.#!/usr/bin/env -S usage exec "deno run --allow-env=usage_*" //USAGE arg "<name>" help="Name to greet"
Fixed
- (cli) In
usage bash,zsh,fishandpowershell, words after--now reach the script as values (#1541, @jdx). Previously,usage bash script.sh positional -- --helpprinted the script's help with anError:prefix and exited with status 1.-hand--helpstill show help when they come before--. - (cli) In
--helpoutput, every line of a multi-lineexampleis now indented (#1548, @jdx). Before, sample output lines after the first started at column 0.
Full Changelog: v6.12.1...v7.0.0
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v6.12.1: Test suite passes with each optional feature enabled on its own
This release doesn't change runtime behavior or public APIs. It matters mainly to downstream packagers who test each optional feature of the crates separately.
Fixed
- (lib) The test suites now pass when an optional feature is enabled on its own (#1513, @jdx). Four configurations used to fail even though the all-features tests passed:
usage-argvwith onlycomplete, onlydiagnosticsor onlyspec, andusage-rswith onlytest. CI now tests each of these separately. This brings in the two test patches from Debian's packaging (debcargo-conf MR !1447), which packagers can drop starting with this release.
Full Changelog: v6.12.0...v6.12.1
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v6.12.0: Delegated shell completion, command-backed choices, and usage_cmd for scripts
Wrapper CLIs can now pass completion of their trailing words to the wrapped tool's own shell completion. Argument values can come from a command's output with choices run=, and scripts get the chosen subcommand as $usage_cmd. The release also fixes several completion bugs in bash, zsh and fish, and two crashes in #[derive(Cli)] binaries.
Added
-
(complete)
complete … delegate="<command>"completes a wrapped command's arguments with that command's own shell completion (#1498, @jdx). With the spec below,wrapper layer1 plan -o<Tab>offers whateverterraform plan -o<Tab>would.delegatecan carry fixed arguments (delegate="kubectl --context prod"), and it can't be combined withrunortype. It works in fish, bash (requires bash-completion) and zsh. PowerShell and Nushell get no delegated candidates. Typed words are passed to the shell as arguments, not spliced into a script, so they are never run. If the shell can't answer within 3 seconds, completion falls back to files. Fig output leaves delegated args bare.arg "<layer>" arg "<command>" var=#true complete "command" delegate="terraform"
-
(spec)
choices run="…"builds an argument's or flag's allowed values from a command that prints one value per line (#1497, @jdx). These values are used to check input (strictandignore_casestill apply), for Tab completion, and in--helphandled by the parser,usage bashandusage exec. Any values written on the node are kept alongside them. Static outputs never run the command.render_help, Markdown and man pages describe it asoutput of `…`, Fig emits a generator, and Go tables and TypeScript/Python SDK types treat the value as an open string. During a parse, the command runs at most once and only when a declared value doesn't match.Parser::with_envvalues are passed to it. New library API includesSpecChoices::run,resolved_values(env),SpecArgBuilder::choices_run,usage::docs::cli::render_runtime_helpandusage::sh::sh_with_env. Fig generator commands, from bothchoices run=andcomplete run=, now escape backslashes, backticks and${.arg "<service>" { choices run="docker compose config --services" }
-
(spec) A
completenode can now sit inside theargit completes, including a flag'sarg, or directly inside a flag as shorthand for its value (#1496, @jdx). The inline form takesrun,typeanddescriptionsbut no name. It takes precedence over a namedcomplete "<name>"for the same arg. The newSpec::completer(cmd, arg)applies this order, andcomplete-word, Fig, usage-dynamic and the Go generator all follow it.flag "--out <path>" { complete type="dir" }
-
(lib) Scripts run by
usage bash,zsh,fish,powershellandexecget the chosen subcommand's canonical name inusage_cmd, with nested names joined by spaces, such as"db migrate"(#1505, @jdx). It is unset at the top level, and ausage_cmdinherited from a parent process is cleared. If the spec declares its own flag or arg namedcmd, that one keeps the variable. The value comes fromParseOutput::as_env, so other embedders such as mise tasks get it too. -
(lib)
FlagMeta,CommandMetaandArgMetainusage-rs/usage-argvhave aconst fngetter for every field, including the fields that 6.11.1 moved intoextra(#1491, @jdx). For example,flag.env_fallback()works however the struct is laid out. The fields stay public for now, but v7 plans to hide them, so switch to the getters. -
(lib)
Parser::without_running_commands()parses without starting anychoices run=command (#1503, @jdx). A value outside the declared choices is accepted unchecked.usage explainnow uses this mode, so explaining a command line against an untrusted spec never runs that spec's commands. -
(cli) Releases now ship a version-matched
usageagent skill for writing specs, parsing script arguments, usingusage explain, and generating completions and docs (#1509, @jdx). mise users can install it withmise use usageand thenmise skills sync --dir .agents/skills.
Fixed
- (derive) A generated
Cli::parse()no longer panics when output goes to a closed pipe, for example withmycli --help | head -1or a cancelled completion (#1484, @jdx). Before,panic = "abort"builds aborted with SIGABRT. Exit statuses are unchanged. - (derive) Async dispatch generated by
#[usage(run_async)]andrun_async_withnow boxes the selected command's future (#1488, @jdx). Before, debug builds reserved stack for every command's future at each dispatch level, which could overflow the stack in large CLIs (for example,STATUS_STACK_OVERFLOWon Windows). This costs one heap allocation per dispatch level. The API is unchanged. - (derive) A renamed
usage-rsdependency inherited from[workspace.dependencies]now resolves even when an earlier entry uses a multi-line inline table (#1507, @jdx). The derive now reads manifests with a real TOML parser. - (complete) Typed completers (
#[usage(complete = my_fn)]) now receive the command line when called through a spec'srun=(#1487, @jdx).CompletionRequest::parseused to ignore--line=…and now accepts--option=valuefor every option that takes a value. - (complete) A command line that doesn't parse no longer prints an error over the prompt when you press Tab (#1495, @jdx). zsh shows the message below the prompt with
_message. bash, fish and Nushell discard it. - (bash) Values for
--flag=valuenow complete when the cursor is after the=, in both per-binary scripts and thecompletion-inithandler (#1499, @jdx). - (fish) Words you've started quoting or escaping now complete:
'prod<Tab>finds'prod env'(#1500, @jdx). Text after the cursor is no longer sent. Multi-line help no longer shows up as extra fake candidates in fish, zsh, Nushell or PowerShell. - (zsh) With
completion-init zshsourced, file completion for commands that aren't usage scripts works normally again, including in cases likeemacs --<Tab>that used to insert a literal*(#1493, @jdx). The fix applies from the next shell start. - (cli)
usage bash <(…),/dev/stdinand other pipe or FIFO script paths used to run an empty script and exit 0. usage now copies the script to a private temp directory first, for bash, zsh, fish and PowerShell (#1494, @jdx). - (lib) The published
usage-rscrate's tests now pass on their own, so downstream packagers such as Debian can test the released source (#1510, @jdx).
Changed
- All crates now use the Rust 2024 edition, and the minimum supported Rust version stays at 1.91 (#1511, @jdx). Public macros accept 2024 expression syntax such as
var_min = const { 1 }. Generated shadow crates rename reserved field names such as--gentogen_.
Upgrading
Regenerate completion scripts made with usage generate completion <shell> <bin> to get the fixes from #1495 (all shells), #1499 (bash) and #1500 (fish). If you use completion-init, just start a new shell.
Full Changelog: v6.11.1...v6.12.0
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v6.11.1: Smaller usage-argv footprint in derived CLIs, and coloured help stops styling look-alike prose
The help, completion, parse-error and metadata code that usage-argv adds to a #[derive(Cli)] binary is substantially smaller, with byte-identical output, and coloured help pages no longer colour author text that happens to look like a heading or a flag row.
Fixed
- (help) Coloured help colours only the structure the renderer itself writes (#1480, @jdx). Colour used to be applied by matching every finished line against the page's headings, synopsis and row usages, so a line reading
Flags:inafter_help/before_help/about, or heading prose that began with a flag's spelling such as-f, --force overrides the *lock*, came out styled as a heading or a flag row. Headings, the synopsis, row usages and command names are now coloured as they are written, and the remaining pass over the page applies only Markdown emphasis (**bold**,*italic*,`code`,~~strike~~), still skipping$example lines. Plain (non-TTY) output was never affected and is unchanged.
Changed
-
(argv) Less code and static data per derived CLI (#1469, #1471, #1476, #1475, #1477, #1478, @jdx). Help rows for
-hand--helpgo through one renderer, coloured-help structure is collected while the page is written instead of by a second metadata walk, the__complete_word__handler and the value-binding/error-exit code that the derive used to expand into every CLI now live in the runtime, the parse-error renderer builds messages from data instead of per-error formatting code, and cold-path lists (help rows, completion candidates, "did you mean" suggestions) share one stable sort instead of six monomorphised quicksorts. View-related branches fold away entirely for CLIs that declare no views. Help, error, spec and completion output was compared byte for byte before and after each change and is identical; a completion request now also walks the command line once instead of twice. -
(argv) Smaller metadata tables (#1470, #1472, #1474, @jdx). Rarely declared flag fields (relations, deprecation, validation, bounds, hidden aliases, spec-only metadata) moved into
FlagExtrabehindFlagMeta::extra, and rarely declared command fields (deprecation, help prose, examples, headings, outputs, layout settings, clause, exit codes) intoCommandExtrabehindCommandMeta::extra; every flag or command that declares none of them points at one shared static. Clauses are stored by reference anddisplay_order, variadic bounds and terminal widths are narrowed tou32/u16. AFlagMetashrinks from 664 to 168 bytes and aCommandMetafrom about 600 to 472. Declared values too large for the narrower types now saturate rather than wrap (adisplay_orderaboveu32::MAXsorts last;term_width = 0still disables wrapping).Measured on oxlint and oxfmt with their release profile (opt-level 3, fat LTO, one codegen unit, linux x86_64), the first two changes alone cut what usage-rs adds over bpaf from about 219 KB to 138 KB for oxlint (from 169 KB to 114 KB for oxfmt), and each of the remaining changes took a further 1 to 14 KB off.
Breaking Changes
Only code that reads or hand-writes usage-argv metadata tables directly is affected; CLIs built with #[derive(Cli)], Args or ArgGroup need no changes.
-
Fields moved off
FlagMetaandCommandMetaare reached throughextra(#1470, #1472):// before if let Some(reason) = meta.deprecated { /* … */ } // after if let Some(reason) = meta.extra.deprecated { /* … */ } // hand-written table static META: CommandMeta = CommandMeta { cmd: &CMD, about: Some("…"), extra: &CommandExtra { deprecated: Some("use `new`"), ..CommandExtra::EMPTY }, ..CommandMeta::EMPTY };
..FlagMeta::EMPTYand..CommandMeta::EMPTYalready point at the sharedNO_FLAG_EXTRA/NO_COMMAND_EXTRA, so entries with no extras keep working unchanged. -
Command::clauseis nowOption<&Clause>andCommandMeta::clause(now underextra) isOption<&ClauseMeta>, so hand-written tables borrow the clause:clause: Some(&TASKS).display_order,var_min/var_maxandvalue_var_min/value_var_maxareOption<u32>, andterm_width/max_term_widthareOption<u16>; integer literals need no change, but code that read them asusizeneeds a conversion (#1474).Event::ClauseSeparatorstill carries theClauseby value.
Full Changelog: v6.11.0...v6.11.1
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.
v6.11.0: Help pages fill the terminal width and can carry a logo; default subcommands on empty invocations
Help output now wraps to the real terminal width instead of a fixed 80 columns, a spec can put ASCII art on its root help page, and default_subcommand_on_empty routes a bare invocation to the default subcommand.
Added
-
(parse)
default_subcommand_on_emptyselects the default subcommand on an empty invocation (#1458, @zeitlinger). Until nowdefault_subcommandonly fired on an unmatched word, soexwith no arguments stayed on the root. With this opt-in (Rust:#[usage(default_subcommand = "run", default_subcommand_on_empty)]), a bareexor one carrying only parent/global flags such asex --verboseparses asex run, with child env values and defaults bound afterwards and the child validated exactly as if it had been named. Explicit commands, positional values, a syntactic--,--help,--version, and parse errors keep their normal precedence; root requirements still apply unlesssubcommand_negates_reqsis set. It requiresdefault_subcommand(usage lintreportsinvalid-default-subcommand-on-emptyotherwise) and is implemented in the Rust library,usage-argv, generated Go parsers, and the Go runtime.default_subcommand "run" default_subcommand_on_empty #true cmd "run" { arg "[path]" }
-
(spec)
logoputs art on the root help page (#1455, @jdx). The optionalstyleproperty takes the same+-combined vocabulary ashelp_template(for example"cyan+bold") and is validated when the spec is parsed, or at compile time for#[usage(logo = include_str!("logo.txt"), logo_style = "cyan+bold")]. Placement depends on terminal width: beside the page when at least 50 columns remain after the art and a two-column gutter, above it as a banner when they do not, and omitted entirely when the terminal is narrower than the art. The logo appears only on the root's-h/--help, never on subcommand pages or in generated Markdown, man pages, or SDKs, and plain (non-TTY) output strips its escapes.usage --helpitself now shows the project's logo. The Rust library,usage-argv, and Go renderers share one placement rule.logo #""" /\ / \ /____\ """# style="cyan+bold"
Fixed
- (help) Help is laid out at the terminal's actual width (#1454, @jdx). Width came only from
COLUMNS, which almost no process has set, so nearly every CLI built on usage wrapped at 80 columns regardless of the window. The renderers now probe the terminal (TIOCGWINSZon unix, the console buffer on Windows) whenCOLUMNSis unset; output to a pipe or file still uses 80, and a declaredterm_width/max_term_widthstill wins. The probe is exposed asusage_argv::tty::columns(). The Go renderer still uses a fixed 80 columns. - (help)
Cli::render_helpnow colours its output by the same rule asparse(): ANSI on a terminal, plain elsewhere,NO_COLORrespected (#1454). CLIs that handledusage::Error::Helpthemselves were getting a monochrome page. Callers that keep the text rather than printing it can use the newCli::render_help_styled(cmd, long, Style::PLAIN)to guarantee escape-free output; see Breaking Changes. - (help) Examples are separated by a blank line on both
-hand--help, in all three renderers, instead of running together as a single block (#1454). - (cli) The published
usage-clicrate now includessrc/cli/logo.txt, which the initial 6.11.0 publish was missing and failed on (#1459, @jdx).
Breaking Changes
Cli::render_help(the derive-generated method) may now return ANSI escape sequences when stdout is a terminal. Code that writes its result to a file, compares it in a snapshot, or embeds it in a document should switch toCli::render_help_styled(cmd, long, Style::PLAIN); settingNO_COLORalso forces plain output with no code change.usage_argv::help::renderis unchanged and still plain.- Help pages rendered to a terminal now wrap at the detected width rather than 80 columns. Redirected output and specs that declare
term_widthare unaffected.
Full Changelog: v6.10.0...v6.11.0
💚 Sponsor usage
usage is built and maintained by @jdx, an open source developer at entire.io, the title sponsor of his open source work.
If usage powers CLI specs, docs, or completions for a tool you maintain or use, please consider becoming an individual or company sponsor. Your support funds ongoing development and helps keep usage fast, free, and independent.