mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-26 22:10:52 +00:00
cli: use a positional argument for jj util completion
this has two main advantages: - it makes it clear that the shells are mutually exclusive - it allows us to extend the command with shell-specific options in the future if necessary as a happy accident, it also adds support for `elvish` and `powershell`. for backwards compatibility, this also keeps the existing options as hidden flags. i am not super happy with how the new help looks; the instructions for setting up the shell are squished together and IMO a little harder to read. i'm open to suggestions.
This commit is contained in:
parent
0773cefe32
commit
0f2715203f
4 changed files with 100 additions and 30 deletions
|
@ -39,8 +39,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
of `R` for "Removed". @joyously pointed out that `R` could also mean
|
of `R` for "Removed". @joyously pointed out that `R` could also mean
|
||||||
"Renamed".
|
"Renamed".
|
||||||
|
|
||||||
|
* `jj util completion` now takes the shell as a positional argument, not a flag.
|
||||||
|
the previous behavior is deprecated, but supported for now. it will be removed
|
||||||
|
in the future.
|
||||||
|
|
||||||
### New features
|
### New features
|
||||||
|
|
||||||
|
* `jj util completion` now supports powershell and elvish.
|
||||||
|
|
||||||
* Official binaries for macOS running on Apple Silicon (`aarch64-apple-darwin`)
|
* Official binaries for macOS running on Apple Silicon (`aarch64-apple-darwin`)
|
||||||
are now available, alongside the existing macOS x86 binaries.
|
are now available, alongside the existing macOS x86 binaries.
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::slice;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use clap::Subcommand;
|
use clap::Subcommand;
|
||||||
|
use clap_complete::Shell;
|
||||||
use jj_lib::repo::Repo;
|
use jj_lib::repo::Repo;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
@ -34,30 +35,26 @@ pub(crate) enum UtilCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Print a command-line-completion script
|
/// Print a command-line-completion script
|
||||||
|
///
|
||||||
|
/// Apply it by running this:
|
||||||
|
/// bash: source <(jj util completion)
|
||||||
|
/// fish: jj util completion --fish | source
|
||||||
|
/// zsh:
|
||||||
|
/// autoload -U compinit
|
||||||
|
/// compinit
|
||||||
|
/// source <(jj util completion --zsh)
|
||||||
#[derive(clap::Args, Clone, Debug)]
|
#[derive(clap::Args, Clone, Debug)]
|
||||||
|
#[command(verbatim_doc_comment)]
|
||||||
pub(crate) struct UtilCompletionArgs {
|
pub(crate) struct UtilCompletionArgs {
|
||||||
/// Print a completion script for Bash (default)
|
shell: Option<Shell>,
|
||||||
///
|
/// Deprecated. Use the SHELL positional argument instead.
|
||||||
/// Apply it by running this:
|
#[arg(long, hide = true)]
|
||||||
///
|
|
||||||
/// source <(jj util completion)
|
|
||||||
#[arg(long, verbatim_doc_comment)]
|
|
||||||
bash: bool,
|
bash: bool,
|
||||||
/// Print a completion script for Fish
|
/// Deprecated. Use the SHELL positional argument instead.
|
||||||
///
|
#[arg(long, hide = true)]
|
||||||
/// Apply it by running this:
|
|
||||||
///
|
|
||||||
/// jj util completion --fish | source
|
|
||||||
#[arg(long, verbatim_doc_comment)]
|
|
||||||
fish: bool,
|
fish: bool,
|
||||||
/// Print a completion script for Zsh
|
/// Deprecated. Use the SHELL positional argument instead.
|
||||||
///
|
#[arg(long, hide = true)]
|
||||||
/// Apply it by running this:
|
|
||||||
///
|
|
||||||
/// autoload -U compinit
|
|
||||||
/// compinit
|
|
||||||
/// source <(jj util completion --zsh)
|
|
||||||
#[arg(long, verbatim_doc_comment)]
|
|
||||||
zsh: bool,
|
zsh: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,13 +106,35 @@ fn cmd_util_completion(
|
||||||
args: &UtilCompletionArgs,
|
args: &UtilCompletionArgs,
|
||||||
) -> Result<(), CommandError> {
|
) -> Result<(), CommandError> {
|
||||||
let mut app = command.app().clone();
|
let mut app = command.app().clone();
|
||||||
|
let warn = |shell| {
|
||||||
|
writeln!(
|
||||||
|
ui.warning(),
|
||||||
|
"warning: `jj util completion --{shell}` will be removed in a future version, and \
|
||||||
|
this will be a hard error"
|
||||||
|
)
|
||||||
|
};
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
let shell = if args.zsh {
|
let shell = match (args.shell, args.fish, args.zsh, args.bash) {
|
||||||
clap_complete::Shell::Zsh
|
(Some(s), false, false, false) => s,
|
||||||
} else if args.fish {
|
// allow `--fish` and `--zsh` for back-compat, but don't allow them to be combined
|
||||||
clap_complete::Shell::Fish
|
(None, true, false, false) => {
|
||||||
} else {
|
warn("fish")?;
|
||||||
clap_complete::Shell::Bash
|
Shell::Fish
|
||||||
|
}
|
||||||
|
(None, false, true, false) => {
|
||||||
|
warn("zsh")?;
|
||||||
|
Shell::Zsh
|
||||||
|
}
|
||||||
|
// default to bash for back-compat. TODO: consider making `shell` a required argument
|
||||||
|
(None, false, false, _) => {
|
||||||
|
warn("bash")?;
|
||||||
|
Shell::Bash
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(user_error(
|
||||||
|
"cannot generate completion for multiple shells at once",
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
clap_complete::generate(shell, &mut app, "jj", &mut buf);
|
clap_complete::generate(shell, &mut app, "jj", &mut buf);
|
||||||
ui.stdout_formatter().write_all(&buf)?;
|
ui.stdout_formatter().write_all(&buf)?;
|
||||||
|
|
|
@ -1708,19 +1708,34 @@ Infrequently used commands such as for generating shell completions
|
||||||
|
|
||||||
Print a command-line-completion script
|
Print a command-line-completion script
|
||||||
|
|
||||||
**Usage:** `jj util completion [OPTIONS]`
|
Apply it by running this:
|
||||||
|
bash: source <(jj util completion)
|
||||||
|
fish: jj util completion --fish | source
|
||||||
|
zsh:
|
||||||
|
autoload -U compinit
|
||||||
|
compinit
|
||||||
|
source <(jj util completion --zsh)
|
||||||
|
|
||||||
|
**Usage:** `jj util completion [SHELL]`
|
||||||
|
|
||||||
|
###### **Arguments:**
|
||||||
|
|
||||||
|
* `<SHELL>`
|
||||||
|
|
||||||
|
Possible values: `bash`, `elvish`, `fish`, `powershell`, `zsh`
|
||||||
|
|
||||||
|
|
||||||
###### **Options:**
|
###### **Options:**
|
||||||
|
|
||||||
* `--bash` — Print a completion script for Bash (default)
|
* `--bash` — Deprecated. Use the SHELL positional argument instead
|
||||||
|
|
||||||
Possible values: `true`, `false`
|
Possible values: `true`, `false`
|
||||||
|
|
||||||
* `--fish` — Print a completion script for Fish
|
* `--fish` — Deprecated. Use the SHELL positional argument instead
|
||||||
|
|
||||||
Possible values: `true`, `false`
|
Possible values: `true`, `false`
|
||||||
|
|
||||||
* `--zsh` — Print a completion script for Zsh
|
* `--zsh` — Deprecated. Use the SHELL positional argument instead
|
||||||
|
|
||||||
Possible values: `true`, `false`
|
Possible values: `true`, `false`
|
||||||
|
|
||||||
|
|
30
cli/tests/test_shell_completion.rs
Normal file
30
cli/tests/test_shell_completion.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2024 The Jujutsu Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use crate::common::TestEnvironment;
|
||||||
|
|
||||||
|
pub mod common;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deprecated_flags() {
|
||||||
|
let test_env = TestEnvironment::default();
|
||||||
|
let (stdout, stderr) =
|
||||||
|
test_env.jj_cmd_ok(test_env.env_root(), &["util", "completion", "--bash"]);
|
||||||
|
assert_eq!(
|
||||||
|
stderr,
|
||||||
|
"warning: `jj util completion --bash` will be removed in a future version, and this will \
|
||||||
|
be a hard error\n"
|
||||||
|
);
|
||||||
|
assert!(stdout.contains("COMPREPLY"));
|
||||||
|
}
|
Loading…
Reference in a new issue