From 13856a121125b1ccca15919942081a5d157d280e Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Fri, 1 Nov 2024 11:09:33 -0300 Subject: [PATCH] feat: nargo command to generate shell completions (#6413) --- Cargo.lock | 74 ++++++++++++---- cspell.json | 3 + .../docs/getting_started/noir_installation.md | 4 + docs/docs/getting_started/quick_start.md | 2 + .../setting_up_shell_completions.md | 87 +++++++++++++++++++ tooling/nargo_cli/Cargo.toml | 1 + .../src/cli/generate_completion_script_cmd.rs | 33 +++++++ tooling/nargo_cli/src/cli/mod.rs | 24 +++-- 8 files changed, 205 insertions(+), 23 deletions(-) create mode 100644 docs/docs/getting_started/setting_up_shell_completions.md create mode 100644 tooling/nargo_cli/src/cli/generate_completion_script_cmd.rs diff --git a/Cargo.lock b/Cargo.lock index 5073468d385..3659a264737 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,23 +175,24 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" @@ -213,12 +214,12 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -772,9 +773,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.11" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -790,23 +791,32 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.11" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", +] + +[[package]] +name = "clap_complete" +version = "4.5.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bc73de94bc81e52f3bebec71bc4463e9748f7a59166663e32044669577b0e2" +dependencies = [ + "clap", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.64", @@ -814,9 +824,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clipboard-win" @@ -1158,7 +1168,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 2.0.64", ] @@ -1840,6 +1850,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.2" @@ -2121,6 +2137,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "iter-extended" version = "0.37.0" @@ -2551,6 +2573,7 @@ dependencies = [ "build-data", "clap", "clap-markdown", + "clap_complete", "color-eyre", "const_format", "criterion", @@ -4283,6 +4306,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum" version = "0.24.1" @@ -5128,6 +5157,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" diff --git a/cspell.json b/cspell.json index 8945ad21bdc..2577bf74548 100644 --- a/cspell.json +++ b/cspell.json @@ -14,6 +14,7 @@ "arithmetization", "arity", "arkworks", + "autoload", "backpropagate", "Backpropagation", "barebones", @@ -51,6 +52,7 @@ "codespan", "coeff", "combinators", + "compinit", "comptime", "cpus", "cranelift", @@ -91,6 +93,7 @@ "forall", "foralls", "formatcp", + "fpath", "frontends", "fuzzer", "fxhash", diff --git a/docs/docs/getting_started/noir_installation.md b/docs/docs/getting_started/noir_installation.md index f92fd8dea38..a5c7e649278 100644 --- a/docs/docs/getting_started/noir_installation.md +++ b/docs/docs/getting_started/noir_installation.md @@ -91,6 +91,10 @@ Step 1: Follow the instructions [here](https://learn.microsoft.com/en-us/windows step 2: Follow the [Noirup instructions](#installing-noirup). +## Setting up shell completions + +Once `nargo` is installed, you can [set up shell completions for it](setting_up_shell_completions). + ## Uninstalling Nargo If you installed Nargo with `noirup`, you can uninstall Nargo by removing the files in `~/.nargo`, `~/nargo`, and `~/noir_cache`. This ensures that all installed binaries, configurations, and cache related to Nargo are fully removed from your system. diff --git a/docs/docs/getting_started/quick_start.md b/docs/docs/getting_started/quick_start.md index 4ce48409818..c693624eb82 100644 --- a/docs/docs/getting_started/quick_start.md +++ b/docs/docs/getting_started/quick_start.md @@ -17,6 +17,8 @@ curl -L noirup.dev | bash noirup ``` +Once installed, you can [set up shell completions for the `nargo` command](setting_up_shell_completions). + ### Proving backend After installing Noir, we install a proving backend to work with our Noir programs. diff --git a/docs/docs/getting_started/setting_up_shell_completions.md b/docs/docs/getting_started/setting_up_shell_completions.md new file mode 100644 index 00000000000..0447321cbab --- /dev/null +++ b/docs/docs/getting_started/setting_up_shell_completions.md @@ -0,0 +1,87 @@ +--- +title: Setting up shell completions +tags: [] +sidebar_position: 3 +--- + +The `nargo` binary provides a command to generate shell completions: + +```bash +nargo generate-completion-script [shell] +``` + +where `shell` must be one of `bash`, `elvish`, `fish`, `powershell`, and `zsh`. + +Below we explain how to install them in some popular shells. + +## Installing Zsh Completions + +If you have `oh-my-zsh` installed, you might already have a directory of automatically loading completion scripts — `.oh-my-zsh/completions`. +If not, first create it: + +```bash +mkdir -p ~/.oh-my-zsh/completions` +``` + +Then copy the completion script to that directory: + +```bash +nargo generate-completion-script zsh > ~/.oh-my-zsh/completions/_nargo +``` + +Without `oh-my-zsh`, you’ll need to add a path for completion scripts to your function path, and turn on completion script auto-loading. +First, add these lines to `~/.zshrc`: + +```bash +fpath=(~/.zsh/completions $fpath) +autoload -U compinit +compinit +``` + +Next, create a directory at `~/.zsh/completions`: + +```bash +mkdir -p ~/.zsh/completions +``` + +Then copy the completion script to that directory: + +```bash +nargo generate-completion-script zsh > ~/.zsh/completions/_nargo +``` + +## Installing Bash Completions + +If you have [bash-completion](https://github.com/scop/bash-completion) installed, you can just copy the completion script to the `/usr/local/etc/bash_completion.d` directory: + +```bash +nargo generate-completion-script bash > /usr/local/etc/bash_completion.d/nargo +``` + +Without `bash-completion`, you’ll need to source the completion script directly. +First create a directory such as `~/.bash_completions/`: + +```bash +mkdir ~/.bash_completions/ +``` + +Copy the completion script to that directory: + +```bash +nargo generate-completion-script bash > ~/.bash_completions/nargo.bash +``` + +Then add the following line to `~/.bash_profile` or `~/.bashrc`: + + +```bash +source ~/.bash_completions/nargo.bash +``` + +## Installing Fish Completions + +Copy the completion script to any path listed in the environment variable `$fish_completion_path`. For example, a typical location is `~/.config/fish/completions/nargo.fish`: + +```bash +nargo generate-completion-script fish > ~/.config/fish/completions/nargo.fish +``` diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index d48e44415b0..4e45749ddaf 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -66,6 +66,7 @@ termion = "3.0.0" # Logs tracing-subscriber.workspace = true tracing-appender = "0.2.3" +clap_complete = "4.5.36" [target.'cfg(not(unix))'.dependencies] tokio-util = { version = "0.7.8", features = ["compat"] } diff --git a/tooling/nargo_cli/src/cli/generate_completion_script_cmd.rs b/tooling/nargo_cli/src/cli/generate_completion_script_cmd.rs new file mode 100644 index 00000000000..0b8fa1ee3e7 --- /dev/null +++ b/tooling/nargo_cli/src/cli/generate_completion_script_cmd.rs @@ -0,0 +1,33 @@ +use clap::{Args, CommandFactory}; +use clap_complete::Shell; + +use crate::errors::CliError; + +use super::NargoCli; + +/// Generates a shell completion script for your favorite shell +#[derive(Debug, Clone, Args)] +pub(crate) struct GenerateCompletionScriptCommand { + /// The shell to generate completions for. One of: bash, elvish, fish, powershell, zsh + pub(crate) shell: String, +} + +pub(crate) fn run(command: GenerateCompletionScriptCommand) -> Result<(), CliError> { + let shell = match command.shell.to_lowercase().as_str() { + "bash" => Shell::Bash, + "elvish" => Shell::Elvish, + "fish" => Shell::Fish, + "powershell" => Shell::PowerShell, + "zsh" => Shell::Zsh, + _ => { + return Err(CliError::Generic( + "Invalid shell. Supported shells are: bash, elvish, fish, powershell, zsh" + .to_string(), + )) + } + }; + + clap_complete::generate(shell, &mut NargoCli::command(), "nargo", &mut std::io::stdout()); + + Ok(()) +} diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index 9108815f05d..284dd10cb88 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -15,6 +15,7 @@ mod debug_cmd; mod execute_cmd; mod export_cmd; mod fmt_cmd; +mod generate_completion_script_cmd; mod info_cmd; mod init_cmd; mod lsp_cmd; @@ -69,6 +70,7 @@ enum NargoCommand { Lsp(lsp_cmd::LspCommand), #[command(hide = true)] Dap(dap_cmd::DapCommand), + GenerateCompletionScript(generate_completion_script_cmd::GenerateCompletionScriptCommand), } #[cfg(not(feature = "codegen-docs"))] @@ -81,11 +83,22 @@ pub(crate) fn start_cli() -> eyre::Result<()> { } // Search through parent directories to find package root if necessary. - if !matches!( - command, - NargoCommand::New(_) | NargoCommand::Init(_) | NargoCommand::Lsp(_) | NargoCommand::Dap(_) - ) { - config.program_dir = find_package_root(&config.program_dir)?; + match &command { + NargoCommand::Check(..) + | NargoCommand::Fmt(..) + | NargoCommand::Compile(..) + | NargoCommand::Execute(..) + | NargoCommand::Export(..) + | NargoCommand::Debug(..) + | NargoCommand::Test(..) + | NargoCommand::Info(..) => { + config.program_dir = find_package_root(&config.program_dir)?; + } + NargoCommand::New(..) + | NargoCommand::Init(..) + | NargoCommand::Lsp(..) + | NargoCommand::Dap(..) + | NargoCommand::GenerateCompletionScript(..) => (), } match command { @@ -101,6 +114,7 @@ pub(crate) fn start_cli() -> eyre::Result<()> { NargoCommand::Lsp(args) => lsp_cmd::run(args, config), NargoCommand::Dap(args) => dap_cmd::run(args, config), NargoCommand::Fmt(args) => fmt_cmd::run(args, config), + NargoCommand::GenerateCompletionScript(args) => generate_completion_script_cmd::run(args), }?; Ok(())