diff --git a/Cargo.lock b/Cargo.lock index 9748ae00e1..18b3bd8fe2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,6 +322,16 @@ dependencies = [ "clap", ] +[[package]] +name = "clap_complete_nushell" +version = "4.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0e48e026ce7df2040239117d25e4e79714907420c70294a5ce4b6bbe6a7b6" +dependencies = [ + "clap", + "clap_complete", +] + [[package]] name = "clap_derive" version = "4.4.7" @@ -1652,6 +1662,7 @@ dependencies = [ "bzip2", "clap", "clap_complete", + "clap_complete_nushell", "configparser", "console", "ctrlc", diff --git a/docs/guide/commands/self/completion.md b/docs/guide/commands/self/completion.md index 7d8c63fc0e..2b3c56cf42 100644 --- a/docs/guide/commands/self/completion.md +++ b/docs/guide/commands/self/completion.md @@ -18,6 +18,6 @@ _no arguments_ * `-s, --shell `: The shell to generate a completion script for (defaults to 'bash') - [possible values: `bash`, `elvish`, `fish`, `powershell`, `zsh`] + [possible values: `bash`, `elvish`, `fish`, `powershell`, `zsh`, `nushell`] * `-h, --help`: Print help (see a summary with '-h') diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 25b62b8d51..1f883ee211 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -137,7 +137,7 @@ to learn more. ## Shell Completion -Rye supports generating completion scripts for Bash, Zsh, Fish or Powershell. Here are some common locations for each shell: +Rye supports generating completion scripts for Bash, Zsh, Fish, Powershell and Nushell. Here are some common locations for each shell: === "Bash" @@ -183,6 +183,12 @@ Rye supports generating completion scripts for Bash, Zsh, Fish or Powershell. He rye self completion -s powershell | Out-File -Encoding utf8 $PROFILE\..\Completions\rye_completion.ps1 ``` +=== "NuShell" + + ```nushell + rye self completion -s nushell | save --append $nu.env-path + ``` + ## Updating Rye To update rye to the latest version you can use `rye` itself: diff --git a/rye/Cargo.toml b/rye/Cargo.toml index 41bdab91e7..72431ba886 100644 --- a/rye/Cargo.toml +++ b/rye/Cargo.toml @@ -16,6 +16,7 @@ clap = { version = "4.3.5", default-features = false, features = [ "std", ] } clap_complete = "4.2.1" +clap_complete_nushell = "4.5.1" console = "0.15.7" curl = { version = "0.4.44", features = ["ssl", "static-curl", "static-ssl"] } flate2 = "1.0.25" diff --git a/rye/src/cli/rye.rs b/rye/src/cli/rye.rs index 3b6d59199c..ddcb6e9603 100644 --- a/rye/src/cli/rye.rs +++ b/rye/src/cli/rye.rs @@ -7,8 +7,9 @@ use std::sync::Arc; use std::{env, fs}; use anyhow::{anyhow, bail, Context, Error}; -use clap::{CommandFactory, Parser}; -use clap_complete::Shell; +use clap::{CommandFactory, Parser, ValueEnum}; +use clap_complete::{Generator, Shell}; +use clap_complete_nushell::Nushell; use console::style; use minijinja::render; use self_replace::self_delete_outside_path; @@ -52,12 +53,54 @@ pub struct Args { command: SubCommand, } +#[derive(Clone, Debug, ValueEnum)] +enum ShellCompletion { + /// Bourne Again SHell (bash) + Bash, + /// Elvish shell + Elvish, + /// Friendly Interactive SHell (fish) + Fish, + /// PowerShell + PowerShell, + /// Z SHell (zsh) + Zsh, + /// Nushell + Nushell, +} + +impl Generator for ShellCompletion { + /// Generate the file name for the completion script. + fn file_name(&self, name: &str) -> String { + match self { + ShellCompletion::Nushell => Nushell.file_name(name), + ShellCompletion::Bash => Shell::Bash.file_name(name), + ShellCompletion::Elvish => Shell::Elvish.file_name(name), + ShellCompletion::Fish => Shell::Fish.file_name(name), + ShellCompletion::PowerShell => Shell::PowerShell.file_name(name), + ShellCompletion::Zsh => Shell::Zsh.file_name(name), + } + } + + /// Generate the completion script for the shell. + fn generate(&self, cmd: &clap::Command, buf: &mut dyn std::io::Write) { + match self { + ShellCompletion::Nushell => Nushell.generate(cmd, buf), + ShellCompletion::Bash => Shell::Bash.generate(cmd, buf), + ShellCompletion::Elvish => Shell::Elvish.generate(cmd, buf), + ShellCompletion::Fish => Shell::Fish.generate(cmd, buf), + ShellCompletion::PowerShell => Shell::PowerShell.generate(cmd, buf), + ShellCompletion::Zsh => Shell::Zsh.generate(cmd, buf), + } + } +} + /// Generates a completion script for a shell. #[derive(Parser, Debug)] pub struct CompletionCommand { /// The shell to generate a completion script for (defaults to 'bash'). #[arg(short, long)] - shell: Option, + shell: Option, } /// Performs an update of rye. @@ -180,7 +223,7 @@ pub fn execute(cmd: Args) -> Result<(), Error> { fn completion(args: CompletionCommand) -> Result<(), Error> { clap_complete::generate( - args.shell.unwrap_or(Shell::Bash), + args.shell.unwrap_or(ShellCompletion::Bash), &mut super::Args::command(), "rye", &mut std::io::stdout(),