forked from mirrors/jj
completion: Add support for Nushell completions
This commit is contained in:
parent
b533cdc538
commit
c75230747a
8 changed files with 94 additions and 12 deletions
|
@ -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`
|
* `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
|
### Fixed bugs
|
||||||
|
|
||||||
* On Windows, symlinks in the repo are now materialized as regular files in the
|
* On Windows, symlinks in the repo are now materialized as regular files in the
|
||||||
|
|
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -391,13 +391,23 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_complete"
|
name = "clap_complete"
|
||||||
version = "4.5.0"
|
version = "4.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "299353be8209bd133b049bf1c63582d184a8b39fd9c04f15fe65f50f88bdfe6c"
|
checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_complete_nushell"
|
||||||
|
version = "4.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80d0e48e026ce7df2040239117d25e4e79714907420c70294a5ce4b6bbe6a7b6"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"clap_complete",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.0"
|
version = "4.5.0"
|
||||||
|
@ -1603,6 +1613,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"clap-markdown",
|
"clap-markdown",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
|
"clap_complete_nushell",
|
||||||
"clap_mangen",
|
"clap_mangen",
|
||||||
"config",
|
"config",
|
||||||
"criterion",
|
"criterion",
|
||||||
|
|
|
@ -31,7 +31,8 @@ clap = { version = "4.5.1", features = [
|
||||||
"wrap_help",
|
"wrap_help",
|
||||||
"string",
|
"string",
|
||||||
] }
|
] }
|
||||||
clap_complete = "4.5.0"
|
clap_complete = "4.5.1"
|
||||||
|
clap_complete_nushell = "4.5.1"
|
||||||
clap-markdown = "0.1.3"
|
clap-markdown = "0.1.3"
|
||||||
clap_mangen = "0.2.10"
|
clap_mangen = "0.2.10"
|
||||||
chrono = { version = "0.4.34", default-features = false, features = [
|
chrono = { version = "0.4.34", default-features = false, features = [
|
||||||
|
|
|
@ -38,6 +38,7 @@ chrono = { workspace = true }
|
||||||
clap = { workspace = true }
|
clap = { workspace = true }
|
||||||
clap-markdown = { workspace = true }
|
clap-markdown = { workspace = true }
|
||||||
clap_complete = { workspace = true }
|
clap_complete = { workspace = true }
|
||||||
|
clap_complete_nushell = { workspace = true }
|
||||||
clap_mangen = { workspace = true }
|
clap_mangen = { workspace = true }
|
||||||
config = { workspace = true }
|
config = { workspace = true }
|
||||||
criterion = { workspace = true, optional = true }
|
criterion = { workspace = true, optional = true }
|
||||||
|
|
|
@ -16,8 +16,7 @@ use std::io::Write;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use clap::Subcommand;
|
use clap::{Command, Subcommand};
|
||||||
use clap_complete::Shell;
|
|
||||||
use jj_lib::repo::Repo;
|
use jj_lib::repo::Repo;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
@ -42,6 +41,11 @@ Apply it by running one of these:
|
||||||
|
|
||||||
- **bash**: `source <(jj util completion bash)`
|
- **bash**: `source <(jj util completion bash)`
|
||||||
- **fish**: `jj util completion fish | source`
|
- **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**:
|
- **zsh**:
|
||||||
```shell
|
```shell
|
||||||
autoload -U compinit
|
autoload -U compinit
|
||||||
|
@ -52,7 +56,7 @@ Apply it by running one of these:
|
||||||
#[derive(clap::Args, Clone, Debug)]
|
#[derive(clap::Args, Clone, Debug)]
|
||||||
#[command(verbatim_doc_comment)]
|
#[command(verbatim_doc_comment)]
|
||||||
pub(crate) struct UtilCompletionArgs {
|
pub(crate) struct UtilCompletionArgs {
|
||||||
shell: Option<Shell>,
|
shell: Option<ShellCompletion>,
|
||||||
/// Deprecated. Use the SHELL positional argument instead.
|
/// Deprecated. Use the SHELL positional argument instead.
|
||||||
#[arg(long, hide = true)]
|
#[arg(long, hide = true)]
|
||||||
bash: bool,
|
bash: bool,
|
||||||
|
@ -91,6 +95,17 @@ pub(crate) struct UtilMarkdownHelp {}
|
||||||
#[derive(clap::Args, Clone, Debug)]
|
#[derive(clap::Args, Clone, Debug)]
|
||||||
pub(crate) struct UtilConfigSchemaArgs {}
|
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)]
|
#[instrument(skip_all)]
|
||||||
pub(crate) fn cmd_util(
|
pub(crate) fn cmd_util(
|
||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
|
@ -120,22 +135,21 @@ fn cmd_util_completion(
|
||||||
)?;
|
)?;
|
||||||
writeln!(ui.hint(), "Hint: Use `jj util completion {shell}` instead")
|
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) {
|
let shell = match (args.shell, args.fish, args.zsh, args.bash) {
|
||||||
(Some(s), false, false, false) => s,
|
(Some(s), false, false, false) => s,
|
||||||
// allow `--fish` and `--zsh` for back-compat, but don't allow them to be combined
|
// allow `--fish` and `--zsh` for back-compat, but don't allow them to be combined
|
||||||
(None, true, false, false) => {
|
(None, true, false, false) => {
|
||||||
warn("fish")?;
|
warn("fish")?;
|
||||||
Shell::Fish
|
ShellCompletion::Fish
|
||||||
}
|
}
|
||||||
(None, false, true, false) => {
|
(None, false, true, false) => {
|
||||||
warn("zsh")?;
|
warn("zsh")?;
|
||||||
Shell::Zsh
|
ShellCompletion::Zsh
|
||||||
}
|
}
|
||||||
// default to bash for back-compat. TODO: consider making `shell` a required argument
|
// default to bash for back-compat. TODO: consider making `shell` a required argument
|
||||||
(None, false, false, _) => {
|
(None, false, false, _) => {
|
||||||
warn("bash")?;
|
warn("bash")?;
|
||||||
Shell::Bash
|
ShellCompletion::Bash
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(user_error(
|
return Err(user_error(
|
||||||
|
@ -143,7 +157,8 @@ fn cmd_util_completion(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
clap_complete::generate(shell, &mut app, "jj", &mut buf);
|
|
||||||
|
let buf = shell.generate(&mut app);
|
||||||
ui.stdout_formatter().write_all(&buf)?;
|
ui.stdout_formatter().write_all(&buf)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -206,3 +221,25 @@ fn cmd_util_config_schema(
|
||||||
ui.stdout_formatter().write_all(buf)?;
|
ui.stdout_formatter().write_all(buf)?;
|
||||||
Ok(())
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1742,6 +1742,11 @@ Apply it by running one of these:
|
||||||
|
|
||||||
- **bash**: `source <(jj util completion bash)`
|
- **bash**: `source <(jj util completion bash)`
|
||||||
- **fish**: `jj util completion fish | source`
|
- **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**:
|
- **zsh**:
|
||||||
```shell
|
```shell
|
||||||
autoload -U compinit
|
autoload -U compinit
|
||||||
|
@ -1755,7 +1760,7 @@ Apply it by running one of these:
|
||||||
|
|
||||||
* `<SHELL>`
|
* `<SHELL>`
|
||||||
|
|
||||||
Possible values: `bash`, `elvish`, `fish`, `powershell`, `zsh`
|
Possible values: `bash`, `elvish`, `fish`, `nushell`, `power-shell`, `zsh`
|
||||||
|
|
||||||
|
|
||||||
###### **Options:**
|
###### **Options:**
|
||||||
|
|
|
@ -92,3 +92,21 @@ fn test_gc_operation_log() {
|
||||||
Error: No operation ID matching "f9400b5274c6f1cfa23afbc1956349897a6975116135a59ab19d941119cc9fad93d9668b8c7d913fbd68c543dcba40a8d44135a53996a9e8ea92d4b78ef52cb6"
|
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");
|
||||||
|
}
|
||||||
|
|
|
@ -179,6 +179,13 @@ source <(jj util completion zsh)
|
||||||
jj util completion fish | source
|
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
|
### Xonsh
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
Loading…
Reference in a new issue