Repository navigation
feat: allow unambiguous command shorthands - #649
Conversation
Allow invoking StGit commands, aliases, and subcommands using any unambiguous prefix (for example, `stg del` for `stg delete`, `stg ser` for `stg series`, or `stg em s` for `stg email send`), matching StGit 1.x behavior. Enable `infer_subcommands(true)` on the base clap Command so clap accepts unambiguous prefixes for top-level and nested subcommands. Because the initial bootstrap CLI parser uses `allow_external_subcommands(true)` to avoid constructing the full command graph up front, also resolve subcommand prefixes across built-in commands, `help`, and configured aliases: - Exact matches on built-in commands, `help`, or aliases always take precedence over prefix matches. - Non-exact prefixes are checked against built-in commands, `help`, and aliases together so that a prefix shared between a built-in command and an alias (such as `res` for `reset` and `resolved`) is rejected as ambiguous. Signed-off-by: Dmitry Torokhov <dtor@google.com>
59d75c2 to
60bee49
Compare
Whether a prefix is unambiguous depends on the set of commands and aliases, so defining an alias or upgrading StGit can silently break an abbreviation that previously worked, and the result can differ between repositories with different local aliases. Users who accept that tradeoff can enable stgit.infer-commands; everyone else keeps the exact-match behavior of StGit 2.x. The config is only read on the fast path when the matched command has nested subcommands, so plain command dispatch stays cheap.
An alias stored in config that relies on a command prefix breaks as soon as another command or alias sharing that prefix appears, far from where the alias was defined. Requiring the exact command name keeps configured aliases stable regardless of stgit.infer-commands. Nested subcommands are still inferred when enabled since they may come from the user's arguments rather than the alias definition.
The flag-style subcommands of stg branch looked like long options, so stg branch --l listed branches even though real long options are never abbreviated. Clap's subcommand inference is a global setting that cannot be enabled for the top-level command alone, so an inferred top-level name is now spelled out in argv before clap sees it. Inference is then only enabled for commands whose nested subcommands do not start with a hyphen. Spelling out an inferred "help" the same way means the full-help fallback never needs inference.
|
Thanks for this PR, @dtor. And sorry for the delayed response. Dropping command prefixes in 2.0 was a deliberate choice (see #240 and #462). The main reason is that whether a prefix is unambiguous depends on which commands and aliases exist. Defining an alias, or upgrading StGit, can quietly break an abbreviation someone relies on, and the same prefix can behave differently between repos that define different aliases. So I don't want to merge this as-is. I would accept prefix support with the following changes, which I've already implemented and tested on top of your commit:
Does this work for your use case? If you're good with it, I'll push these commits to this PR. |
|
Yes, thatworks for me. Frankly, I have muscle memory for "stg ref", "stg res", and "stg del" and that is pretty much it. Thanks! |
|
Thanks, @dtor. One heads-up: You can use an explicit alias though: I'll push the commits to this PR. |
Allow invoking StGit commands, aliases, and subcommands using any unambiguous prefix (for example,
stg delforstg delete,stg serforstg series, orstg em sforstg email send), matching StGit 1.x behavior.Enable
infer_subcommands(true)on the base clap Command so clap accepts unambiguous prefixes for top-level and nested subcommands. Because the initial bootstrap CLI parser usesallow_external_subcommands(true)to avoid constructing the full command graph up front, also resolve subcommand prefixes across built-in commands,help, and configured aliases:help, or aliases always take precedence over prefix matches.help, and aliases together so that a prefix shared between a built-in command and an alias (such asresforresetandresolved) is rejected as ambiguous.