From f374830df4968806e5c85facb289a81f30495506 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 9 Aug 2024 14:31:57 -0500 Subject: [PATCH] feat(complete): Add CompleteArgs::complete --- clap_complete/src/dynamic/shells/mod.rs | 68 +++++++++++++++---------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/clap_complete/src/dynamic/shells/mod.rs b/clap_complete/src/dynamic/shells/mod.rs index 82d18fef..dda1973b 100644 --- a/clap_complete/src/dynamic/shells/mod.rs +++ b/clap_complete/src/dynamic/shells/mod.rs @@ -111,33 +111,7 @@ impl CompleteCommand { pub fn try_complete(&self, cmd: &mut clap::Command) -> clap::error::Result<()> { debug!("CompleteCommand::try_complete: {self:?}"); let CompleteCommand::Complete(args) = self; - if let Some(out_path) = args.register.as_deref() { - let mut buf = Vec::new(); - let name = cmd.get_name(); - let bin = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name()); - args.shell.write_registration(name, bin, bin, &mut buf)?; - if out_path == std::path::Path::new("-") { - std::io::stdout().write_all(&buf)?; - } else if out_path.is_dir() { - let out_path = out_path.join(args.shell.file_name(name)); - std::fs::write(out_path, buf)?; - } else { - std::fs::write(out_path, buf)?; - } - } else { - let current_dir = std::env::current_dir().ok(); - - let mut buf = Vec::new(); - args.shell.write_complete( - cmd, - args.comp_words.clone(), - current_dir.as_deref(), - &mut buf, - )?; - std::io::stdout().write_all(&buf)?; - } - - Ok(()) + args.try_complete(cmd) } } @@ -161,6 +135,46 @@ pub struct CompleteArgs { comp_words: Vec, } +impl CompleteArgs { + /// Process the completion request + pub fn complete(&self, cmd: &mut clap::Command) -> std::convert::Infallible { + self.try_complete(cmd).unwrap_or_else(|e| e.exit()); + std::process::exit(0) + } + + /// Process the completion request + pub fn try_complete(&self, cmd: &mut clap::Command) -> clap::error::Result<()> { + debug!("CompleteCommand::try_complete: {self:?}"); + if let Some(out_path) = self.register.as_deref() { + let mut buf = Vec::new(); + let name = cmd.get_name(); + let bin = cmd.get_bin_name().unwrap_or_else(|| cmd.get_name()); + self.shell.write_registration(name, bin, bin, &mut buf)?; + if out_path == std::path::Path::new("-") { + std::io::stdout().write_all(&buf)?; + } else if out_path.is_dir() { + let out_path = out_path.join(self.shell.file_name(name)); + std::fs::write(out_path, buf)?; + } else { + std::fs::write(out_path, buf)?; + } + } else { + let current_dir = std::env::current_dir().ok(); + + let mut buf = Vec::new(); + self.shell.write_complete( + cmd, + self.comp_words.clone(), + current_dir.as_deref(), + &mut buf, + )?; + std::io::stdout().write_all(&buf)?; + } + + Ok(()) + } +} + /// Shell-specific completions pub trait ShellCompleter { /// The recommended file name for the registration code