mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 23:02:31 +00:00
fix: Only generate stubs if has subcommands
This commit is contained in:
parent
76b9c46241
commit
6243d65463
2 changed files with 40 additions and 26 deletions
|
@ -1,6 +1,6 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use clap::{builder, Arg, ArgAction, Command, ValueHint};
|
use clap::{builder, Arg, Command, ValueHint};
|
||||||
|
|
||||||
use crate::generator::{utils, Generator};
|
use crate::generator::{utils, Generator};
|
||||||
|
|
||||||
|
@ -20,25 +20,13 @@ impl Generator for Fish {
|
||||||
.get_bin_name()
|
.get_bin_name()
|
||||||
.expect("crate::generate should have set the bin_name");
|
.expect("crate::generate should have set the bin_name");
|
||||||
|
|
||||||
// If there is any regular flags, we may have complicated cases, e.g. `git --git-dir somedir status`. Using normal
|
|
||||||
// `__fish_seen_subcommand_from` won't help us find out the real subcommand is `status`, and not `somedir`.
|
|
||||||
// However, we prefer to fallback to the old behavior when there are no regular flags. `-h` and `-v` is not
|
|
||||||
// a regular flag and it behaves like a command. E.g., `rustup --version toolchain` is not a valid command line.
|
|
||||||
let has_global_flags = cmd.get_arguments().any(|a| {
|
|
||||||
!a.is_positional()
|
|
||||||
&& !matches!(
|
|
||||||
a.get_action(),
|
|
||||||
ArgAction::Help
|
|
||||||
| ArgAction::HelpShort
|
|
||||||
| ArgAction::HelpLong
|
|
||||||
| ArgAction::Version
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
let name = escape_name(bin_name);
|
let name = escape_name(bin_name);
|
||||||
let mut needs_fn_name = &format!("__fish_{name}_needs_command")[..];
|
let mut needs_fn_name = &format!("__fish_{name}_needs_command")[..];
|
||||||
let mut using_fn_name = &format!("__fish_{name}_using_subcommand")[..];
|
let mut using_fn_name = &format!("__fish_{name}_using_subcommand")[..];
|
||||||
if has_global_flags && cmd.has_subcommands() {
|
// Given `git --git-dir somedir status`, using `__fish_seen_subcommand_from` won't help us
|
||||||
|
// find out `status` is the real subcommand, and not `somedir`. However, when there are no subcommands,
|
||||||
|
// there is no need to use our custom stubs.
|
||||||
|
if cmd.has_subcommands() {
|
||||||
gen_subcommand_helpers(&name, cmd, buf, needs_fn_name, using_fn_name);
|
gen_subcommand_helpers(&name, cmd, buf, needs_fn_name, using_fn_name);
|
||||||
} else {
|
} else {
|
||||||
needs_fn_name = "__fish_use_subcommand";
|
needs_fn_name = "__fish_use_subcommand";
|
||||||
|
|
|
@ -1,9 +1,35 @@
|
||||||
complete -c my-app -n "__fish_use_subcommand" -s h -l help -d 'Print help'
|
# Print an optspec for argparse to handle cmd's options that are independent of any subcommand.
|
||||||
complete -c my-app -n "__fish_use_subcommand" -a "foo"
|
function __fish_my_app_global_optspecs
|
||||||
complete -c my-app -n "__fish_use_subcommand" -a "bar"
|
string join \n h/help
|
||||||
complete -c my-app -n "__fish_use_subcommand" -a "help" -d 'Print this message or the help of the given subcommand(s)'
|
end
|
||||||
complete -c my-app -n "__fish_seen_subcommand_from foo" -s h -l help -d 'Print help'
|
|
||||||
complete -c my-app -n "__fish_seen_subcommand_from bar" -s h -l help -d 'Print help'
|
function __fish_my_app_needs_command
|
||||||
complete -c my-app -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from foo bar help" -f -a "foo"
|
# Figure out if the current invocation already has a command.
|
||||||
complete -c my-app -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from foo bar help" -f -a "bar"
|
set -l cmd (commandline -opc)
|
||||||
complete -c my-app -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from foo bar help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
|
set -e cmd[1]
|
||||||
|
argparse -s (__fish_my_app_global_optspecs) -- $cmd 2>/dev/null
|
||||||
|
or return
|
||||||
|
if set -q argv[1]
|
||||||
|
# Also print the command, so this can be used to figure out what it is.
|
||||||
|
echo $argv[1]
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function __fish_my_app_using_subcommand
|
||||||
|
set -l cmd (__fish_my_app_needs_command)
|
||||||
|
test -z "$cmd"
|
||||||
|
and return 1
|
||||||
|
contains -- $cmd[1] $argv
|
||||||
|
end
|
||||||
|
|
||||||
|
complete -c my-app -n "__fish_my_app_needs_command" -s h -l help -d 'Print help'
|
||||||
|
complete -c my-app -n "__fish_my_app_needs_command" -a "foo"
|
||||||
|
complete -c my-app -n "__fish_my_app_needs_command" -a "bar"
|
||||||
|
complete -c my-app -n "__fish_my_app_needs_command" -a "help" -d 'Print this message or the help of the given subcommand(s)'
|
||||||
|
complete -c my-app -n "__fish_my_app_using_subcommand foo" -s h -l help -d 'Print help'
|
||||||
|
complete -c my-app -n "__fish_my_app_using_subcommand bar" -s h -l help -d 'Print help'
|
||||||
|
complete -c my-app -n "__fish_my_app_using_subcommand help; and not __fish_seen_subcommand_from foo bar help" -f -a "foo"
|
||||||
|
complete -c my-app -n "__fish_my_app_using_subcommand help; and not __fish_seen_subcommand_from foo bar help" -f -a "bar"
|
||||||
|
complete -c my-app -n "__fish_my_app_using_subcommand help; and not __fish_seen_subcommand_from foo bar help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)'
|
||||||
|
|
Loading…
Reference in a new issue