diff --git a/.github/ISSUE_TEMPLATE/10_bug_report.yml b/.github/ISSUE_TEMPLATE/10_bug_report.yml
index e132eca1e5..1bf6c80e40 100644
--- a/.github/ISSUE_TEMPLATE/10_bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/10_bug_report.yml
@@ -14,7 +14,7 @@ body:
### Description
diff --git a/Cargo.lock b/Cargo.lock
index 2b3d7b2691..42649b137f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -39,6 +39,26 @@ dependencies = [
"workspace-hack",
]
+[[package]]
+name = "acp_tools"
+version = "0.1.0"
+dependencies = [
+ "agent-client-protocol",
+ "collections",
+ "gpui",
+ "language",
+ "markdown",
+ "project",
+ "serde",
+ "serde_json",
+ "settings",
+ "theme",
+ "ui",
+ "util",
+ "workspace",
+ "workspace-hack",
+]
+
[[package]]
name = "action_log"
version = "0.1.0"
@@ -171,11 +191,12 @@ dependencies = [
[[package]]
name = "agent-client-protocol"
-version = "0.0.30"
+version = "0.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f792e009ba59b137ee1db560bc37e567887ad4b5af6f32181d381fff690e2d4"
+checksum = "289eb34ee17213dadcca47eedadd386a5e7678094095414e475965d1bcca2860"
dependencies = [
"anyhow",
+ "async-broadcast",
"futures 0.3.31",
"log",
"parking_lot",
@@ -264,10 +285,10 @@ name = "agent_servers"
version = "0.1.0"
dependencies = [
"acp_thread",
+ "acp_tools",
"action_log",
"agent-client-protocol",
"agent_settings",
- "agentic-coding-protocol",
"anyhow",
"client",
"collections",
@@ -382,6 +403,7 @@ dependencies = [
"parking_lot",
"paths",
"picker",
+ "postage",
"pretty_assertions",
"project",
"prompt_store",
@@ -421,24 +443,6 @@ dependencies = [
"zed_actions",
]
-[[package]]
-name = "agentic-coding-protocol"
-version = "0.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e6ae951b36fa2f8d9dd6e1af6da2fcaba13d7c866cf6a9e65deda9dc6c5fe4"
-dependencies = [
- "anyhow",
- "chrono",
- "derive_more 2.0.1",
- "futures 0.3.31",
- "log",
- "parking_lot",
- "schemars",
- "semver",
- "serde",
- "serde_json",
-]
-
[[package]]
name = "ahash"
version = "0.7.8"
@@ -854,7 +858,7 @@ dependencies = [
"anyhow",
"async-trait",
"collections",
- "derive_more 0.99.19",
+ "derive_more",
"extension",
"futures 0.3.31",
"gpui",
@@ -917,7 +921,7 @@ dependencies = [
"clock",
"collections",
"ctor",
- "derive_more 0.99.19",
+ "derive_more",
"gpui",
"icons",
"indoc",
@@ -954,7 +958,7 @@ dependencies = [
"cloud_llm_client",
"collections",
"component",
- "derive_more 0.99.19",
+ "derive_more",
"diffy",
"editor",
"feature_flags",
@@ -3067,7 +3071,7 @@ dependencies = [
"cocoa 0.26.0",
"collections",
"credentials_provider",
- "derive_more 0.99.19",
+ "derive_more",
"feature_flags",
"fs",
"futures 0.3.31",
@@ -3499,7 +3503,7 @@ name = "command_palette_hooks"
version = "0.1.0"
dependencies = [
"collections",
- "derive_more 0.99.19",
+ "derive_more",
"gpui",
"workspace-hack",
]
@@ -4662,27 +4666,6 @@ dependencies = [
"syn 2.0.101",
]
-[[package]]
-name = "derive_more"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
-dependencies = [
- "derive_more-impl",
-]
-
-[[package]]
-name = "derive_more-impl"
-version = "2.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.101",
- "unicode-xid",
-]
-
[[package]]
name = "derive_refineable"
version = "0.1.0"
@@ -4703,7 +4686,6 @@ dependencies = [
"component",
"ctor",
"editor",
- "futures 0.3.31",
"gpui",
"indoc",
"language",
@@ -6419,7 +6401,7 @@ dependencies = [
"askpass",
"async-trait",
"collections",
- "derive_more 0.99.19",
+ "derive_more",
"futures 0.3.31",
"git2",
"gpui",
@@ -7449,7 +7431,7 @@ dependencies = [
"core-video",
"cosmic-text",
"ctor",
- "derive_more 0.99.19",
+ "derive_more",
"embed-resource",
"env_logger 0.11.8",
"etagere",
@@ -7974,7 +7956,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"bytes 1.10.1",
- "derive_more 0.99.19",
+ "derive_more",
"futures 0.3.31",
"http 1.3.1",
"http-body 1.0.1",
@@ -8486,6 +8468,7 @@ dependencies = [
"theme",
"ui",
"util",
+ "util_macros",
"workspace",
"workspace-hack",
"zed_actions",
@@ -13538,6 +13521,7 @@ dependencies = [
"smol",
"sysinfo",
"telemetry_events",
+ "thiserror 2.0.12",
"toml 0.8.20",
"unindent",
"util",
@@ -14377,12 +14361,10 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe8c9d1c68d67dd9f97ecbc6f932b60eb289c5dbddd8aa1405484a8fd2fcd984"
dependencies = [
- "chrono",
"dyn-clone",
"indexmap",
"ref-cast",
"schemars_derive",
- "semver",
"serde",
"serde_json",
]
@@ -16466,7 +16448,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"collections",
- "derive_more 0.99.19",
+ "derive_more",
"fs",
"futures 0.3.31",
"gpui",
@@ -19807,7 +19789,6 @@ dependencies = [
"any_vec",
"anyhow",
"async-recursion",
- "bincode",
"call",
"client",
"clock",
@@ -19826,6 +19807,7 @@ dependencies = [
"node_runtime",
"parking_lot",
"postage",
+ "pretty_assertions",
"project",
"remote",
"schemars",
@@ -19981,7 +19963,6 @@ dependencies = [
"rustix 1.0.7",
"rustls 0.23.26",
"rustls-webpki 0.103.1",
- "schemars",
"scopeguard",
"sea-orm",
"sea-query-binder",
@@ -20417,6 +20398,7 @@ dependencies = [
name = "zed"
version = "0.202.0"
dependencies = [
+ "acp_tools",
"activity_indicator",
"agent",
"agent_servers",
diff --git a/Cargo.toml b/Cargo.toml
index 84de9b30ad..6ec243a9b9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,7 @@
[workspace]
resolver = "2"
members = [
+ "crates/acp_tools",
"crates/acp_thread",
"crates/action_log",
"crates/activity_indicator",
@@ -227,6 +228,7 @@ edition = "2024"
# Workspace member crates
#
+acp_tools = { path = "crates/acp_tools" }
acp_thread = { path = "crates/acp_thread" }
action_log = { path = "crates/action_log" }
agent = { path = "crates/agent" }
@@ -424,8 +426,7 @@ zlog_settings = { path = "crates/zlog_settings" }
# External crates
#
-agentic-coding-protocol = "0.0.10"
-agent-client-protocol = "0.0.30"
+agent-client-protocol = "0.0.31"
aho-corasick = "1.1"
alacritty_terminal = { git = "https://github.com/zed-industries/alacritty.git", branch = "add-hush-login-flag" }
any_vec = "0.14"
diff --git a/Procfile.web b/Procfile.web
new file mode 100644
index 0000000000..8140555144
--- /dev/null
+++ b/Procfile.web
@@ -0,0 +1,2 @@
+postgrest_llm: postgrest crates/collab/postgrest_llm.conf
+website: cd ../zed.dev; npm run dev -- --port=3000
diff --git a/assets/icons/copy.svg b/assets/icons/copy.svg
index bca13f8d56..aba193930b 100644
--- a/assets/icons/copy.svg
+++ b/assets/icons/copy.svg
@@ -1 +1,4 @@
-
+
diff --git a/assets/icons/terminal_ghost.svg b/assets/icons/terminal_ghost.svg
new file mode 100644
index 0000000000..7d0d0e068e
--- /dev/null
+++ b/assets/icons/terminal_ghost.svg
@@ -0,0 +1,4 @@
+
diff --git a/assets/images/acp_grid.svg b/assets/images/acp_grid.svg
new file mode 100644
index 0000000000..8ebff8e1bc
--- /dev/null
+++ b/assets/images/acp_grid.svg
@@ -0,0 +1,1257 @@
+
diff --git a/assets/images/acp_logo.svg b/assets/images/acp_logo.svg
new file mode 100644
index 0000000000..efaa46707b
--- /dev/null
+++ b/assets/images/acp_logo.svg
@@ -0,0 +1 @@
+
diff --git a/assets/images/acp_logo_serif.svg b/assets/images/acp_logo_serif.svg
new file mode 100644
index 0000000000..6bc359cf82
--- /dev/null
+++ b/assets/images/acp_logo_serif.svg
@@ -0,0 +1,2 @@
+
+
diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json
index 955e68f5a9..3cca560c00 100644
--- a/assets/keymaps/default-linux.json
+++ b/assets/keymaps/default-linux.json
@@ -16,7 +16,6 @@
"up": "menu::SelectPrevious",
"enter": "menu::Confirm",
"ctrl-enter": "menu::SecondaryConfirm",
- "ctrl-escape": "menu::Cancel",
"ctrl-c": "menu::Cancel",
"escape": "menu::Cancel",
"alt-shift-enter": "menu::Restart",
@@ -41,7 +40,7 @@
"shift-f11": "debugger::StepOut",
"f11": "zed::ToggleFullScreen",
"ctrl-alt-z": "edit_prediction::RateCompletions",
- "ctrl-shift-i": "edit_prediction::ToggleMenu",
+ "ctrl-alt-shift-i": "edit_prediction::ToggleMenu",
"ctrl-alt-l": "lsp_tool::ToggleMenu"
}
},
@@ -121,7 +120,7 @@
"alt-g m": "git::OpenModifiedFiles",
"menu": "editor::OpenContextMenu",
"shift-f10": "editor::OpenContextMenu",
- "ctrl-shift-e": "editor::ToggleEditPrediction",
+ "ctrl-alt-shift-e": "editor::ToggleEditPrediction",
"f9": "editor::ToggleBreakpoint",
"shift-f9": "editor::EditLogBreakpoint"
}
@@ -856,7 +855,7 @@
"ctrl-backspace": ["project_panel::Delete", { "skip_prompt": false }],
"ctrl-delete": ["project_panel::Delete", { "skip_prompt": false }],
"alt-ctrl-r": "project_panel::RevealInFileManager",
- "ctrl-shift-enter": "project_panel::OpenWithSystem",
+ "ctrl-shift-enter": "workspace::OpenWithSystem",
"alt-d": "project_panel::CompareMarkedFiles",
"shift-find": "project_panel::NewSearchInDirectory",
"ctrl-alt-shift-f": "project_panel::NewSearchInDirectory",
@@ -1195,9 +1194,16 @@
"ctrl-1": "onboarding::ActivateBasicsPage",
"ctrl-2": "onboarding::ActivateEditingPage",
"ctrl-3": "onboarding::ActivateAISetupPage",
- "ctrl-escape": "onboarding::Finish",
- "alt-tab": "onboarding::SignIn",
+ "ctrl-enter": "onboarding::Finish",
+ "alt-shift-l": "onboarding::SignIn",
"alt-shift-a": "onboarding::OpenAccount"
}
+ },
+ {
+ "context": "InvalidBuffer",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-enter": "workspace::OpenWithSystem"
+ }
}
]
diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json
index 8b18299a91..e72f4174ff 100644
--- a/assets/keymaps/default-macos.json
+++ b/assets/keymaps/default-macos.json
@@ -915,7 +915,7 @@
"cmd-backspace": ["project_panel::Trash", { "skip_prompt": true }],
"cmd-delete": ["project_panel::Delete", { "skip_prompt": false }],
"alt-cmd-r": "project_panel::RevealInFileManager",
- "ctrl-shift-enter": "project_panel::OpenWithSystem",
+ "ctrl-shift-enter": "workspace::OpenWithSystem",
"alt-d": "project_panel::CompareMarkedFiles",
"cmd-alt-backspace": ["project_panel::Delete", { "skip_prompt": false }],
"cmd-alt-shift-f": "project_panel::NewSearchInDirectory",
@@ -1301,5 +1301,12 @@
"alt-tab": "onboarding::SignIn",
"alt-shift-a": "onboarding::OpenAccount"
}
+ },
+ {
+ "context": "InvalidBuffer",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-enter": "workspace::OpenWithSystem"
+ }
}
]
diff --git a/assets/keymaps/default-windows.json b/assets/keymaps/default-windows.json
new file mode 100644
index 0000000000..c7a6c3149c
--- /dev/null
+++ b/assets/keymaps/default-windows.json
@@ -0,0 +1,1260 @@
+[
+ // Standard Windows bindings
+ {
+ "use_key_equivalents": true,
+ "bindings": {
+ "home": "menu::SelectFirst",
+ "shift-pageup": "menu::SelectFirst",
+ "pageup": "menu::SelectFirst",
+ "end": "menu::SelectLast",
+ "shift-pagedown": "menu::SelectLast",
+ "pagedown": "menu::SelectLast",
+ "ctrl-n": "menu::SelectNext",
+ "tab": "menu::SelectNext",
+ "down": "menu::SelectNext",
+ "ctrl-p": "menu::SelectPrevious",
+ "shift-tab": "menu::SelectPrevious",
+ "up": "menu::SelectPrevious",
+ "enter": "menu::Confirm",
+ "ctrl-enter": "menu::SecondaryConfirm",
+ "ctrl-escape": "menu::Cancel",
+ "ctrl-c": "menu::Cancel",
+ "escape": "menu::Cancel",
+ "shift-alt-enter": "menu::Restart",
+ "alt-enter": ["picker::ConfirmInput", { "secondary": false }],
+ "ctrl-alt-enter": ["picker::ConfirmInput", { "secondary": true }],
+ "ctrl-shift-w": "workspace::CloseWindow",
+ "shift-escape": "workspace::ToggleZoom",
+ "open": "workspace::Open",
+ "ctrl-o": "workspace::Open",
+ "ctrl-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
+ "ctrl-shift-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
+ "ctrl--": ["zed::DecreaseBufferFontSize", { "persist": false }],
+ "ctrl-0": ["zed::ResetBufferFontSize", { "persist": false }],
+ "ctrl-,": "zed::OpenSettings",
+ "ctrl-q": "zed::Quit",
+ "f4": "debugger::Start",
+ "shift-f5": "debugger::Stop",
+ "ctrl-shift-f5": "debugger::RerunSession",
+ "f6": "debugger::Pause",
+ "f7": "debugger::StepOver",
+ "ctrl-f11": "debugger::StepInto",
+ "shift-f11": "debugger::StepOut",
+ "f11": "zed::ToggleFullScreen",
+ "ctrl-shift-i": "edit_prediction::ToggleMenu",
+ "shift-alt-l": "lsp_tool::ToggleMenu"
+ }
+ },
+ {
+ "context": "Picker || menu",
+ "use_key_equivalents": true,
+ "bindings": {
+ "up": "menu::SelectPrevious",
+ "down": "menu::SelectNext"
+ }
+ },
+ {
+ "context": "Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "editor::Cancel",
+ "shift-backspace": "editor::Backspace",
+ "backspace": "editor::Backspace",
+ "delete": "editor::Delete",
+ "tab": "editor::Tab",
+ "shift-tab": "editor::Backtab",
+ "ctrl-k": "editor::CutToEndOfLine",
+ "ctrl-k ctrl-q": "editor::Rewrap",
+ "ctrl-k q": "editor::Rewrap",
+ "ctrl-backspace": "editor::DeleteToPreviousWordStart",
+ "ctrl-delete": "editor::DeleteToNextWordEnd",
+ "cut": "editor::Cut",
+ "shift-delete": "editor::Cut",
+ "ctrl-x": "editor::Cut",
+ "copy": "editor::Copy",
+ "ctrl-insert": "editor::Copy",
+ "ctrl-c": "editor::Copy",
+ "paste": "editor::Paste",
+ "shift-insert": "editor::Paste",
+ "ctrl-v": "editor::Paste",
+ "undo": "editor::Undo",
+ "ctrl-z": "editor::Undo",
+ "redo": "editor::Redo",
+ "ctrl-y": "editor::Redo",
+ "ctrl-shift-z": "editor::Redo",
+ "up": "editor::MoveUp",
+ "ctrl-up": "editor::LineUp",
+ "ctrl-down": "editor::LineDown",
+ "pageup": "editor::MovePageUp",
+ "alt-pageup": "editor::PageUp",
+ "shift-pageup": "editor::SelectPageUp",
+ "home": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
+ "down": "editor::MoveDown",
+ "pagedown": "editor::MovePageDown",
+ "alt-pagedown": "editor::PageDown",
+ "shift-pagedown": "editor::SelectPageDown",
+ "end": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
+ "left": "editor::MoveLeft",
+ "right": "editor::MoveRight",
+ "ctrl-left": "editor::MoveToPreviousWordStart",
+ "ctrl-right": "editor::MoveToNextWordEnd",
+ "ctrl-home": "editor::MoveToBeginning",
+ "ctrl-end": "editor::MoveToEnd",
+ "shift-up": "editor::SelectUp",
+ "shift-down": "editor::SelectDown",
+ "shift-left": "editor::SelectLeft",
+ "shift-right": "editor::SelectRight",
+ "ctrl-shift-left": "editor::SelectToPreviousWordStart",
+ "ctrl-shift-right": "editor::SelectToNextWordEnd",
+ "ctrl-shift-home": "editor::SelectToBeginning",
+ "ctrl-shift-end": "editor::SelectToEnd",
+ "ctrl-a": "editor::SelectAll",
+ "ctrl-l": "editor::SelectLine",
+ "shift-alt-f": "editor::Format",
+ "shift-alt-o": "editor::OrganizeImports",
+ "shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
+ "shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
+ "ctrl-alt-space": "editor::ShowCharacterPalette",
+ "ctrl-;": "editor::ToggleLineNumbers",
+ "ctrl-'": "editor::ToggleSelectedDiffHunks",
+ "ctrl-\"": "editor::ExpandAllDiffHunks",
+ "ctrl-i": "editor::ShowSignatureHelp",
+ "alt-g b": "git::Blame",
+ "alt-g m": "git::OpenModifiedFiles",
+ "menu": "editor::OpenContextMenu",
+ "shift-f10": "editor::OpenContextMenu",
+ "ctrl-shift-e": "editor::ToggleEditPrediction",
+ "f9": "editor::ToggleBreakpoint",
+ "shift-f9": "editor::EditLogBreakpoint"
+ }
+ },
+ {
+ "context": "Editor && mode == full",
+ "use_key_equivalents": true,
+ "bindings": {
+ "shift-enter": "editor::Newline",
+ "enter": "editor::Newline",
+ "ctrl-enter": "editor::NewlineAbove",
+ "ctrl-shift-enter": "editor::NewlineBelow",
+ "ctrl-k ctrl-z": "editor::ToggleSoftWrap",
+ "ctrl-k z": "editor::ToggleSoftWrap",
+ "find": "buffer_search::Deploy",
+ "ctrl-f": "buffer_search::Deploy",
+ "ctrl-h": "buffer_search::DeployReplace",
+ "ctrl-shift-.": "assistant::QuoteSelection",
+ "ctrl-shift-,": "assistant::InsertIntoEditor",
+ "shift-alt-e": "editor::SelectEnclosingSymbol",
+ "ctrl-shift-backspace": "editor::GoToPreviousChange",
+ "ctrl-shift-alt-backspace": "editor::GoToNextChange",
+ "alt-enter": "editor::OpenSelectionsInMultibuffer"
+ }
+ },
+ {
+ "context": "Editor && mode == full && edit_prediction",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-]": "editor::NextEditPrediction",
+ "alt-[": "editor::PreviousEditPrediction"
+ }
+ },
+ {
+ "context": "Editor && !edit_prediction",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-\\": "editor::ShowEditPrediction"
+ }
+ },
+ {
+ "context": "Editor && mode == auto_height",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-enter": "editor::Newline",
+ "shift-enter": "editor::Newline",
+ "ctrl-shift-enter": "editor::NewlineBelow"
+ }
+ },
+ {
+ "context": "Markdown",
+ "use_key_equivalents": true,
+ "bindings": {
+ "copy": "markdown::Copy",
+ "ctrl-c": "markdown::Copy"
+ }
+ },
+ {
+ "context": "Editor && jupyter && !ContextEditor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-enter": "repl::Run",
+ "ctrl-alt-enter": "repl::RunInPlace"
+ }
+ },
+ {
+ "context": "Editor && !agent_diff",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-k ctrl-r": "git::Restore",
+ "alt-y": "git::StageAndNext",
+ "shift-alt-y": "git::UnstageAndNext"
+ }
+ },
+ {
+ "context": "Editor && editor_agent_diff",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-y": "agent::Keep",
+ "ctrl-n": "agent::Reject",
+ "ctrl-shift-y": "agent::KeepAll",
+ "ctrl-shift-n": "agent::RejectAll",
+ "ctrl-shift-r": "agent::OpenAgentDiff"
+ }
+ },
+ {
+ "context": "AgentDiff",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-y": "agent::Keep",
+ "ctrl-n": "agent::Reject",
+ "ctrl-shift-y": "agent::KeepAll",
+ "ctrl-shift-n": "agent::RejectAll"
+ }
+ },
+ {
+ "context": "ContextEditor > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-enter": "assistant::Assist",
+ "ctrl-s": "workspace::Save",
+ "save": "workspace::Save",
+ "ctrl-shift-,": "assistant::InsertIntoEditor",
+ "shift-enter": "assistant::Split",
+ "ctrl-r": "assistant::CycleMessageRole",
+ "enter": "assistant::ConfirmCommand",
+ "alt-enter": "editor::Newline",
+ "ctrl-k c": "assistant::CopyCode",
+ "ctrl-g": "search::SelectNextMatch",
+ "ctrl-shift-g": "search::SelectPreviousMatch",
+ "ctrl-k l": "agent::OpenRulesLibrary"
+ }
+ },
+ {
+ "context": "AgentPanel",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-n": "agent::NewThread",
+ "shift-alt-n": "agent::NewTextThread",
+ "ctrl-shift-h": "agent::OpenHistory",
+ "shift-alt-c": "agent::OpenSettings",
+ "shift-alt-p": "agent::OpenRulesLibrary",
+ "ctrl-i": "agent::ToggleProfileSelector",
+ "shift-alt-/": "agent::ToggleModelSelector",
+ "ctrl-shift-a": "agent::ToggleContextPicker",
+ "ctrl-shift-j": "agent::ToggleNavigationMenu",
+ "ctrl-shift-i": "agent::ToggleOptionsMenu",
+ // "ctrl-shift-alt-n": "agent::ToggleNewThreadMenu",
+ "shift-alt-escape": "agent::ExpandMessageEditor",
+ "ctrl-shift-.": "assistant::QuoteSelection",
+ "shift-alt-e": "agent::RemoveAllContext",
+ "ctrl-shift-e": "project_panel::ToggleFocus",
+ "ctrl-shift-enter": "agent::ContinueThread",
+ "super-ctrl-b": "agent::ToggleBurnMode",
+ "alt-enter": "agent::ContinueWithBurnMode"
+ }
+ },
+ {
+ "context": "AgentPanel > NavigationMenu",
+ "use_key_equivalents": true,
+ "bindings": {
+ "shift-backspace": "agent::DeleteRecentlyOpenThread"
+ }
+ },
+ {
+ "context": "AgentPanel > Markdown",
+ "use_key_equivalents": true,
+ "bindings": {
+ "copy": "markdown::CopyAsMarkdown",
+ "ctrl-c": "markdown::CopyAsMarkdown"
+ }
+ },
+ {
+ "context": "AgentPanel && prompt_editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-n": "agent::NewTextThread",
+ "ctrl-alt-t": "agent::NewThread"
+ }
+ },
+ {
+ "context": "AgentPanel && external_agent_thread",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-n": "agent::NewExternalAgentThread",
+ "ctrl-alt-t": "agent::NewThread"
+ }
+ },
+ {
+ "context": "MessageEditor && !Picker > Editor && !use_modifier_to_send",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "agent::Chat",
+ "ctrl-enter": "agent::ChatWithFollow",
+ "ctrl-i": "agent::ToggleProfileSelector",
+ "ctrl-shift-r": "agent::OpenAgentDiff",
+ "ctrl-shift-y": "agent::KeepAll",
+ "ctrl-shift-n": "agent::RejectAll"
+ }
+ },
+ {
+ "context": "MessageEditor && !Picker > Editor && use_modifier_to_send",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-enter": "agent::Chat",
+ "enter": "editor::Newline",
+ "ctrl-i": "agent::ToggleProfileSelector",
+ "ctrl-shift-r": "agent::OpenAgentDiff",
+ "ctrl-shift-y": "agent::KeepAll",
+ "ctrl-shift-n": "agent::RejectAll"
+ }
+ },
+ {
+ "context": "EditMessageEditor > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "menu::Cancel",
+ "enter": "menu::Confirm",
+ "alt-enter": "editor::Newline"
+ }
+ },
+ {
+ "context": "AgentFeedbackMessageEditor > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "menu::Cancel",
+ "enter": "menu::Confirm",
+ "alt-enter": "editor::Newline"
+ }
+ },
+ {
+ "context": "ContextStrip",
+ "use_key_equivalents": true,
+ "bindings": {
+ "up": "agent::FocusUp",
+ "right": "agent::FocusRight",
+ "left": "agent::FocusLeft",
+ "down": "agent::FocusDown",
+ "backspace": "agent::RemoveFocusedContext",
+ "enter": "agent::AcceptSuggestedContext"
+ }
+ },
+ {
+ "context": "AcpThread > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "agent::Chat",
+ "ctrl-shift-r": "agent::OpenAgentDiff",
+ "ctrl-shift-y": "agent::KeepAll",
+ "ctrl-shift-n": "agent::RejectAll"
+ }
+ },
+ {
+ "context": "ThreadHistory",
+ "use_key_equivalents": true,
+ "bindings": {
+ "backspace": "agent::RemoveSelectedThread"
+ }
+ },
+ {
+ "context": "PromptLibrary",
+ "use_key_equivalents": true,
+ "bindings": {
+ "new": "rules_library::NewRule",
+ "ctrl-n": "rules_library::NewRule",
+ "ctrl-shift-s": "rules_library::ToggleDefaultRule"
+ }
+ },
+ {
+ "context": "BufferSearchBar",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "buffer_search::Dismiss",
+ "tab": "buffer_search::FocusEditor",
+ "enter": "search::SelectNextMatch",
+ "shift-enter": "search::SelectPreviousMatch",
+ "alt-enter": "search::SelectAllMatches",
+ "find": "search::FocusSearch",
+ "ctrl-f": "search::FocusSearch",
+ "ctrl-h": "search::ToggleReplace",
+ "ctrl-l": "search::ToggleSelection"
+ }
+ },
+ {
+ "context": "BufferSearchBar && in_replace > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "search::ReplaceNext",
+ "ctrl-enter": "search::ReplaceAll"
+ }
+ },
+ {
+ "context": "BufferSearchBar && !in_replace > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "up": "search::PreviousHistoryQuery",
+ "down": "search::NextHistoryQuery"
+ }
+ },
+ {
+ "context": "ProjectSearchBar",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "project_search::ToggleFocus",
+ "shift-find": "search::FocusSearch",
+ "ctrl-shift-f": "search::FocusSearch",
+ "ctrl-shift-h": "search::ToggleReplace",
+ "alt-r": "search::ToggleRegex" // vscode
+ }
+ },
+ {
+ "context": "ProjectSearchBar > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "up": "search::PreviousHistoryQuery",
+ "down": "search::NextHistoryQuery"
+ }
+ },
+ {
+ "context": "ProjectSearchBar && in_replace > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "search::ReplaceNext",
+ "ctrl-alt-enter": "search::ReplaceAll"
+ }
+ },
+ {
+ "context": "ProjectSearchView",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "project_search::ToggleFocus",
+ "ctrl-shift-h": "search::ToggleReplace",
+ "alt-r": "search::ToggleRegex" // vscode
+ }
+ },
+ {
+ "context": "Pane",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-1": ["pane::ActivateItem", 0],
+ "alt-2": ["pane::ActivateItem", 1],
+ "alt-3": ["pane::ActivateItem", 2],
+ "alt-4": ["pane::ActivateItem", 3],
+ "alt-5": ["pane::ActivateItem", 4],
+ "alt-6": ["pane::ActivateItem", 5],
+ "alt-7": ["pane::ActivateItem", 6],
+ "alt-8": ["pane::ActivateItem", 7],
+ "alt-9": ["pane::ActivateItem", 8],
+ "alt-0": "pane::ActivateLastItem",
+ "ctrl-pageup": "pane::ActivatePreviousItem",
+ "ctrl-pagedown": "pane::ActivateNextItem",
+ "ctrl-shift-pageup": "pane::SwapItemLeft",
+ "ctrl-shift-pagedown": "pane::SwapItemRight",
+ "ctrl-f4": ["pane::CloseActiveItem", { "close_pinned": false }],
+ "ctrl-w": ["pane::CloseActiveItem", { "close_pinned": false }],
+ "ctrl-shift-alt-t": ["pane::CloseOtherItems", { "close_pinned": false }],
+ "ctrl-shift-alt-w": "workspace::CloseInactiveTabsAndPanes",
+ "ctrl-k e": ["pane::CloseItemsToTheLeft", { "close_pinned": false }],
+ "ctrl-k t": ["pane::CloseItemsToTheRight", { "close_pinned": false }],
+ "ctrl-k u": ["pane::CloseCleanItems", { "close_pinned": false }],
+ "ctrl-k w": ["pane::CloseAllItems", { "close_pinned": false }],
+ "ctrl-k ctrl-w": "workspace::CloseAllItemsAndPanes",
+ "back": "pane::GoBack",
+ "alt--": "pane::GoBack",
+ "alt-=": "pane::GoForward",
+ "forward": "pane::GoForward",
+ "f3": "search::SelectNextMatch",
+ "shift-f3": "search::SelectPreviousMatch",
+ "shift-find": "project_search::ToggleFocus",
+ "ctrl-shift-f": "project_search::ToggleFocus",
+ "shift-alt-h": "search::ToggleReplace",
+ "alt-l": "search::ToggleSelection",
+ "alt-enter": "search::SelectAllMatches",
+ "alt-c": "search::ToggleCaseSensitive",
+ "alt-w": "search::ToggleWholeWord",
+ "alt-find": "project_search::ToggleFilters",
+ "alt-f": "project_search::ToggleFilters",
+ "alt-r": "search::ToggleRegex",
+ // "ctrl-shift-alt-x": "search::ToggleRegex",
+ "ctrl-k shift-enter": "pane::TogglePinTab"
+ }
+ },
+ // Bindings from VS Code
+ {
+ "context": "Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-[": "editor::Outdent",
+ "ctrl-]": "editor::Indent",
+ "ctrl-shift-alt-up": "editor::AddSelectionAbove", // Insert Cursor Above
+ "ctrl-shift-alt-down": "editor::AddSelectionBelow", // Insert Cursor Below
+ "ctrl-shift-k": "editor::DeleteLine",
+ "alt-up": "editor::MoveLineUp",
+ "alt-down": "editor::MoveLineDown",
+ "shift-alt-up": "editor::DuplicateLineUp",
+ "shift-alt-down": "editor::DuplicateLineDown",
+ "shift-alt-right": "editor::SelectLargerSyntaxNode", // Expand Selection
+ "shift-alt-left": "editor::SelectSmallerSyntaxNode", // Shrink Selection
+ "ctrl-shift-l": "editor::SelectAllMatches", // Select all occurrences of current selection
+ "ctrl-f2": "editor::SelectAllMatches", // Select all occurrences of current word
+ "ctrl-d": ["editor::SelectNext", { "replace_newest": false }], // editor.action.addSelectionToNextFindMatch / find_under_expand
+ "ctrl-shift-down": ["editor::SelectNext", { "replace_newest": false }], // editor.action.addSelectionToNextFindMatch
+ "ctrl-shift-up": ["editor::SelectPrevious", { "replace_newest": false }], // editor.action.addSelectionToPreviousFindMatch
+ "ctrl-k ctrl-d": ["editor::SelectNext", { "replace_newest": true }], // editor.action.moveSelectionToNextFindMatch / find_under_expand_skip
+ "ctrl-k ctrl-shift-d": ["editor::SelectPrevious", { "replace_newest": true }], // editor.action.moveSelectionToPreviousFindMatch
+ "ctrl-k ctrl-i": "editor::Hover",
+ "ctrl-k ctrl-b": "editor::BlameHover",
+ "ctrl-/": ["editor::ToggleComments", { "advance_downwards": false }],
+ "f8": ["editor::GoToDiagnostic", { "severity": { "min": "hint", "max": "error" } }],
+ "shift-f8": ["editor::GoToPreviousDiagnostic", { "severity": { "min": "hint", "max": "error" } }],
+ "f2": "editor::Rename",
+ "f12": "editor::GoToDefinition",
+ "alt-f12": "editor::GoToDefinitionSplit",
+ "ctrl-shift-f10": "editor::GoToDefinitionSplit",
+ "ctrl-f12": "editor::GoToImplementation",
+ "shift-f12": "editor::GoToTypeDefinition",
+ "ctrl-alt-f12": "editor::GoToTypeDefinitionSplit",
+ "shift-alt-f12": "editor::FindAllReferences",
+ "ctrl-m": "editor::MoveToEnclosingBracket", // from jetbrains
+ "ctrl-shift-\\": "editor::MoveToEnclosingBracket",
+ "ctrl-shift-[": "editor::Fold",
+ "ctrl-shift-]": "editor::UnfoldLines",
+ "ctrl-k ctrl-l": "editor::ToggleFold",
+ "ctrl-k ctrl-[": "editor::FoldRecursive",
+ "ctrl-k ctrl-]": "editor::UnfoldRecursive",
+ "ctrl-k ctrl-1": ["editor::FoldAtLevel", 1],
+ "ctrl-k ctrl-2": ["editor::FoldAtLevel", 2],
+ "ctrl-k ctrl-3": ["editor::FoldAtLevel", 3],
+ "ctrl-k ctrl-4": ["editor::FoldAtLevel", 4],
+ "ctrl-k ctrl-5": ["editor::FoldAtLevel", 5],
+ "ctrl-k ctrl-6": ["editor::FoldAtLevel", 6],
+ "ctrl-k ctrl-7": ["editor::FoldAtLevel", 7],
+ "ctrl-k ctrl-8": ["editor::FoldAtLevel", 8],
+ "ctrl-k ctrl-9": ["editor::FoldAtLevel", 9],
+ "ctrl-k ctrl-0": "editor::FoldAll",
+ "ctrl-k ctrl-j": "editor::UnfoldAll",
+ "ctrl-space": "editor::ShowCompletions",
+ "ctrl-shift-space": "editor::ShowWordCompletions",
+ "ctrl-.": "editor::ToggleCodeActions",
+ "ctrl-k r": "editor::RevealInFileManager",
+ "ctrl-k p": "editor::CopyPath",
+ "ctrl-\\": "pane::SplitRight",
+ "ctrl-shift-alt-c": "editor::DisplayCursorNames",
+ "alt-.": "editor::GoToHunk",
+ "alt-,": "editor::GoToPreviousHunk"
+ }
+ },
+ {
+ "context": "Editor && extension == md",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-k v": "markdown::OpenPreviewToTheSide",
+ "ctrl-shift-v": "markdown::OpenPreview"
+ }
+ },
+ {
+ "context": "Editor && extension == svg",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-k v": "svg::OpenPreviewToTheSide",
+ "ctrl-shift-v": "svg::OpenPreview"
+ }
+ },
+ {
+ "context": "Editor && mode == full",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-o": "outline::Toggle",
+ "ctrl-g": "go_to_line::Toggle"
+ }
+ },
+ {
+ "context": "Workspace",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-open": ["projects::OpenRecent", { "create_new_window": false }],
+ // Change the default action on `menu::Confirm` by setting the parameter
+ // "ctrl-alt-o": ["projects::OpenRecent", { "create_new_window": true }],
+ "ctrl-r": ["projects::OpenRecent", { "create_new_window": false }],
+ "shift-alt-open": ["projects::OpenRemote", { "from_existing_connection": false, "create_new_window": false }],
+ // Change to open path modal for existing remote connection by setting the parameter
+ // "ctrl-shift-alt-o": "["projects::OpenRemote", { "from_existing_connection": true }]",
+ "ctrl-shift-alt-o": ["projects::OpenRemote", { "from_existing_connection": false, "create_new_window": false }],
+ "shift-alt-b": "branches::OpenRecent",
+ "shift-alt-enter": "toast::RunAction",
+ "ctrl-shift-`": "workspace::NewTerminal",
+ "save": "workspace::Save",
+ "ctrl-s": "workspace::Save",
+ "ctrl-k ctrl-shift-s": "workspace::SaveWithoutFormat",
+ "shift-save": "workspace::SaveAs",
+ "ctrl-shift-s": "workspace::SaveAs",
+ "new": "workspace::NewFile",
+ "ctrl-n": "workspace::NewFile",
+ "shift-new": "workspace::NewWindow",
+ "ctrl-shift-n": "workspace::NewWindow",
+ "ctrl-`": "terminal_panel::ToggleFocus",
+ "f10": ["app_menu::OpenApplicationMenu", "Zed"],
+ "alt-1": ["workspace::ActivatePane", 0],
+ "alt-2": ["workspace::ActivatePane", 1],
+ "alt-3": ["workspace::ActivatePane", 2],
+ "alt-4": ["workspace::ActivatePane", 3],
+ "alt-5": ["workspace::ActivatePane", 4],
+ "alt-6": ["workspace::ActivatePane", 5],
+ "alt-7": ["workspace::ActivatePane", 6],
+ "alt-8": ["workspace::ActivatePane", 7],
+ "alt-9": ["workspace::ActivatePane", 8],
+ "ctrl-alt-b": "workspace::ToggleRightDock",
+ "ctrl-b": "workspace::ToggleLeftDock",
+ "ctrl-j": "workspace::ToggleBottomDock",
+ "ctrl-shift-y": "workspace::CloseAllDocks",
+ "alt-r": "workspace::ResetActiveDockSize",
+ // For 0px parameter, uses UI font size value.
+ "shift-alt--": ["workspace::DecreaseActiveDockSize", { "px": 0 }],
+ "shift-alt-=": ["workspace::IncreaseActiveDockSize", { "px": 0 }],
+ "shift-alt-0": "workspace::ResetOpenDocksSize",
+ "ctrl-shift-alt--": ["workspace::DecreaseOpenDocksSize", { "px": 0 }],
+ "ctrl-shift-alt-=": ["workspace::IncreaseOpenDocksSize", { "px": 0 }],
+ "shift-find": "pane::DeploySearch",
+ "ctrl-shift-f": "pane::DeploySearch",
+ "ctrl-shift-h": ["pane::DeploySearch", { "replace_enabled": true }],
+ "ctrl-shift-t": "pane::ReopenClosedItem",
+ "ctrl-k ctrl-s": "zed::OpenKeymapEditor",
+ "ctrl-k ctrl-t": "theme_selector::Toggle",
+ "ctrl-alt-super-p": "settings_profile_selector::Toggle",
+ "ctrl-t": "project_symbols::Toggle",
+ "ctrl-p": "file_finder::Toggle",
+ "ctrl-tab": "tab_switcher::Toggle",
+ "ctrl-shift-tab": ["tab_switcher::Toggle", { "select_last": true }],
+ "ctrl-e": "file_finder::Toggle",
+ "f1": "command_palette::Toggle",
+ "ctrl-shift-p": "command_palette::Toggle",
+ "ctrl-shift-m": "diagnostics::Deploy",
+ "ctrl-shift-e": "project_panel::ToggleFocus",
+ "ctrl-shift-b": "outline_panel::ToggleFocus",
+ "ctrl-shift-g": "git_panel::ToggleFocus",
+ "ctrl-shift-d": "debug_panel::ToggleFocus",
+ "ctrl-shift-/": "agent::ToggleFocus",
+ "alt-save": "workspace::SaveAll",
+ "ctrl-k s": "workspace::SaveAll",
+ "ctrl-k m": "language_selector::Toggle",
+ "escape": "workspace::Unfollow",
+ "ctrl-k ctrl-left": "workspace::ActivatePaneLeft",
+ "ctrl-k ctrl-right": "workspace::ActivatePaneRight",
+ "ctrl-k ctrl-up": "workspace::ActivatePaneUp",
+ "ctrl-k ctrl-down": "workspace::ActivatePaneDown",
+ "ctrl-k shift-left": "workspace::SwapPaneLeft",
+ "ctrl-k shift-right": "workspace::SwapPaneRight",
+ "ctrl-k shift-up": "workspace::SwapPaneUp",
+ "ctrl-k shift-down": "workspace::SwapPaneDown",
+ "ctrl-shift-x": "zed::Extensions",
+ "ctrl-shift-r": "task::Rerun",
+ "alt-t": "task::Rerun",
+ "shift-alt-t": "task::Spawn",
+ "shift-alt-r": ["task::Spawn", { "reveal_target": "center" }],
+ // also possible to spawn tasks by name:
+ // "foo-bar": ["task::Spawn", { "task_name": "MyTask", "reveal_target": "dock" }]
+ // or by tag:
+ // "foo-bar": ["task::Spawn", { "task_tag": "MyTag" }],
+ "f5": "debugger::Rerun",
+ "ctrl-f4": "workspace::CloseActiveDock",
+ "ctrl-w": "workspace::CloseActiveDock"
+ }
+ },
+ {
+ "context": "Workspace && debugger_running",
+ "use_key_equivalents": true,
+ "bindings": {
+ "f5": "zed::NoAction"
+ }
+ },
+ {
+ "context": "Workspace && debugger_stopped",
+ "use_key_equivalents": true,
+ "bindings": {
+ "f5": "debugger::Continue"
+ }
+ },
+ {
+ "context": "ApplicationMenu",
+ "use_key_equivalents": true,
+ "bindings": {
+ "f10": "menu::Cancel",
+ "left": "app_menu::ActivateMenuLeft",
+ "right": "app_menu::ActivateMenuRight"
+ }
+ },
+ // Bindings from Sublime Text
+ {
+ "context": "Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-u": "editor::UndoSelection",
+ "ctrl-shift-u": "editor::RedoSelection",
+ "ctrl-shift-j": "editor::JoinLines",
+ "ctrl-alt-backspace": "editor::DeleteToPreviousSubwordStart",
+ "shift-alt-h": "editor::DeleteToPreviousSubwordStart",
+ "ctrl-alt-delete": "editor::DeleteToNextSubwordEnd",
+ "shift-alt-d": "editor::DeleteToNextSubwordEnd",
+ "ctrl-alt-left": "editor::MoveToPreviousSubwordStart",
+ "ctrl-alt-right": "editor::MoveToNextSubwordEnd",
+ "ctrl-shift-alt-left": "editor::SelectToPreviousSubwordStart",
+ "ctrl-shift-alt-right": "editor::SelectToNextSubwordEnd"
+ }
+ },
+ // Bindings from Atom
+ {
+ "context": "Pane",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-k up": "pane::SplitUp",
+ "ctrl-k down": "pane::SplitDown",
+ "ctrl-k left": "pane::SplitLeft",
+ "ctrl-k right": "pane::SplitRight"
+ }
+ },
+ // Bindings that should be unified with bindings for more general actions
+ {
+ "context": "Editor && renaming",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "editor::ConfirmRename"
+ }
+ },
+ {
+ "context": "Editor && showing_completions",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "editor::ConfirmCompletion",
+ "shift-enter": "editor::ConfirmCompletionReplace",
+ "tab": "editor::ComposeCompletion"
+ }
+ },
+ // Bindings for accepting edit predictions
+ //
+ // alt-l is provided as an alternative to tab/alt-tab. and will be displayed in the UI. This is
+ // because alt-tab may not be available, as it is often used for window switching.
+ {
+ "context": "Editor && edit_prediction",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-tab": "editor::AcceptEditPrediction",
+ "alt-l": "editor::AcceptEditPrediction",
+ "tab": "editor::AcceptEditPrediction",
+ "alt-right": "editor::AcceptPartialEditPrediction"
+ }
+ },
+ {
+ "context": "Editor && edit_prediction_conflict",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-tab": "editor::AcceptEditPrediction",
+ "alt-l": "editor::AcceptEditPrediction",
+ "alt-right": "editor::AcceptPartialEditPrediction"
+ }
+ },
+ {
+ "context": "Editor && showing_code_actions",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "editor::ConfirmCodeAction"
+ }
+ },
+ {
+ "context": "Editor && (showing_code_actions || showing_completions)",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-p": "editor::ContextMenuPrevious",
+ "up": "editor::ContextMenuPrevious",
+ "ctrl-n": "editor::ContextMenuNext",
+ "down": "editor::ContextMenuNext",
+ "pageup": "editor::ContextMenuFirst",
+ "pagedown": "editor::ContextMenuLast"
+ }
+ },
+ {
+ "context": "Editor && showing_signature_help && !showing_completions",
+ "use_key_equivalents": true,
+ "bindings": {
+ "up": "editor::SignatureHelpPrevious",
+ "down": "editor::SignatureHelpNext"
+ }
+ },
+ // Custom bindings
+ {
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-alt-f": "workspace::FollowNextCollaborator",
+ // Only available in debug builds: opens an element inspector for development.
+ "shift-alt-i": "dev::ToggleInspector"
+ }
+ },
+ {
+ "context": "!Terminal",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-c": "collab_panel::ToggleFocus"
+ }
+ },
+ {
+ "context": "!ContextEditor > Editor && mode == full",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-enter": "editor::OpenExcerpts",
+ "shift-enter": "editor::ExpandExcerpts",
+ "ctrl-alt-enter": "editor::OpenExcerptsSplit",
+ "ctrl-shift-e": "pane::RevealInProjectPanel",
+ "ctrl-f8": "editor::GoToHunk",
+ "ctrl-shift-f8": "editor::GoToPreviousHunk",
+ "ctrl-enter": "assistant::InlineAssist",
+ "ctrl-shift-;": "editor::ToggleInlayHints"
+ }
+ },
+ {
+ "context": "PromptEditor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-[": "agent::CyclePreviousInlineAssist",
+ "ctrl-]": "agent::CycleNextInlineAssist",
+ "shift-alt-e": "agent::RemoveAllContext"
+ }
+ },
+ {
+ "context": "Prompt",
+ "use_key_equivalents": true,
+ "bindings": {
+ "left": "menu::SelectPrevious",
+ "right": "menu::SelectNext",
+ "h": "menu::SelectPrevious",
+ "l": "menu::SelectNext"
+ }
+ },
+ {
+ "context": "ProjectSearchBar && !in_replace",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-enter": "project_search::SearchInNew"
+ }
+ },
+ {
+ "context": "OutlinePanel && not_editing",
+ "use_key_equivalents": true,
+ "bindings": {
+ "left": "outline_panel::CollapseSelectedEntry",
+ "right": "outline_panel::ExpandSelectedEntry",
+ "alt-copy": "outline_panel::CopyPath",
+ "shift-alt-c": "outline_panel::CopyPath",
+ "shift-alt-copy": "workspace::CopyRelativePath",
+ "ctrl-shift-alt-c": "workspace::CopyRelativePath",
+ "ctrl-alt-r": "outline_panel::RevealInFileManager",
+ "space": "outline_panel::OpenSelectedEntry",
+ "shift-down": "menu::SelectNext",
+ "shift-up": "menu::SelectPrevious",
+ "alt-enter": "editor::OpenExcerpts",
+ "ctrl-alt-enter": "editor::OpenExcerptsSplit"
+ }
+ },
+ {
+ "context": "ProjectPanel",
+ "use_key_equivalents": true,
+ "bindings": {
+ "left": "project_panel::CollapseSelectedEntry",
+ "right": "project_panel::ExpandSelectedEntry",
+ "new": "project_panel::NewFile",
+ "ctrl-n": "project_panel::NewFile",
+ "alt-new": "project_panel::NewDirectory",
+ "alt-n": "project_panel::NewDirectory",
+ "cut": "project_panel::Cut",
+ "ctrl-x": "project_panel::Cut",
+ "copy": "project_panel::Copy",
+ "ctrl-insert": "project_panel::Copy",
+ "ctrl-c": "project_panel::Copy",
+ "paste": "project_panel::Paste",
+ "shift-insert": "project_panel::Paste",
+ "ctrl-v": "project_panel::Paste",
+ "alt-copy": "project_panel::CopyPath",
+ "shift-alt-c": "project_panel::CopyPath",
+ "shift-alt-copy": "workspace::CopyRelativePath",
+ "ctrl-k ctrl-shift-c": "workspace::CopyRelativePath",
+ "enter": "project_panel::Rename",
+ "f2": "project_panel::Rename",
+ "backspace": ["project_panel::Trash", { "skip_prompt": false }],
+ "delete": ["project_panel::Trash", { "skip_prompt": false }],
+ "shift-delete": ["project_panel::Delete", { "skip_prompt": false }],
+ "ctrl-backspace": ["project_panel::Delete", { "skip_prompt": false }],
+ "ctrl-delete": ["project_panel::Delete", { "skip_prompt": false }],
+ "ctrl-alt-r": "project_panel::RevealInFileManager",
+ "ctrl-shift-enter": "project_panel::OpenWithSystem",
+ "alt-d": "project_panel::CompareMarkedFiles",
+ "shift-find": "project_panel::NewSearchInDirectory",
+ "ctrl-k ctrl-shift-f": "project_panel::NewSearchInDirectory",
+ "shift-down": "menu::SelectNext",
+ "shift-up": "menu::SelectPrevious",
+ "escape": "menu::Cancel"
+ }
+ },
+ {
+ "context": "ProjectPanel && not_editing",
+ "use_key_equivalents": true,
+ "bindings": {
+ "space": "project_panel::Open"
+ }
+ },
+ {
+ "context": "GitPanel && ChangesList",
+ "use_key_equivalents": true,
+ "bindings": {
+ "up": "menu::SelectPrevious",
+ "down": "menu::SelectNext",
+ "enter": "menu::Confirm",
+ "alt-y": "git::StageFile",
+ "shift-alt-y": "git::UnstageFile",
+ "space": "git::ToggleStaged",
+ "shift-space": "git::StageRange",
+ "tab": "git_panel::FocusEditor",
+ "shift-tab": "git_panel::FocusEditor",
+ "escape": "git_panel::ToggleFocus",
+ "alt-enter": "menu::SecondaryConfirm",
+ "delete": ["git::RestoreFile", { "skip_prompt": false }],
+ "backspace": ["git::RestoreFile", { "skip_prompt": false }],
+ "shift-delete": ["git::RestoreFile", { "skip_prompt": false }],
+ "ctrl-backspace": ["git::RestoreFile", { "skip_prompt": false }],
+ "ctrl-delete": ["git::RestoreFile", { "skip_prompt": false }]
+ }
+ },
+ {
+ "context": "GitPanel && CommitEditor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "git::Cancel"
+ }
+ },
+ {
+ "context": "GitCommit > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "menu::Cancel",
+ "enter": "editor::Newline",
+ "ctrl-enter": "git::Commit",
+ "ctrl-shift-enter": "git::Amend",
+ "alt-l": "git::GenerateCommitMessage"
+ }
+ },
+ {
+ "context": "GitPanel",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-g ctrl-g": "git::Fetch",
+ "ctrl-g up": "git::Push",
+ "ctrl-g down": "git::Pull",
+ "ctrl-g shift-up": "git::ForcePush",
+ "ctrl-g d": "git::Diff",
+ "ctrl-g backspace": "git::RestoreTrackedFiles",
+ "ctrl-g shift-backspace": "git::TrashUntrackedFiles",
+ "ctrl-space": "git::StageAll",
+ "ctrl-shift-space": "git::UnstageAll",
+ "ctrl-enter": "git::Commit",
+ "ctrl-shift-enter": "git::Amend"
+ }
+ },
+ {
+ "context": "GitDiff > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-enter": "git::Commit",
+ "ctrl-shift-enter": "git::Amend",
+ "ctrl-space": "git::StageAll",
+ "ctrl-shift-space": "git::UnstageAll"
+ }
+ },
+ {
+ "context": "AskPass > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "menu::Confirm"
+ }
+ },
+ {
+ "context": "CommitEditor > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "git_panel::FocusChanges",
+ "tab": "git_panel::FocusChanges",
+ "shift-tab": "git_panel::FocusChanges",
+ "enter": "editor::Newline",
+ "ctrl-enter": "git::Commit",
+ "ctrl-shift-enter": "git::Amend",
+ "alt-up": "git_panel::FocusChanges",
+ "alt-l": "git::GenerateCommitMessage"
+ }
+ },
+ {
+ "context": "DebugPanel",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-t": "debugger::ToggleThreadPicker",
+ "ctrl-i": "debugger::ToggleSessionPicker",
+ "shift-alt-escape": "debugger::ToggleExpandItem"
+ }
+ },
+ {
+ "context": "VariableList",
+ "use_key_equivalents": true,
+ "bindings": {
+ "left": "variable_list::CollapseSelectedEntry",
+ "right": "variable_list::ExpandSelectedEntry",
+ "enter": "variable_list::EditVariable",
+ "ctrl-c": "variable_list::CopyVariableValue",
+ "ctrl-alt-c": "variable_list::CopyVariableName",
+ "delete": "variable_list::RemoveWatch",
+ "backspace": "variable_list::RemoveWatch",
+ "alt-enter": "variable_list::AddWatch"
+ }
+ },
+ {
+ "context": "BreakpointList",
+ "use_key_equivalents": true,
+ "bindings": {
+ "space": "debugger::ToggleEnableBreakpoint",
+ "backspace": "debugger::UnsetBreakpoint",
+ "left": "debugger::PreviousBreakpointProperty",
+ "right": "debugger::NextBreakpointProperty"
+ }
+ },
+ {
+ "context": "CollabPanel && not_editing",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-backspace": "collab_panel::Remove",
+ "space": "menu::Confirm"
+ }
+ },
+ {
+ "context": "CollabPanel",
+ "use_key_equivalents": true,
+ "bindings": {
+ "alt-up": "collab_panel::MoveChannelUp",
+ "alt-down": "collab_panel::MoveChannelDown"
+ }
+ },
+ {
+ "context": "(CollabPanel && editing) > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "space": "collab_panel::InsertSpace"
+ }
+ },
+ {
+ "context": "ChannelModal",
+ "use_key_equivalents": true,
+ "bindings": {
+ "tab": "channel_modal::ToggleMode"
+ }
+ },
+ {
+ "context": "Picker > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "menu::Cancel",
+ "up": "menu::SelectPrevious",
+ "down": "menu::SelectNext",
+ "tab": "picker::ConfirmCompletion",
+ "alt-enter": ["picker::ConfirmInput", { "secondary": false }]
+ }
+ },
+ {
+ "context": "ChannelModal > Picker > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "tab": "channel_modal::ToggleMode"
+ }
+ },
+ {
+ "context": "FileFinder || (FileFinder > Picker > Editor)",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-p": "file_finder::Toggle",
+ "ctrl-shift-a": "file_finder::ToggleSplitMenu",
+ "ctrl-shift-i": "file_finder::ToggleFilterMenu"
+ }
+ },
+ {
+ "context": "FileFinder || (FileFinder > Picker > Editor) || (FileFinder > Picker > menu)",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-p": "file_finder::SelectPrevious",
+ "ctrl-j": "pane::SplitDown",
+ "ctrl-k": "pane::SplitUp",
+ "ctrl-h": "pane::SplitLeft",
+ "ctrl-l": "pane::SplitRight"
+ }
+ },
+ {
+ "context": "TabSwitcher",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-shift-tab": "menu::SelectPrevious",
+ "ctrl-up": "menu::SelectPrevious",
+ "ctrl-down": "menu::SelectNext",
+ "ctrl-backspace": "tab_switcher::CloseSelectedItem"
+ }
+ },
+ {
+ "context": "Terminal",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-alt-space": "terminal::ShowCharacterPalette",
+ "copy": "terminal::Copy",
+ "ctrl-insert": "terminal::Copy",
+ "ctrl-shift-c": "terminal::Copy",
+ "paste": "terminal::Paste",
+ "shift-insert": "terminal::Paste",
+ "ctrl-shift-v": "terminal::Paste",
+ "ctrl-enter": "assistant::InlineAssist",
+ "alt-b": ["terminal::SendText", "\u001bb"],
+ "alt-f": ["terminal::SendText", "\u001bf"],
+ "alt-.": ["terminal::SendText", "\u001b."],
+ "ctrl-delete": ["terminal::SendText", "\u001bd"],
+ // Overrides for conflicting keybindings
+ "ctrl-b": ["terminal::SendKeystroke", "ctrl-b"],
+ "ctrl-c": ["terminal::SendKeystroke", "ctrl-c"],
+ "ctrl-e": ["terminal::SendKeystroke", "ctrl-e"],
+ "ctrl-o": ["terminal::SendKeystroke", "ctrl-o"],
+ "ctrl-w": ["terminal::SendKeystroke", "ctrl-w"],
+ "ctrl-backspace": ["terminal::SendKeystroke", "ctrl-w"],
+ "ctrl-shift-a": "editor::SelectAll",
+ "find": "buffer_search::Deploy",
+ "ctrl-shift-f": "buffer_search::Deploy",
+ "ctrl-shift-l": "terminal::Clear",
+ "ctrl-shift-w": "pane::CloseActiveItem",
+ "up": ["terminal::SendKeystroke", "up"],
+ "pageup": ["terminal::SendKeystroke", "pageup"],
+ "down": ["terminal::SendKeystroke", "down"],
+ "pagedown": ["terminal::SendKeystroke", "pagedown"],
+ "escape": ["terminal::SendKeystroke", "escape"],
+ "enter": ["terminal::SendKeystroke", "enter"],
+ "shift-pageup": "terminal::ScrollPageUp",
+ "shift-pagedown": "terminal::ScrollPageDown",
+ "shift-up": "terminal::ScrollLineUp",
+ "shift-down": "terminal::ScrollLineDown",
+ "shift-home": "terminal::ScrollToTop",
+ "shift-end": "terminal::ScrollToBottom",
+ "ctrl-shift-space": "terminal::ToggleViMode",
+ "ctrl-shift-r": "terminal::RerunTask",
+ "ctrl-alt-r": "terminal::RerunTask",
+ "alt-t": "terminal::RerunTask"
+ }
+ },
+ {
+ "context": "ZedPredictModal",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "menu::Cancel"
+ }
+ },
+ {
+ "context": "ConfigureContextServerModal > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "menu::Cancel",
+ "enter": "editor::Newline",
+ "ctrl-enter": "menu::Confirm"
+ }
+ },
+ {
+ "context": "OnboardingAiConfigurationModal",
+ "use_key_equivalents": true,
+ "bindings": {
+ "escape": "menu::Cancel"
+ }
+ },
+ {
+ "context": "Diagnostics",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-r": "diagnostics::ToggleDiagnosticsRefresh"
+ }
+ },
+ {
+ "context": "DebugConsole > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "menu::Confirm",
+ "alt-enter": "console::WatchExpression"
+ }
+ },
+ {
+ "context": "RunModal",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-tab": "pane::ActivateNextItem",
+ "ctrl-shift-tab": "pane::ActivatePreviousItem"
+ }
+ },
+ {
+ "context": "MarkdownPreview",
+ "use_key_equivalents": true,
+ "bindings": {
+ "pageup": "markdown::MovePageUp",
+ "pagedown": "markdown::MovePageDown"
+ }
+ },
+ {
+ "context": "KeymapEditor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-f": "search::FocusSearch",
+ "alt-find": "keymap_editor::ToggleKeystrokeSearch",
+ "alt-f": "keymap_editor::ToggleKeystrokeSearch",
+ "alt-c": "keymap_editor::ToggleConflictFilter",
+ "enter": "keymap_editor::EditBinding",
+ "alt-enter": "keymap_editor::CreateBinding",
+ "ctrl-c": "keymap_editor::CopyAction",
+ "ctrl-shift-c": "keymap_editor::CopyContext",
+ "ctrl-t": "keymap_editor::ShowMatchingKeybinds"
+ }
+ },
+ {
+ "context": "KeystrokeInput",
+ "use_key_equivalents": true,
+ "bindings": {
+ "enter": "keystroke_input::StartRecording",
+ "escape escape escape": "keystroke_input::StopRecording",
+ "delete": "keystroke_input::ClearKeystrokes"
+ }
+ },
+ {
+ "context": "KeybindEditorModal",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-enter": "menu::Confirm",
+ "escape": "menu::Cancel"
+ }
+ },
+ {
+ "context": "KeybindEditorModal > Editor",
+ "use_key_equivalents": true,
+ "bindings": {
+ "up": "menu::SelectPrevious",
+ "down": "menu::SelectNext"
+ }
+ },
+ {
+ "context": "Onboarding",
+ "use_key_equivalents": true,
+ "bindings": {
+ "ctrl-1": "onboarding::ActivateBasicsPage",
+ "ctrl-2": "onboarding::ActivateEditingPage",
+ "ctrl-3": "onboarding::ActivateAISetupPage",
+ "ctrl-escape": "onboarding::Finish",
+ "alt-tab": "onboarding::SignIn",
+ "shift-alt-a": "onboarding::OpenAccount"
+ }
+ }
+]
diff --git a/assets/keymaps/linux/emacs.json b/assets/keymaps/linux/emacs.json
index 0ff3796f03..62910e297b 100755
--- a/assets/keymaps/linux/emacs.json
+++ b/assets/keymaps/linux/emacs.json
@@ -38,6 +38,7 @@
"alt-;": ["editor::ToggleComments", { "advance_downwards": false }],
"ctrl-x ctrl-;": "editor::ToggleComments",
"alt-.": "editor::GoToDefinition", // xref-find-definitions
+ "alt-?": "editor::FindAllReferences", // xref-find-references
"alt-,": "pane::GoBack", // xref-pop-marker-stack
"ctrl-x h": "editor::SelectAll", // mark-whole-buffer
"ctrl-d": "editor::Delete", // delete-char
diff --git a/assets/keymaps/macos/emacs.json b/assets/keymaps/macos/emacs.json
index 0ff3796f03..62910e297b 100755
--- a/assets/keymaps/macos/emacs.json
+++ b/assets/keymaps/macos/emacs.json
@@ -38,6 +38,7 @@
"alt-;": ["editor::ToggleComments", { "advance_downwards": false }],
"ctrl-x ctrl-;": "editor::ToggleComments",
"alt-.": "editor::GoToDefinition", // xref-find-definitions
+ "alt-?": "editor::FindAllReferences", // xref-find-references
"alt-,": "pane::GoBack", // xref-pop-marker-stack
"ctrl-x h": "editor::SelectAll", // mark-whole-buffer
"ctrl-d": "editor::Delete", // delete-char
diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json
index be6d34a134..67add61bd3 100644
--- a/assets/keymaps/vim.json
+++ b/assets/keymaps/vim.json
@@ -428,11 +428,13 @@
"g h": "vim::StartOfLine",
"g s": "vim::FirstNonWhitespace", // "g s" default behavior is "space s"
"g e": "vim::EndOfDocument",
+ "g .": "vim::HelixGotoLastModification", // go to last modification
"g r": "editor::FindAllReferences", // zed specific
"g t": "vim::WindowTop",
"g c": "vim::WindowMiddle",
"g b": "vim::WindowBottom",
+ "shift-r": "editor::Paste",
"x": "editor::SelectLine",
"shift-x": "editor::SelectLine",
"%": "editor::SelectAll",
@@ -819,7 +821,7 @@
"v": "project_panel::OpenPermanent",
"p": "project_panel::Open",
"x": "project_panel::RevealInFileManager",
- "s": "project_panel::OpenWithSystem",
+ "s": "workspace::OpenWithSystem",
"z d": "project_panel::CompareMarkedFiles",
"] c": "project_panel::SelectNextGitEntry",
"[ c": "project_panel::SelectPrevGitEntry",
diff --git a/assets/settings/default.json b/assets/settings/default.json
index 014b483250..804198090f 100644
--- a/assets/settings/default.json
+++ b/assets/settings/default.json
@@ -162,6 +162,12 @@
// 2. Always quit the application
// "on_last_window_closed": "quit_app",
"on_last_window_closed": "platform_default",
+ // Whether to show padding for zoomed panels.
+ // When enabled, zoomed center panels (e.g. code editor) will have padding all around,
+ // while zoomed bottom/left/right panels will have padding to the top/right/left (respectively).
+ //
+ // Default: true
+ "zoomed_padding": true,
// Whether to use the system provided dialogs for Open and Save As.
// When set to false, Zed will use the built-in keyboard-first pickers.
"use_system_path_prompts": true,
@@ -647,6 +653,8 @@
// "never"
"show": "always"
},
+ // Whether to enable drag-and-drop operations in the project panel.
+ "drag_and_drop": true,
// Whether to hide the root entry when only one folder is open in the window.
"hide_root": false
},
@@ -1133,11 +1141,6 @@
// The minimum severity of the diagnostics to show inline.
// Inherits editor's diagnostics' max severity settings when `null`.
"max_severity": null
- },
- "cargo": {
- // When enabled, Zed disables rust-analyzer's check on save and starts to query
- // Cargo diagnostics separately.
- "fetch_cargo_diagnostics": false
}
},
// Files or globs of files that will be excluded by Zed entirely. They will be skipped during file
@@ -1634,6 +1637,9 @@
"allowed": true
}
},
+ "Kotlin": {
+ "language_servers": ["kotlin-language-server", "!kotlin-lsp", "..."]
+ },
"LaTeX": {
"formatter": "language_server",
"language_servers": ["texlab", "..."],
diff --git a/assets/settings/initial_tasks.json b/assets/settings/initial_tasks.json
index a79c550671..5cead67b6d 100644
--- a/assets/settings/initial_tasks.json
+++ b/assets/settings/initial_tasks.json
@@ -43,8 +43,8 @@
// "args": ["--login"]
// }
// }
- "shell": "system",
+ "shell": "system"
// Represents the tags for inline runnable indicators, or spawning multiple tasks at once.
- "tags": []
+ // "tags": []
}
]
diff --git a/assets/themes/ayu/ayu.json b/assets/themes/ayu/ayu.json
index f9f8720729..0ffbb9f61e 100644
--- a/assets/themes/ayu/ayu.json
+++ b/assets/themes/ayu/ayu.json
@@ -93,7 +93,7 @@
"terminal.ansi.bright_cyan": "#4c806fff",
"terminal.ansi.dim_cyan": "#cbf2e4ff",
"terminal.ansi.white": "#bfbdb6ff",
- "terminal.ansi.bright_white": "#bfbdb6ff",
+ "terminal.ansi.bright_white": "#fafafaff",
"terminal.ansi.dim_white": "#787876ff",
"link_text.hover": "#5ac1feff",
"conflict": "#feb454ff",
@@ -479,7 +479,7 @@
"terminal.ansi.bright_cyan": "#ace0cbff",
"terminal.ansi.dim_cyan": "#2a5f4aff",
"terminal.ansi.white": "#fcfcfcff",
- "terminal.ansi.bright_white": "#fcfcfcff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#bcbec0ff",
"link_text.hover": "#3b9ee5ff",
"conflict": "#f1ad49ff",
@@ -865,7 +865,7 @@
"terminal.ansi.bright_cyan": "#4c806fff",
"terminal.ansi.dim_cyan": "#cbf2e4ff",
"terminal.ansi.white": "#cccac2ff",
- "terminal.ansi.bright_white": "#cccac2ff",
+ "terminal.ansi.bright_white": "#fafafaff",
"terminal.ansi.dim_white": "#898a8aff",
"link_text.hover": "#72cffeff",
"conflict": "#fecf72ff",
diff --git a/assets/themes/gruvbox/gruvbox.json b/assets/themes/gruvbox/gruvbox.json
index 459825c733..f0f0358b76 100644
--- a/assets/themes/gruvbox/gruvbox.json
+++ b/assets/themes/gruvbox/gruvbox.json
@@ -94,7 +94,7 @@
"terminal.ansi.bright_cyan": "#45603eff",
"terminal.ansi.dim_cyan": "#c7dfbdff",
"terminal.ansi.white": "#fbf1c7ff",
- "terminal.ansi.bright_white": "#fbf1c7ff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#83a598ff",
"version_control.added": "#b7bb26ff",
@@ -494,7 +494,7 @@
"terminal.ansi.bright_cyan": "#45603eff",
"terminal.ansi.dim_cyan": "#c7dfbdff",
"terminal.ansi.white": "#fbf1c7ff",
- "terminal.ansi.bright_white": "#fbf1c7ff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#83a598ff",
"version_control.added": "#b7bb26ff",
@@ -894,7 +894,7 @@
"terminal.ansi.bright_cyan": "#45603eff",
"terminal.ansi.dim_cyan": "#c7dfbdff",
"terminal.ansi.white": "#fbf1c7ff",
- "terminal.ansi.bright_white": "#fbf1c7ff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#83a598ff",
"version_control.added": "#b7bb26ff",
@@ -1294,7 +1294,7 @@
"terminal.ansi.bright_cyan": "#9fbca8ff",
"terminal.ansi.dim_cyan": "#253e2eff",
"terminal.ansi.white": "#fbf1c7ff",
- "terminal.ansi.bright_white": "#fbf1c7ff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#0b6678ff",
"version_control.added": "#797410ff",
@@ -1694,7 +1694,7 @@
"terminal.ansi.bright_cyan": "#9fbca8ff",
"terminal.ansi.dim_cyan": "#253e2eff",
"terminal.ansi.white": "#f9f5d7ff",
- "terminal.ansi.bright_white": "#f9f5d7ff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#0b6678ff",
"version_control.added": "#797410ff",
@@ -2094,7 +2094,7 @@
"terminal.ansi.bright_cyan": "#9fbca8ff",
"terminal.ansi.dim_cyan": "#253e2eff",
"terminal.ansi.white": "#f2e5bcff",
- "terminal.ansi.bright_white": "#f2e5bcff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#b0a189ff",
"link_text.hover": "#0b6678ff",
"version_control.added": "#797410ff",
diff --git a/assets/themes/one/one.json b/assets/themes/one/one.json
index 23ebbcc67e..33f6d3c622 100644
--- a/assets/themes/one/one.json
+++ b/assets/themes/one/one.json
@@ -93,7 +93,7 @@
"terminal.ansi.bright_cyan": "#3a565bff",
"terminal.ansi.dim_cyan": "#b9d9dfff",
"terminal.ansi.white": "#dce0e5ff",
- "terminal.ansi.bright_white": "#dce0e5ff",
+ "terminal.ansi.bright_white": "#fafafaff",
"terminal.ansi.dim_white": "#575d65ff",
"link_text.hover": "#74ade8ff",
"version_control.added": "#27a657ff",
@@ -468,7 +468,7 @@
"terminal.bright_foreground": "#242529ff",
"terminal.dim_foreground": "#fafafaff",
"terminal.ansi.black": "#242529ff",
- "terminal.ansi.bright_black": "#242529ff",
+ "terminal.ansi.bright_black": "#747579ff",
"terminal.ansi.dim_black": "#97979aff",
"terminal.ansi.red": "#d36151ff",
"terminal.ansi.bright_red": "#f0b0a4ff",
@@ -489,7 +489,7 @@
"terminal.ansi.bright_cyan": "#a3bedaff",
"terminal.ansi.dim_cyan": "#254058ff",
"terminal.ansi.white": "#fafafaff",
- "terminal.ansi.bright_white": "#fafafaff",
+ "terminal.ansi.bright_white": "#ffffffff",
"terminal.ansi.dim_white": "#aaaaaaff",
"link_text.hover": "#5c78e2ff",
"version_control.added": "#27a657ff",
diff --git a/crates/acp_thread/src/acp_thread.rs b/crates/acp_thread/src/acp_thread.rs
index c748f22275..4ded647a74 100644
--- a/crates/acp_thread/src/acp_thread.rs
+++ b/crates/acp_thread/src/acp_thread.rs
@@ -183,16 +183,15 @@ impl ToolCall {
language_registry: Arc,
cx: &mut App,
) -> Self {
+ let title = if let Some((first_line, _)) = tool_call.title.split_once("\n") {
+ first_line.to_owned() + "…"
+ } else {
+ tool_call.title
+ };
Self {
id: tool_call.id,
- label: cx.new(|cx| {
- Markdown::new(
- tool_call.title.into(),
- Some(language_registry.clone()),
- None,
- cx,
- )
- }),
+ label: cx
+ .new(|cx| Markdown::new(title.into(), Some(language_registry.clone()), None, cx)),
kind: tool_call.kind,
content: tool_call
.content
@@ -233,7 +232,11 @@ impl ToolCall {
if let Some(title) = title {
self.label.update(cx, |label, cx| {
- label.replace(title, cx);
+ if let Some((first_line, _)) = title.split_once("\n") {
+ label.replace(first_line.to_owned() + "…", cx)
+ } else {
+ label.replace(title, cx);
+ }
});
}
@@ -509,7 +512,7 @@ impl ContentBlock {
"`Image`".into()
}
- fn to_markdown<'a>(&'a self, cx: &'a App) -> &'a str {
+ pub fn to_markdown<'a>(&'a self, cx: &'a App) -> &'a str {
match self {
ContentBlock::Empty => "",
ContentBlock::Markdown { markdown } => markdown.read(cx).source(),
@@ -756,6 +759,8 @@ pub struct AcpThread {
connection: Rc,
session_id: acp::SessionId,
token_usage: Option,
+ prompt_capabilities: acp::PromptCapabilities,
+ _observe_prompt_capabilities: Task>,
}
#[derive(Debug)]
@@ -770,11 +775,12 @@ pub enum AcpThreadEvent {
Stopped,
Error,
LoadError(LoadError),
+ PromptCapabilitiesUpdated,
}
impl EventEmitter for AcpThread {}
-#[derive(PartialEq, Eq)]
+#[derive(PartialEq, Eq, Debug)]
pub enum ThreadStatus {
Idle,
WaitingForToolConfirmation,
@@ -821,7 +827,20 @@ impl AcpThread {
project: Entity,
action_log: Entity,
session_id: acp::SessionId,
+ mut prompt_capabilities_rx: watch::Receiver,
+ cx: &mut Context,
) -> Self {
+ let prompt_capabilities = *prompt_capabilities_rx.borrow();
+ let task = cx.spawn::<_, anyhow::Result<()>>(async move |this, cx| {
+ loop {
+ let caps = prompt_capabilities_rx.recv().await?;
+ this.update(cx, |this, cx| {
+ this.prompt_capabilities = caps;
+ cx.emit(AcpThreadEvent::PromptCapabilitiesUpdated);
+ })?;
+ }
+ });
+
Self {
action_log,
shared_buffers: Default::default(),
@@ -833,9 +852,15 @@ impl AcpThread {
connection,
session_id,
token_usage: None,
+ prompt_capabilities,
+ _observe_prompt_capabilities: task,
}
}
+ pub fn prompt_capabilities(&self) -> acp::PromptCapabilities {
+ self.prompt_capabilities
+ }
+
pub fn connection(&self) -> &Rc {
&self.connection
}
@@ -1373,6 +1398,10 @@ impl AcpThread {
})
}
+ pub fn can_resume(&self, cx: &App) -> bool {
+ self.connection.resume(&self.session_id, cx).is_some()
+ }
+
pub fn resume(&mut self, cx: &mut Context) -> BoxFuture<'static, Result<()>> {
self.run_turn(cx, async move |this, cx| {
this.update(cx, |this, cx| {
@@ -2595,13 +2624,19 @@ mod tests {
.into(),
);
let action_log = cx.new(|_| ActionLog::new(project.clone()));
- let thread = cx.new(|_cx| {
+ let thread = cx.new(|cx| {
AcpThread::new(
"Test",
self.clone(),
project,
action_log,
session_id.clone(),
+ watch::Receiver::constant(acp::PromptCapabilities {
+ image: true,
+ audio: true,
+ embedded_context: true,
+ }),
+ cx,
)
});
self.sessions.lock().insert(session_id, thread.downgrade());
@@ -2635,14 +2670,6 @@ mod tests {
}
}
- fn prompt_capabilities(&self) -> acp::PromptCapabilities {
- acp::PromptCapabilities {
- image: true,
- audio: true,
- embedded_context: true,
- }
- }
-
fn cancel(&self, session_id: &acp::SessionId, cx: &mut App) {
let sessions = self.sessions.lock();
let thread = sessions.get(session_id).unwrap().clone();
@@ -2659,7 +2686,7 @@ mod tests {
fn truncate(
&self,
session_id: &acp::SessionId,
- _cx: &mut App,
+ _cx: &App,
) -> Option> {
Some(Rc::new(FakeAgentSessionEditor {
_session_id: session_id.clone(),
diff --git a/crates/acp_thread/src/connection.rs b/crates/acp_thread/src/connection.rs
index 91e46dbac1..af229b7545 100644
--- a/crates/acp_thread/src/connection.rs
+++ b/crates/acp_thread/src/connection.rs
@@ -38,12 +38,10 @@ pub trait AgentConnection {
cx: &mut App,
) -> Task>;
- fn prompt_capabilities(&self) -> acp::PromptCapabilities;
-
fn resume(
&self,
_session_id: &acp::SessionId,
- _cx: &mut App,
+ _cx: &App,
) -> Option> {
None
}
@@ -53,7 +51,7 @@ pub trait AgentConnection {
fn truncate(
&self,
_session_id: &acp::SessionId,
- _cx: &mut App,
+ _cx: &App,
) -> Option> {
None
}
@@ -61,7 +59,7 @@ pub trait AgentConnection {
fn set_title(
&self,
_session_id: &acp::SessionId,
- _cx: &mut App,
+ _cx: &App,
) -> Option> {
None
}
@@ -329,13 +327,19 @@ mod test_support {
) -> Task>> {
let session_id = acp::SessionId(self.sessions.lock().len().to_string().into());
let action_log = cx.new(|_| ActionLog::new(project.clone()));
- let thread = cx.new(|_cx| {
+ let thread = cx.new(|cx| {
AcpThread::new(
"Test",
self.clone(),
project,
action_log,
session_id.clone(),
+ watch::Receiver::constant(acp::PromptCapabilities {
+ image: true,
+ audio: true,
+ embedded_context: true,
+ }),
+ cx,
)
});
self.sessions.lock().insert(
@@ -348,14 +352,6 @@ mod test_support {
Task::ready(Ok(thread))
}
- fn prompt_capabilities(&self) -> acp::PromptCapabilities {
- acp::PromptCapabilities {
- image: true,
- audio: true,
- embedded_context: true,
- }
- }
-
fn authenticate(
&self,
_method_id: acp::AuthMethodId,
@@ -439,7 +435,7 @@ mod test_support {
fn truncate(
&self,
_session_id: &agent_client_protocol::SessionId,
- _cx: &mut App,
+ _cx: &App,
) -> Option> {
Some(Rc::new(StubAgentSessionEditor))
}
diff --git a/crates/acp_thread/src/mention.rs b/crates/acp_thread/src/mention.rs
index a1e713cffa..6fa0887e22 100644
--- a/crates/acp_thread/src/mention.rs
+++ b/crates/acp_thread/src/mention.rs
@@ -5,7 +5,7 @@ use prompt_store::{PromptId, UserPromptId};
use serde::{Deserialize, Serialize};
use std::{
fmt,
- ops::Range,
+ ops::RangeInclusive,
path::{Path, PathBuf},
str::FromStr,
};
@@ -17,13 +17,14 @@ pub enum MentionUri {
File {
abs_path: PathBuf,
},
+ PastedImage,
Directory {
abs_path: PathBuf,
},
Symbol {
- path: PathBuf,
+ abs_path: PathBuf,
name: String,
- line_range: Range,
+ line_range: RangeInclusive,
},
Thread {
id: acp::SessionId,
@@ -38,8 +39,9 @@ pub enum MentionUri {
name: String,
},
Selection {
- path: PathBuf,
- line_range: Range,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ abs_path: Option,
+ line_range: RangeInclusive,
},
Fetch {
url: Url,
@@ -48,36 +50,44 @@ pub enum MentionUri {
impl MentionUri {
pub fn parse(input: &str) -> Result {
+ fn parse_line_range(fragment: &str) -> Result> {
+ let range = fragment
+ .strip_prefix("L")
+ .context("Line range must start with \"L\"")?;
+ let (start, end) = range
+ .split_once(":")
+ .context("Line range must use colon as separator")?;
+ let range = start
+ .parse::()
+ .context("Parsing line range start")?
+ .checked_sub(1)
+ .context("Line numbers should be 1-based")?
+ ..=end
+ .parse::()
+ .context("Parsing line range end")?
+ .checked_sub(1)
+ .context("Line numbers should be 1-based")?;
+ Ok(range)
+ }
+
let url = url::Url::parse(input)?;
let path = url.path();
match url.scheme() {
"file" => {
let path = url.to_file_path().ok().context("Extracting file path")?;
if let Some(fragment) = url.fragment() {
- let range = fragment
- .strip_prefix("L")
- .context("Line range must start with \"L\"")?;
- let (start, end) = range
- .split_once(":")
- .context("Line range must use colon as separator")?;
- let line_range = start
- .parse::()
- .context("Parsing line range start")?
- .checked_sub(1)
- .context("Line numbers should be 1-based")?
- ..end
- .parse::()
- .context("Parsing line range end")?
- .checked_sub(1)
- .context("Line numbers should be 1-based")?;
+ let line_range = parse_line_range(fragment)?;
if let Some(name) = single_query_param(&url, "symbol")? {
Ok(Self::Symbol {
name,
- path,
+ abs_path: path,
line_range,
})
} else {
- Ok(Self::Selection { path, line_range })
+ Ok(Self::Selection {
+ abs_path: Some(path),
+ line_range,
+ })
}
} else if input.ends_with("/") {
Ok(Self::Directory { abs_path: path })
@@ -105,6 +115,17 @@ impl MentionUri {
id: rule_id.into(),
name,
})
+ } else if path.starts_with("/agent/pasted-image") {
+ Ok(Self::PastedImage)
+ } else if path.starts_with("/agent/untitled-buffer") {
+ let fragment = url
+ .fragment()
+ .context("Missing fragment for untitled buffer selection")?;
+ let line_range = parse_line_range(fragment)?;
+ Ok(Self::Selection {
+ abs_path: None,
+ line_range,
+ })
} else {
bail!("invalid zed url: {:?}", input);
}
@@ -121,13 +142,16 @@ impl MentionUri {
.unwrap_or_default()
.to_string_lossy()
.into_owned(),
+ MentionUri::PastedImage => "Image".to_string(),
MentionUri::Symbol { name, .. } => name.clone(),
MentionUri::Thread { name, .. } => name.clone(),
MentionUri::TextThread { name, .. } => name.clone(),
MentionUri::Rule { name, .. } => name.clone(),
MentionUri::Selection {
- path, line_range, ..
- } => selection_name(path, line_range),
+ abs_path: path,
+ line_range,
+ ..
+ } => selection_name(path.as_deref(), line_range),
MentionUri::Fetch { url } => url.to_string(),
}
}
@@ -137,6 +161,7 @@ impl MentionUri {
MentionUri::File { abs_path } => {
FileIcons::get_icon(abs_path, cx).unwrap_or_else(|| IconName::File.path().into())
}
+ MentionUri::PastedImage => IconName::Image.path().into(),
MentionUri::Directory { .. } => FileIcons::get_folder_icon(false, cx)
.unwrap_or_else(|| IconName::Folder.path().into()),
MentionUri::Symbol { .. } => IconName::Code.path().into(),
@@ -157,29 +182,40 @@ impl MentionUri {
MentionUri::File { abs_path } => {
Url::from_file_path(abs_path).expect("mention path should be absolute")
}
+ MentionUri::PastedImage => Url::parse("zed:///agent/pasted-image").unwrap(),
MentionUri::Directory { abs_path } => {
Url::from_directory_path(abs_path).expect("mention path should be absolute")
}
MentionUri::Symbol {
- path,
+ abs_path,
name,
line_range,
} => {
- let mut url = Url::from_file_path(path).expect("mention path should be absolute");
+ let mut url =
+ Url::from_file_path(abs_path).expect("mention path should be absolute");
url.query_pairs_mut().append_pair("symbol", name);
url.set_fragment(Some(&format!(
"L{}:{}",
- line_range.start + 1,
- line_range.end + 1
+ line_range.start() + 1,
+ line_range.end() + 1
)));
url
}
- MentionUri::Selection { path, line_range } => {
- let mut url = Url::from_file_path(path).expect("mention path should be absolute");
+ MentionUri::Selection {
+ abs_path: path,
+ line_range,
+ } => {
+ let mut url = if let Some(path) = path {
+ Url::from_file_path(path).expect("mention path should be absolute")
+ } else {
+ let mut url = Url::parse("zed:///").unwrap();
+ url.set_path("/agent/untitled-buffer");
+ url
+ };
url.set_fragment(Some(&format!(
"L{}:{}",
- line_range.start + 1,
- line_range.end + 1
+ line_range.start() + 1,
+ line_range.end() + 1
)));
url
}
@@ -191,7 +227,10 @@ impl MentionUri {
}
MentionUri::TextThread { path, name } => {
let mut url = Url::parse("zed:///").unwrap();
- url.set_path(&format!("/agent/text-thread/{}", path.to_string_lossy()));
+ url.set_path(&format!(
+ "/agent/text-thread/{}",
+ path.to_string_lossy().trim_start_matches('/')
+ ));
url.query_pairs_mut().append_pair("name", name);
url
}
@@ -237,12 +276,14 @@ fn single_query_param(url: &Url, name: &'static str) -> Result