This commit is contained in:
silvanshade 2026-05-30 19:10:11 -06:00 committed by GitHub
commit ce156d444b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 144 additions and 3 deletions

12
Cargo.lock generated
View file

@ -3122,6 +3122,16 @@ dependencies = [
"clap",
]
[[package]]
name = "clap_complete_nushell"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbb9e9715d29a754b468591be588f6b926f5b0a1eb6a8b62acabeb66ff84d897"
dependencies = [
"clap",
"clap_complete",
]
[[package]]
name = "clap_derive"
version = "4.5.49"
@ -3147,6 +3157,8 @@ dependencies = [
"anyhow",
"askpass",
"clap",
"clap_complete",
"clap_complete_nushell",
"collections",
"console",
"core-foundation 0.10.0",

View file

@ -556,6 +556,8 @@ chrono = { version = "0.4", features = ["serde"] }
ciborium = "0.2"
circular-buffer = "1.0"
clap = { version = "4.4", features = ["derive", "wrap_help"] }
clap_complete = { version = "4.4" }
clap_complete_nushell = { version = "4.4" }
cocoa = "=0.26.0"
cocoa-foundation = "=0.2.0"
const_format = "0.2"

View file

@ -24,6 +24,8 @@ default = []
anyhow.workspace = true
askpass.workspace = true
clap.workspace = true
clap_complete.workspace = true
clap_complete_nushell.workspace = true
collections.workspace = true
console.workspace = true
dialoguer.workspace = true

View file

@ -0,0 +1,47 @@
mod shells {
pub use clap_complete::aot::{Bash, Elvish, Fish, PowerShell, Zsh};
pub use clap_complete_nushell::Nushell;
}
use clap_complete::Generator;
#[derive(Clone, Debug, clap::ValueEnum)]
#[non_exhaustive]
#[value(rename_all = "lower")]
pub(crate) enum Shell {
Bash,
Elvish,
Fish,
Nushell,
PowerShell,
Zsh,
}
impl Generator for Shell {
fn file_name(&self, name: &str) -> String {
match self {
Shell::Bash => self::shells::Bash.file_name(name),
Shell::Elvish => self::shells::Elvish.file_name(name),
Shell::Fish => self::shells::Fish.file_name(name),
Shell::Nushell => self::shells::Nushell.file_name(name),
Shell::PowerShell => self::shells::PowerShell.file_name(name),
Shell::Zsh => self::shells::Zsh.file_name(name),
}
}
fn generate(&self, cmd: &clap::Command, buf: &mut dyn std::io::Write) {
match self {
Shell::Bash => self::shells::Bash.generate(cmd, buf),
Shell::Elvish => self::shells::Elvish.generate(cmd, buf),
Shell::Fish => self::shells::Fish.generate(cmd, buf),
Shell::Nushell => self::shells::Nushell.generate(cmd, buf),
Shell::PowerShell => self::shells::PowerShell.generate(cmd, buf),
Shell::Zsh => self::shells::Zsh.generate(cmd, buf),
}
}
}
pub(crate) fn main(cmd: &clap::Command, shell: &Shell) {
let buf = &mut std::io::stdout();
shell.generate(cmd, buf);
}

View file

@ -7,8 +7,12 @@
allow(dead_code)
)]
mod completions;
use crate::completions::Shell;
use anyhow::{Context as _, Result};
use clap::Parser;
use clap::{CommandFactory, Parser};
use cli::{CliRequest, CliResponse, IpcHandshake, ipc::IpcOneShotServer};
use parking_lot::Mutex;
use std::{
@ -89,11 +93,12 @@ struct Args {
not(any(target_os = "windows", target_os = "macos")),
doc = "`$XDG_DATA_HOME/zed`."
)]
#[arg(long, value_name = "DIR")]
#[arg(long, value_name = "DIR", value_hint = clap::ValueHint::DirPath)]
user_data_dir: Option<String>,
/// The paths to open in Zed (space-separated).
///
/// Use `path:line:column` syntax to open a file at the given line and column.
#[arg(trailing_var_arg = true, value_hint = clap::ValueHint::AnyPath)]
paths_with_position: Vec<String>,
/// Print Zed's version and the app path.
#[arg(short, long)]
@ -131,8 +136,11 @@ struct Args {
dev_container: bool,
/// Pairs of file paths to diff. Can be specified multiple times.
/// When directories are provided, recurses into them and shows all changed files in a single multi-diff view.
#[arg(long, action = clap::ArgAction::Append, num_args = 2, value_names = ["OLD_PATH", "NEW_PATH"])]
#[arg(long, action = clap::ArgAction::Append, num_args = 2, value_names = ["OLD_PATH", "NEW_PATH"], value_hint = clap::ValueHint::AnyPath)]
diff: Vec<String>,
/// Generate shell completions for Zed
#[arg(long, value_names = ["SHELL"])]
completions: Option<Shell>,
/// Uninstall Zed from user system
#[cfg(all(
any(target_os = "linux", target_os = "macos"),
@ -506,6 +514,20 @@ fn run() -> Result<()> {
let app = Detect::detect(args.zed.as_deref()).context("Bundle detection")?;
if let Some(shell) = &args.completions {
let file_path = std::env::current_exe()?;
let file_name = file_path
.file_name()
.and_then(OsStr::to_str)
.ok_or("--completions expects a UTF-8 name for cli bin")
.map_err(anyhow::Error::msg)?;
let mut cmd = Args::command();
cmd.set_bin_name(file_name);
cmd.build();
crate::completions::main(&cmd, shell);
return Ok(());
}
if args.version {
println!("{}", app.zed_version_string());
return Ok(());

View file

@ -126,6 +126,62 @@ Print Zed's version and exit:
zed --version
```
### `--completions <SHELL>`
Generate shell completions for the `zed` CLI:
#### Bash
Add to `~/.bashrc`:
```bash
eval "$(zed --completions bash)"
```
#### Elvish
Add to `~/.config/elvish/rc.elv`:
```elvish
set edit:completion:arg-completer[zed] = { |@args|
eval (zed --completions elvish | slurp)
$edit:completion:arg-completer[zed] $@args
}
```
#### Fish
Add to `~/.config/fish/config.fish`:
```fish
zed --completions fish | source
```
#### Nushell
Add to `~/.config/nushell/config.nu`:
```nu
mkdir ($nu.data-dir | path join "vendor/autoload")
^zed --completions nushell | save --force ($nu.data-dir | path join "vendor/autoload/zed.nu")
```
#### Powershell
Add to `$PROFILE`:
```powershell
(&zed --completions powershell) | Out-String | Invoke-Expression
```
#### Zsh
Add to `~/.zshrc`:
```zsh
eval "$(zed --completions zsh)"
```
### `--uninstall`
Uninstall Zed and remove all related files (macOS and Linux only):