Skip to content

Commit

Permalink
Merge pull request #5681 from epage/static
Browse files Browse the repository at this point in the history
fix(complete)!: Shuffle API up for stabilization
  • Loading branch information
epage authored Aug 16, 2024
2 parents 17d6d24 + 3c69aaa commit addec17
Show file tree
Hide file tree
Showing 20 changed files with 173 additions and 87 deletions.
6 changes: 3 additions & 3 deletions clap_complete/examples/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ fn command() -> clap::Command {
.value_parser(["json", "yaml", "toml"]),
)
.args_conflicts_with_subcommands(true);
clap_complete::dynamic::CompleteCommand::augment_subcommands(cmd)
clap_complete::CompleteCommand::augment_subcommands(cmd)
}

fn main() {
clap_complete::dynamic::CompleteEnv::with_factory(command).complete();
clap_complete::CompleteEnv::with_factory(command).complete();

let cmd = command();
let matches = cmd.get_matches();
if let Ok(completions) = clap_complete::dynamic::CompleteCommand::from_arg_matches(&matches) {
if let Ok(completions) = clap_complete::CompleteCommand::from_arg_matches(&matches) {
completions.complete(&mut command());
} else {
println!("{matches:#?}");
Expand Down
6 changes: 3 additions & 3 deletions clap_complete/examples/exhaustive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use clap_complete::{generate, Generator, Shell};

fn main() {
#[cfg(feature = "unstable-dynamic")]
clap_complete::dynamic::CompleteEnv::with_factory(cli).complete();
clap_complete::CompleteEnv::with_factory(cli).complete();

let matches = cli().get_matches();
if let Some(generator) = matches.get_one::<Shell>("generate") {
Expand All @@ -16,7 +16,7 @@ fn main() {
}

#[cfg(feature = "unstable-command")]
if let Ok(completions) = clap_complete::dynamic::CompleteCommand::from_arg_matches(&matches) {
if let Ok(completions) = clap_complete::CompleteCommand::from_arg_matches(&matches) {
completions.complete(&mut cli());
return;
};
Expand Down Expand Up @@ -199,6 +199,6 @@ fn cli() -> clap::Command {
]),
]);
#[cfg(feature = "unstable-command")]
let cli = clap_complete::dynamic::CompleteCommand::augment_subcommands(cli);
let cli = clap_complete::CompleteCommand::augment_subcommands(cli);
cli
}
File renamed without changes.
File renamed without changes.
56 changes: 56 additions & 0 deletions clap_complete/src/aot/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//! Prebuilt completions
//!
//! ## Quick Start
//!
//! - For generating at compile-time, see [`generate_to`]
//! - For generating at runtime, see [`generate`]
//!
//! [`Shell`] is a convenience `enum` for an argument value type that implements `Generator`
//! for each natively-supported shell type.
//!
//! To customize completions, see
//! - [`ValueHint`]
//! - [`ValueEnum`][clap::ValueEnum]
//!
//! ## Example
//!
//! ```rust,no_run
//! use clap::{Command, Arg, ValueHint, value_parser, ArgAction};
//! use clap_complete::{generate, Generator, Shell};
//! use std::io;
//!
//! fn build_cli() -> Command {
//! Command::new("example")
//! .arg(Arg::new("file")
//! .help("some input file")
//! .value_hint(ValueHint::AnyPath),
//! )
//! .arg(
//! Arg::new("generator")
//! .long("generate")
//! .action(ArgAction::Set)
//! .value_parser(value_parser!(Shell)),
//! )
//! }
//!
//! fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
//! generate(gen, cmd, cmd.get_name().to_string(), &mut io::stdout());
//! }
//!
//! fn main() {
//! let matches = build_cli().get_matches();
//!
//! if let Some(generator) = matches.get_one::<Shell>("generator").copied() {
//! let mut cmd = build_cli();
//! eprintln!("Generating completion file for {generator}...");
//! print_completions(generator, &mut cmd);
//! }
//! }
//! ```
mod generator;
mod shells;

pub use clap::ValueHint;
pub use generator::*;
pub use shells::*;
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ impl Generator for Bash {

let fn_name = bin_name.replace('-', "__");

w!(
write!(
buf,
format!(
"_{name}() {{
"_{name}() {{
local i cur prev opts cmd
COMPREPLY=()
cur=\"${{COMP_WORDS[COMP_CWORD]}}\"
Expand Down Expand Up @@ -66,15 +65,13 @@ else
complete -F _{name} -o bashdefault -o default {name}
fi
",
name = bin_name,
cmd = fn_name,
name_opts = all_options_for_path(cmd, bin_name),
name_opts_details = option_details_for_path(cmd, bin_name),
subcmds = all_subcommands(cmd, &fn_name),
subcmd_details = subcommand_details(cmd)
)
.as_bytes()
);
name = bin_name,
cmd = fn_name,
name_opts = all_options_for_path(cmd, bin_name),
name_opts_details = option_details_for_path(cmd, bin_name),
subcmds = all_subcommands(cmd, &fn_name),
subcmd_details = subcommand_details(cmd)
).expect("failed to write completion file");
}
}

Expand Down Expand Up @@ -274,22 +271,23 @@ fn all_options_for_path(cmd: &Command, path: &str) -> String {

let mut opts = String::new();
for short in utils::shorts_and_visible_aliases(p) {
write!(&mut opts, "-{short} ").unwrap();
write!(&mut opts, "-{short} ").expect("writing to String is infallible");
}
for long in utils::longs_and_visible_aliases(p) {
write!(&mut opts, "--{long} ").unwrap();
write!(&mut opts, "--{long} ").expect("writing to String is infallible");
}
for pos in p.get_positionals() {
if let Some(vals) = utils::possible_values(pos) {
for value in vals {
write!(&mut opts, "{} ", value.get_name()).unwrap();
write!(&mut opts, "{} ", value.get_name())
.expect("writing to String is infallible");
}
} else {
write!(&mut opts, "{pos} ").unwrap();
write!(&mut opts, "{pos} ").expect("writing to String is infallible");
}
}
for (sc, _) in utils::subcommands(p) {
write!(&mut opts, "{sc} ").unwrap();
write!(&mut opts, "{sc} ").expect("writing to String is infallible");
}
opts.pop();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ impl Generator for Elvish {

let subcommands_cases = generate_inner(cmd, "");

let result = format!(
write!(
buf,
r#"
use builtin;
use str;
Expand All @@ -46,9 +47,8 @@ set edit:completion:arg-completer[{bin_name}] = {{|@words|
$completions[$command]
}}
"#,
);

w!(buf, result.as_bytes());
)
.expect("failed to write completion file");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Generator for Fish {
needs_fn_name,
using_fn_name,
);
w!(buf, buffer.as_bytes());
write!(buf, "{buffer}").expect("failed to write completion file");
}
}

Expand Down Expand Up @@ -240,7 +240,9 @@ fn gen_subcommand_helpers(
}
}
let optspecs_fn_name = format!("__fish_{bin_name}_global_optspecs");
let template = format!("\
write!(
buf,
"\
# Print an optspec for argparse to handle cmd's options that are independent of any subcommand.\n\
function {optspecs_fn_name}\n\
\tstring join \\n{optspecs}\n\
Expand All @@ -264,8 +266,7 @@ fn gen_subcommand_helpers(
\tand return 1\n\
\tcontains -- $cmd[1] $argv\n\
end\n\n\
");
w!(buf, template.as_bytes());
").expect("failed to write completion file");
}

fn value_completion(option: &Arg) -> String {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ impl Generator for PowerShell {

let subcommands_cases = generate_inner(cmd, "");

let result = format!(
write!(
buf,
r#"
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Expand Down Expand Up @@ -51,9 +52,8 @@ Register-ArgumentCompleter -Native -CommandName '{bin_name}' -ScriptBlock {{
Sort-Object -Property ListItemText
}}
"#
);

w!(buf, result.as_bytes());
)
.expect("failed to write completion file");
}
}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ impl Generator for Zsh {
.get_bin_name()
.expect("crate::generate should have set the bin_name");

w!(
write!(
buf,
format!(
"#compdef {name}
"#compdef {name}
autoload -U is-at-least
Expand All @@ -49,13 +48,12 @@ else
compdef _{name} {name}
fi
",
name = bin_name,
initial_args = get_args_of(cmd, None),
subcommands = get_subcommands_of(cmd),
subcommand_details = subcommand_details(cmd)
)
.as_bytes()
);
name = bin_name,
initial_args = get_args_of(cmd, None),
subcommands = get_subcommands_of(cmd),
subcommand_details = subcommand_details(cmd)
)
.expect("failed to write completion file");
}
}

Expand Down Expand Up @@ -673,7 +671,7 @@ fn write_positionals_of(p: &Command) -> String {

#[cfg(test)]
mod tests {
use crate::shells::zsh::{escape_help, escape_value};
use super::{escape_help, escape_value};

#[test]
fn test_escape_value() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ pub use shells::*;

/// A completion subcommand to add to your CLI
///
/// To customize completions, see
/// - [`ValueHint`][crate::ValueHint]
/// - [`ValueEnum`][clap::ValueEnum]
/// - [`ArgValueCompleter`][crate::ArgValueCompleter]
///
/// **Warning:** `stdout` should not be written to before [`CompleteCommand::complete`] has had a
/// chance to run.
///
Expand All @@ -55,7 +60,7 @@ pub use shells::*;
/// ```no_run
/// // src/main.rs
/// use clap::{CommandFactory, FromArgMatches, Parser, Subcommand};
/// use clap_complete::dynamic::CompleteCommand;
/// use clap_complete::CompleteCommand;
///
/// #[derive(Parser, Debug)]
/// #[clap(name = "dynamic", about = "A dynamic command line tool")]
Expand Down Expand Up @@ -113,6 +118,11 @@ impl CompleteCommand {

/// A completion subcommand to add to your CLI
///
/// To customize completions, see
/// - [`ValueHint`][crate::ValueHint]
/// - [`ValueEnum`][clap::ValueEnum]
/// - [`ArgValueCompleter`][crate::ArgValueCompleter]
///
/// **Warning:** `stdout` should not be written to before [`CompleteArgs::complete`] has had a
/// chance to run.
///
Expand All @@ -122,7 +132,7 @@ impl CompleteCommand {
/// ```no_run
/// // src/main.rs
/// use clap::{CommandFactory, FromArgMatches, Parser, Subcommand};
/// use clap_complete::dynamic::CompleteArgs;
/// use clap_complete::CompleteArgs;
///
/// #[derive(Parser, Debug)]
/// #[clap(name = "dynamic", about = "A dynamic command line tool")]
Expand Down
File renamed without changes.
17 changes: 2 additions & 15 deletions clap_complete/src/dynamic/mod.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
//! Complete commands within shells
//! `clap`-native completion system
//!
//! To customize completions, see
//! - [`ValueHint`][crate::ValueHint]
//! - [`ValueEnum`][clap::ValueEnum]
//! - [`ArgValueCompleter`]
//! See [`complete()`]
mod candidate;
mod complete;
mod custom;

#[cfg(feature = "unstable-command")]
pub mod command;
pub mod env;

pub use candidate::CompletionCandidate;
pub use complete::complete;
pub use custom::ArgValueCompleter;
pub use custom::CustomCompleter;

#[cfg(feature = "unstable-command")]
pub use command::CompleteArgs;
#[cfg(feature = "unstable-command")]
pub use command::CompleteCommand;
pub use env::CompleteEnv;
Loading

0 comments on commit addec17

Please sign in to comment.