From 4ff1c1aa8811d599d268f9e48f31a4902683fe8e Mon Sep 17 00:00:00 2001 From: Christian Guinard <28689358+christiangnrd@users.noreply.github.com> Date: Wed, 4 Sep 2024 15:39:14 -0300 Subject: [PATCH] Use dynamic command completions --- Cargo.lock | 12 ++++++++++++ Cargo.toml | 3 ++- README.md | 14 +++++++++++++- src/bin/juliaup.rs | 5 ++++- src/cli.rs | 2 +- 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8196368..3fc0334e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,6 +266,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d7db6eca8c205649e8d3ccd05aa5042b1800a784e56bc7c43524fde8abbfa9b" dependencies = [ "clap", + "clap_lex", + "is_executable", + "shlex", ] [[package]] @@ -965,6 +968,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "is_executable" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9acdc6d67b75e626ad644734e8bc6df893d9cd2a834129065d3dd6158ea9c8" +dependencies = [ + "winapi", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" diff --git a/Cargo.toml b/Cargo.toml index f6ce7650..5789eca1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ license = "MIT" keywords = ["julia"] categories = ["command-line-utilities"] edition = "2021" +rust-version = "1.80" default-run = "juliaup" authors = ["David Anthoff "] exclude = [ @@ -27,7 +28,7 @@ codegen-units = 1 [dependencies] clap = { version = "4.5", features = ["derive"] } -clap_complete = "4.5" +clap_complete = { version = "4.5", features = ["unstable-dynamic"] } dirs = "5.0.1" dunce = "1.0" serde = { version = "1.0", features = ["derive"] } diff --git a/README.md b/README.md index d6bee397..9cd1cde0 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,6 @@ Here are some of the things you can do with `juliaup`: - `juliaup override set --path foo/bar lts` sets a directory override for the path `foo/bar` to the `lts` channel. - `juliaup override unset --path foo/bar` removes a directory override for the path `foo/bar`. - `juliaup override unset --nonexistent` removes all directory overrides for paths that no longer exist. -- `juliaup completions bash > ~/.local/share/bash-completion/completions/juliaup` generates Bash completions for `juliaup` and saves them to a file. To use them, simply source this file in your `~/.bashrc`. Other supported shells are `zsh`, `fish`, `elvish` and `powershell`. - `juliaup` shows you what other commands are available. The available system provided channels are: @@ -168,6 +167,19 @@ the `JULIAUP_DEPOT_PATH` environment variable. Caution: Previous versions of Jul Juliaup by default downloads julia binary tarballs from the official server "https://julialang-s3.julialang.org". If requested, the environment variable `JULIAUP_SERVER` can be used to tell Juliaup to use a third-party mirror server. +## Shell completions + +To generate shell completions, load `COMPLETE=$SHELL juliaup` at shell launch. For example, with bash, it could look like `source <(COMPLETE=bash juliaup)`. + +For more specific information on adding completions to your shell, see https://docs.rs/clap_complete/latest/clap_complete/env/index.html + +Note: MacOS ships with an ancient version of bash that does not support process substitution. To work around this, you can create a temporary file and `source` that instead like: + +```bash +COMPLETE=bash juliaup > /tmp/juliaup_completion.sh +source /tmp/juliaup_completion.sh +``` + ## Development guides For juliaup developers, information on how to build juliaup locally, update julia versions, and release updates diff --git a/src/bin/juliaup.rs b/src/bin/juliaup.rs index 1cdbb2f0..43aabd60 100644 --- a/src/bin/juliaup.rs +++ b/src/bin/juliaup.rs @@ -1,5 +1,6 @@ use anyhow::{Context, Result}; -use clap::Parser; +use clap::{CommandFactory, Parser}; +use clap_complete::CompleteEnv; use juliaup::cli::{ConfigSubCmd, Juliaup, OverrideSubCmd, SelfSubCmd}; use juliaup::command_api::run_command_api; #[cfg(not(windows))] @@ -36,6 +37,8 @@ use juliaup::command_selfuninstall::run_command_selfuninstall_unavailable; use log::info; fn main() -> Result<()> { + CompleteEnv::with_factory(|| Juliaup::command()).complete(); + human_panic::setup_panic!( human_panic::Metadata::new("Juliaup", env!("CARGO_PKG_VERSION")) .support("https://github.com/JuliaLang/juliaup") diff --git a/src/cli.rs b/src/cli.rs index ea393760..839dafac 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,7 +1,7 @@ use clap::{Parser, ValueEnum}; #[derive(Parser)] -#[clap(name = "Juliaup", version)] +#[clap(name = "juliaup", version)] #[command( after_help = "To launch a specific Julia version, use `julia +{channel}` e.g. `julia +1.6`. Entering just `julia` uses the default channel set via `juliaup default`."