ok/jj
1
0
Fork 0
forked from mirrors/jj

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:
jyn 2024-02-04 14:49:20 -05:00
parent 0773cefe32
commit 0f2715203f
4 changed files with 100 additions and 30 deletions

View file

@ -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
"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
* `jj util completion` now supports powershell and elvish.
* Official binaries for macOS running on Apple Silicon (`aarch64-apple-darwin`)
are now available, alongside the existing macOS x86 binaries.

View file

@ -17,6 +17,7 @@ use std::slice;
use std::time::{Duration, SystemTime};
use clap::Subcommand;
use clap_complete::Shell;
use jj_lib::repo::Repo;
use tracing::instrument;
@ -34,30 +35,26 @@ pub(crate) enum UtilCommand {
}
/// 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)]
#[command(verbatim_doc_comment)]
pub(crate) struct UtilCompletionArgs {
/// Print a completion script for Bash (default)
///
/// Apply it by running this:
///
/// source <(jj util completion)
#[arg(long, verbatim_doc_comment)]
shell: Option<Shell>,
/// Deprecated. Use the SHELL positional argument instead.
#[arg(long, hide = true)]
bash: bool,
/// Print a completion script for Fish
///
/// Apply it by running this:
///
/// jj util completion --fish | source
#[arg(long, verbatim_doc_comment)]
/// Deprecated. Use the SHELL positional argument instead.
#[arg(long, hide = true)]
fish: bool,
/// Print a completion script for Zsh
///
/// Apply it by running this:
///
/// autoload -U compinit
/// compinit
/// source <(jj util completion --zsh)
#[arg(long, verbatim_doc_comment)]
/// Deprecated. Use the SHELL positional argument instead.
#[arg(long, hide = true)]
zsh: bool,
}
@ -109,13 +106,35 @@ fn cmd_util_completion(
args: &UtilCompletionArgs,
) -> Result<(), CommandError> {
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 shell = if args.zsh {
clap_complete::Shell::Zsh
} else if args.fish {
clap_complete::Shell::Fish
} else {
clap_complete::Shell::Bash
let shell = match (args.shell, args.fish, args.zsh, args.bash) {
(Some(s), false, false, false) => s,
// allow `--fish` and `--zsh` for back-compat, but don't allow them to be combined
(None, true, false, false) => {
warn("fish")?;
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);
ui.stdout_formatter().write_all(&buf)?;

View file

@ -1708,19 +1708,34 @@ Infrequently used commands such as for generating shell completions
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:**
* `--bash` — Print a completion script for Bash (default)
* `--bash` — Deprecated. Use the SHELL positional argument instead
Possible values: `true`, `false`
* `--fish` — Print a completion script for Fish
* `--fish` — Deprecated. Use the SHELL positional argument instead
Possible values: `true`, `false`
* `--zsh` — Print a completion script for Zsh
* `--zsh` — Deprecated. Use the SHELL positional argument instead
Possible values: `true`, `false`

View 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"));
}