Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: completion: Add support for Nushell completions #3073

Merged
merged 1 commit into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* `jj move --from/--to` can now be abbreviated to `jj move -f/-t`

* Added completions for [Nushell](https://nushell.sh) to `jj util completion`

### Fixed bugs

* On Windows, symlinks in the repo are now materialized as regular files in the
Expand Down
15 changes: 13 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ clap = { version = "4.5.1", features = [
"wrap_help",
"string",
] }
clap_complete = "4.5.0"
clap_complete = "4.5.1"
clap_complete_nushell = "4.5.1"
clap-markdown = "0.1.3"
clap_mangen = "0.2.10"
chrono = { version = "0.4.34", default-features = false, features = [
Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ chrono = { workspace = true }
clap = { workspace = true }
clap-markdown = { workspace = true }
clap_complete = { workspace = true }
clap_complete_nushell = { workspace = true }
clap_mangen = { workspace = true }
config = { workspace = true }
criterion = { workspace = true, optional = true }
Expand Down
53 changes: 45 additions & 8 deletions cli/src/commands/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ use std::io::Write;
use std::slice;
use std::time::{Duration, SystemTime};

use clap::Subcommand;
use clap_complete::Shell;
use clap::{Command, Subcommand};
use jj_lib::repo::Repo;
use tracing::instrument;

Expand All @@ -42,6 +41,11 @@ Apply it by running one of these:

- **bash**: `source <(jj util completion bash)`
- **fish**: `jj util completion fish | source`
- **nushell**:
```nu
jj util completion nushell | save "completions-jj.nu"
use "completions-jj.nu" * # Or `source "completions-jj.nu"`
```
- **zsh**:
```shell
autoload -U compinit
Expand All @@ -52,7 +56,7 @@ Apply it by running one of these:
#[derive(clap::Args, Clone, Debug)]
#[command(verbatim_doc_comment)]
pub(crate) struct UtilCompletionArgs {
shell: Option<Shell>,
shell: Option<ShellCompletion>,
/// Deprecated. Use the SHELL positional argument instead.
#[arg(long, hide = true)]
bash: bool,
Expand Down Expand Up @@ -91,6 +95,17 @@ pub(crate) struct UtilMarkdownHelp {}
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct UtilConfigSchemaArgs {}

/// Available shell completions
#[derive(clap::ValueEnum, Clone, Copy, Debug, Eq, Hash, PartialEq)]
enum ShellCompletion {
Bash,
Elvish,
Fish,
Nushell,
PowerShell,
Zsh,
}

#[instrument(skip_all)]
pub(crate) fn cmd_util(
ui: &mut Ui,
Expand Down Expand Up @@ -120,30 +135,30 @@ fn cmd_util_completion(
)?;
writeln!(ui.hint(), "Hint: Use `jj util completion {shell}` instead")
};
let mut buf = vec![];
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
ShellCompletion::Fish
}
(None, false, true, false) => {
warn("zsh")?;
Shell::Zsh
ShellCompletion::Zsh
}
// default to bash for back-compat. TODO: consider making `shell` a required argument
(None, false, false, _) => {
warn("bash")?;
Shell::Bash
ShellCompletion::Bash
}
_ => {
return Err(user_error(
"cannot generate completion for multiple shells at once",
))
}
};
clap_complete::generate(shell, &mut app, "jj", &mut buf);

let buf = shell.generate(&mut app);
ui.stdout_formatter().write_all(&buf)?;
Ok(())
}
Expand Down Expand Up @@ -206,3 +221,25 @@ fn cmd_util_config_schema(
ui.stdout_formatter().write_all(buf)?;
Ok(())
}

impl ShellCompletion {
fn generate(&self, cmd: &mut Command) -> Vec<u8> {
use clap_complete::{generate, Shell};
use clap_complete_nushell::Nushell;

let mut buf = Vec::new();

let bin_name = "jj";

match self {
Self::Bash => generate(Shell::Bash, cmd, bin_name, &mut buf),
Self::Elvish => generate(Shell::Elvish, cmd, bin_name, &mut buf),
Self::Fish => generate(Shell::Fish, cmd, bin_name, &mut buf),
Self::Nushell => generate(Nushell, cmd, bin_name, &mut buf),
Self::PowerShell => generate(Shell::PowerShell, cmd, bin_name, &mut buf),
Self::Zsh => generate(Shell::Zsh, cmd, bin_name, &mut buf),
}

buf
}
}
7 changes: 6 additions & 1 deletion cli/tests/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -1742,6 +1742,11 @@ Apply it by running one of these:

- **bash**: `source <(jj util completion bash)`
- **fish**: `jj util completion fish | source`
- **nushell**:
```nu
jj util completion nushell | save "completions-jj.nu"
use "completions-jj.nu" * # Or `source "completions-jj.nu"`
```
- **zsh**:
```shell
autoload -U compinit
Expand All @@ -1755,7 +1760,7 @@ Apply it by running one of these:

* `<SHELL>`

Possible values: `bash`, `elvish`, `fish`, `powershell`, `zsh`
Possible values: `bash`, `elvish`, `fish`, `nushell`, `power-shell`, `zsh`


###### **Options:**
Expand Down
18 changes: 18 additions & 0 deletions cli/tests/test_util_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,21 @@ fn test_gc_operation_log() {
Error: No operation ID matching "f9400b5274c6f1cfa23afbc1956349897a6975116135a59ab19d941119cc9fad93d9668b8c7d913fbd68c543dcba40a8d44135a53996a9e8ea92d4b78ef52cb6"
"###);
}

#[test]
fn test_shell_completions() {
#[track_caller]
fn test(shell: &str) {
let test_env = TestEnvironment::default();
// Use the local backend because GitBackend::gc() depends on the git CLI.
let (out, err) = test_env.jj_cmd_ok(test_env.env_root(), &["util", "completion", shell]);
// Ensures only stdout contains text
assert!(!out.is_empty());
assert!(err.is_empty());
}

test("bash");
test("fish");
test("nushell");
test("zsh");
}
7 changes: 7 additions & 0 deletions docs/install-and-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ source <(jj util completion zsh)
jj util completion fish | source
```

### Nushell

```nu
jj util completion nushell | save completions-jj.nu
use completions-jj.nu * # Or `source completions-jj.nu`
```

### Xonsh

```shell
Expand Down