-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cli: add shell completion subcommand
As the clap_complete dynamic module is unstable and hard-codes the subcommand as `complete`, which conflicts with the current `collect` subcommand. Let's still use the legacy static way to generate the completion file. Usage: $ retis sh-complete -h Generate completions file for a specified shell Usage: retis sh-complete [OPTIONS] Options: --shell <SHELL> Specify shell to complete for [possible values: bash, elvish, fish, powershell, zsh] --register <REGISTER> Path to write completion-registration to -h, --help Print help $ retis sh-complete --shell bash --register . $ source retis.bash Close: #68 Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
- Loading branch information
1 parent
19d8d90
commit f009cdb
Showing
7 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//! # Completion | ||
//! | ||
//! Generate a completions file for a specified shell at runtime. | ||
|
||
use std::{any::Any, io::Write, path::PathBuf}; | ||
|
||
use anyhow::Result; | ||
use clap::{ | ||
error::Error as ClapError, | ||
{value_parser, ArgMatches, Command, Parser}, | ||
}; | ||
use clap_complete::{generate, Generator, Shell}; | ||
|
||
use crate::{cli::*, module::Modules}; | ||
|
||
/// Generate completion file for a specified shell | ||
#[derive(Parser, Debug, Default)] | ||
#[command(name = "sh-complete")] | ||
pub(crate) struct Complete { | ||
/// Specify shell to complete for | ||
// We use an Option and require the parameter to be set here to allow | ||
// deriving Default on Complete. | ||
#[arg(long, required = true, value_parser(value_parser!(Shell)))] | ||
shell: Option<Shell>, | ||
|
||
/// Path to write completion-registration to | ||
#[arg(long)] | ||
register: Option<PathBuf>, | ||
} | ||
|
||
impl SubCommand for Complete { | ||
fn new() -> Result<Self> | ||
where | ||
Self: Sized, | ||
{ | ||
Ok(Self::default()) | ||
} | ||
|
||
fn name(&self) -> String { | ||
<Self as clap::CommandFactory>::command() | ||
.get_name() | ||
.to_string() | ||
} | ||
|
||
fn as_any(&self) -> &dyn Any { | ||
self | ||
} | ||
|
||
fn as_any_mut(&mut self) -> &mut dyn Any { | ||
self | ||
} | ||
|
||
fn full(&self) -> Result<Command> { | ||
Ok(<Self as clap::CommandFactory>::command()) | ||
} | ||
|
||
fn update_from_arg_matches(&mut self, args: &ArgMatches) -> Result<(), ClapError> { | ||
<Self as clap::FromArgMatches>::update_from_arg_matches(self, args) | ||
} | ||
|
||
fn runner(&self) -> Result<Box<dyn SubCommandRunner>> { | ||
Ok(Box::new(CompleteRunner {})) | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub(crate) struct CompleteRunner {} | ||
|
||
impl SubCommandRunner for CompleteRunner { | ||
fn check_prerequisites(&self) -> Result<()> { | ||
Ok(()) | ||
} | ||
|
||
fn run(&mut self, cli: FullCli, _modules: Modules) -> Result<()> { | ||
let mut cmd = cli.get_command(); | ||
let matches = cli.get_command().get_matches(); | ||
|
||
if let Some(sub_m) = matches.subcommand_matches("sh-complete") { | ||
if let Some(generator) = sub_m.get_one::<Shell>("shell") { | ||
let mut buf = Vec::new(); | ||
let name = cmd.get_name().to_string(); | ||
|
||
generate(*generator, &mut cmd, name.clone(), &mut buf); | ||
if let Some(out_path) = sub_m.get_one::<PathBuf>("register") { | ||
if out_path.is_dir() { | ||
let out_path = out_path.join(generator.file_name(&name)); | ||
let _ = std::fs::write(out_path, buf); | ||
} else { | ||
let _ = std::fs::write(out_path, buf); | ||
} | ||
} else { | ||
let _ = std::io::stdout().write_all(&buf); | ||
} | ||
} | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
//! # Generate | ||
//! | ||
//! Generate a completions file for a specified shell at runtime. | ||
|
||
pub(crate) mod completion; | ||
pub(crate) use self::completion::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters