diff --git a/Cargo.lock b/Cargo.lock index b191042f4..273a4037e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -762,6 +762,16 @@ dependencies = [ "clap", ] +[[package]] +name = "clap_complete_nushell" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1accf1b463dee0d3ab2be72591dccdab8bef314958340447c882c4c72acfe2a3" +dependencies = [ + "clap", + "clap_complete", +] + [[package]] name = "clap_derive" version = "4.5.5" @@ -3437,6 +3447,7 @@ dependencies = [ "clap-markdown", "clap-verbosity-flag", "clap_complete", + "clap_complete_nushell", "comfy-table", "console", "content_inspector", diff --git a/Cargo.toml b/Cargo.toml index e15053c44..a52171c03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,7 @@ dunce = "1.0.4" fs-err = "2.11.0" which = "6.0.1" clap_complete = "4.5.6" +clap_complete_nushell = "4.5.2" tokio-util = "0.7.11" tar = "0.4.41" diff --git a/docs/index.md b/docs/index.md index 3c7abad60..334fdcde7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -56,16 +56,59 @@ Other options are: Releases](https://github.com/prefix-dev/rattler-build/releases/). ### Completion + When installing `rattler-build` you might want to enable shell completion. -Do this by running the `rattler-build completion` command in the activation of your shell. - -```sh -# For bash (add this to ~/.bashrc) -echo 'eval "$(rattler-build completion --shell=bash)"' >> ~/.bashrc -# For zsh (add this to ~/.zshrc) -echo 'eval "$(rattler-build completion --shell=zsh)"' >> ~/.zshrc -# For fish (add this to ~/.config/fish/config.fish) -echo 'rattler-build completion --shell=fish | source' >> ~/.config/fish/config.fish +Afterwards, restart the shell or source the shell config file. + +### Bash (default on most Linux systems) + +```bash +echo 'eval "$(rattler-build completion --shell bash)"' >> ~/.bashrc +``` +### Zsh (default on macOS) + +```zsh +echo 'eval "$(rattler-build completion --shell zsh)"' >> ~/.zshrc +``` + +### PowerShell (pre-installed on all Windows systems) + +```pwsh +Add-Content -Path $PROFILE -Value '(& rattler-build completion --shell powershell) | Out-String | Invoke-Expression' +``` + +!!! tip "Failure because no profile file exists" + Make sure your profile file exists, otherwise create it with: + ```PowerShell + New-Item -Path $PROFILE -ItemType File -Force + ``` + + +### Fish + +```fish +echo 'rattler-build completion --shell fish | source' >> ~/.config/fish/config.fish +``` + +### Nushell + +Add the following to the end of your Nushell env file (find it by running `$nu.env-path` in Nushell): + +```nushell +mkdir ~/.cache/rattler-build +rattler-build completion --shell nushell | save -f ~/.cache/rattler-build/completions.nu +``` + +And add the following to the end of your Nushell configuration (find it by running `$nu.config-path`): + +```nushell +use ~/.cache/rattler-build/completions.nu * +``` + +### Elvish + +```elv +echo 'eval (rattler-build completion --shell elvish | slurp)' >> ~/.elvish/rc.elv ``` ### Dependencies diff --git a/docs/reference/cli.md b/docs/reference/cli.md index c59d43c96..9e1ddf3d7 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -556,15 +556,27 @@ Options for uploading to a Anaconda.org server Generate shell completion script -**Usage:** `rattler-build completion [OPTIONS]` +**Usage:** `rattler-build completion --shell ` ##### **Options:** - `-s`, `--shell ` - Shell + Specifies the shell for which the completions should be generated - - Possible values: `bash`, `elvish`, `fish`, `powershell`, `zsh` + - Possible values: + - `bash`: + Bourne Again SHell (bash) + - `elvish`: + Elvish shell + - `fish`: + Friendly Interactive SHell (fish) + - `nushell`: + Nushell + - `powershell`: + PowerShell + - `zsh`: + Z SHell (zsh) diff --git a/src/main.rs b/src/main.rs index 68154edf1..6937bea71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,9 +50,7 @@ async fn main() -> miette::Result<()> { &mut std::io::stdout(), ); } - let shell = shell - .or(clap_complete::Shell::from_env()) - .unwrap_or(clap_complete::Shell::Bash); + print_completions(shell, &mut cmd); Ok(()) } diff --git a/src/opt.rs b/src/opt.rs index a37adf265..94eb6e005 100644 --- a/src/opt.rs +++ b/src/opt.rs @@ -8,7 +8,9 @@ use crate::{ tool_configuration::SkipExisting, }; use clap::builder::ArgPredicate; -use clap::{arg, crate_version, Parser}; +use clap::{arg, crate_version, Parser, ValueEnum}; +use clap_complete::{shells, Generator}; +use clap_complete_nushell::Nushell; use clap_verbosity_flag::{InfoLevel, Verbosity}; use rattler_conda_types::{package::ArchiveType, Platform}; use rattler_package_streaming::write::CompressionLevel; @@ -53,9 +55,51 @@ pub enum SubCommands { /// Shell completion options. #[derive(Parser)] pub struct ShellCompletion { - /// Shell. + /// Specifies the shell for which the completions should be generated #[arg(short, long)] - pub shell: Option, + pub shell: Shell, +} + +/// Defines the shells for which we can provide completions +#[allow(clippy::enum_variant_names)] +#[derive(ValueEnum, Clone, Debug, Copy, Eq, Hash, PartialEq)] +pub enum Shell { + /// Bourne Again SHell (bash) + Bash, + /// Elvish shell + Elvish, + /// Friendly Interactive SHell (fish) + Fish, + /// Nushell + Nushell, + /// PowerShell + Powershell, + /// Z SHell (zsh) + Zsh, +} + +impl Generator for Shell { + fn file_name(&self, name: &str) -> String { + match self { + Shell::Bash => shells::Bash.file_name(name), + Shell::Elvish => shells::Elvish.file_name(name), + Shell::Fish => shells::Fish.file_name(name), + Shell::Nushell => Nushell.file_name(name), + Shell::Powershell => shells::PowerShell.file_name(name), + Shell::Zsh => shells::Zsh.file_name(name), + } + } + + fn generate(&self, cmd: &clap::Command, buf: &mut dyn std::io::Write) { + match self { + Shell::Bash => shells::Bash.generate(cmd, buf), + Shell::Elvish => shells::Elvish.generate(cmd, buf), + Shell::Fish => shells::Fish.generate(cmd, buf), + Shell::Nushell => Nushell.generate(cmd, buf), + Shell::Powershell => shells::PowerShell.generate(cmd, buf), + Shell::Zsh => shells::Zsh.generate(cmd, buf), + } + } } #[allow(missing_docs)]