diff --git a/.github/workflows/release_actions.yml b/.github/workflows/release_actions.yml
index c1df24a8e5..550eda882b 100644
--- a/.github/workflows/release_actions.yml
+++ b/.github/workflows/release_actions.yml
@@ -20,9 +20,7 @@ jobs:
id: get-content
with:
stringToTruncate: |
- 📣 Zed ${{ github.event.release.tag_name }} was just released!
-
- Restart your Zed or head to ${{ steps.get-release-url.outputs.URL }} to grab it.
+ 📣 Zed [${{ github.event.release.tag_name }}](${{ steps.get-release-url.outputs.URL }}) was just released!
${{ github.event.release.body }}
maxLength: 2000
diff --git a/Cargo.lock b/Cargo.lock
index 3dd85395b1..3aca27106c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -91,6 +91,7 @@ dependencies = [
"futures 0.3.28",
"gpui",
"isahc",
+ "language",
"lazy_static",
"log",
"matrixmultiply",
@@ -103,7 +104,34 @@ dependencies = [
"rusqlite",
"serde",
"serde_json",
- "tiktoken-rs 0.5.4",
+ "tiktoken-rs",
+ "util",
+]
+
+[[package]]
+name = "ai2"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "async-trait",
+ "bincode",
+ "futures 0.3.28",
+ "gpui2",
+ "isahc",
+ "language2",
+ "lazy_static",
+ "log",
+ "matrixmultiply",
+ "ordered-float 2.10.0",
+ "parking_lot 0.11.2",
+ "parse_duration",
+ "postage",
+ "rand 0.8.5",
+ "regex",
+ "rusqlite",
+ "serde",
+ "serde_json",
+ "tiktoken-rs",
"util",
]
@@ -309,6 +337,7 @@ dependencies = [
"language",
"log",
"menu",
+ "multi_buffer",
"ordered-float 2.10.0",
"parking_lot 0.11.2",
"project",
@@ -316,12 +345,13 @@ dependencies = [
"regex",
"schemars",
"search",
+ "semantic_index",
"serde",
"serde_json",
"settings",
"smol",
"theme",
- "tiktoken-rs 0.4.5",
+ "tiktoken-rs",
"util",
"uuid 1.4.1",
"workspace",
@@ -1573,7 +1603,7 @@ dependencies = [
[[package]]
name = "collab"
-version = "0.24.0"
+version = "0.27.0"
dependencies = [
"anyhow",
"async-trait",
@@ -1609,6 +1639,7 @@ dependencies = [
"lsp",
"nanoid",
"node_runtime",
+ "notifications",
"parking_lot 0.11.2",
"pretty_assertions",
"project",
@@ -1664,20 +1695,26 @@ dependencies = [
"fuzzy",
"gpui",
"language",
+ "lazy_static",
"log",
"menu",
+ "notifications",
"picker",
"postage",
+ "pretty_assertions",
"project",
"recent_projects",
"rich_text",
+ "rpc",
"schemars",
"serde",
"serde_derive",
"settings",
+ "smallvec",
"theme",
"theme_selector",
"time",
+ "tree-sitter-markdown",
"util",
"vcs_menu",
"workspace",
@@ -1731,6 +1768,7 @@ dependencies = [
"theme",
"util",
"workspace",
+ "zed-actions",
]
[[package]]
@@ -1810,6 +1848,7 @@ dependencies = [
"log",
"lsp",
"node_runtime",
+ "parking_lot 0.11.2",
"rpc",
"serde",
"serde_derive",
@@ -2556,11 +2595,11 @@ dependencies = [
"lazy_static",
"log",
"lsp",
+ "multi_buffer",
"ordered-float 2.10.0",
"parking_lot 0.11.2",
"postage",
"project",
- "pulldown-cmark",
"rand 0.8.5",
"rich_text",
"rpc",
@@ -4159,6 +4198,24 @@ dependencies = [
"workspace",
]
+[[package]]
+name = "journal2"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "chrono",
+ "dirs 4.0.0",
+ "editor",
+ "gpui2",
+ "log",
+ "schemars",
+ "serde",
+ "settings2",
+ "shellexpand",
+ "util",
+ "workspace",
+]
+
[[package]]
name = "jpeg-decoder"
version = "0.1.22"
@@ -4244,6 +4301,7 @@ dependencies = [
"lsp",
"parking_lot 0.11.2",
"postage",
+ "pulldown-cmark",
"rand 0.8.5",
"regex",
"rpc",
@@ -4764,6 +4822,13 @@ dependencies = [
"gpui",
]
+[[package]]
+name = "menu2"
+version = "0.1.0"
+dependencies = [
+ "gpui2",
+]
+
[[package]]
name = "metal"
version = "0.21.0"
@@ -4921,6 +4986,55 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389"
+[[package]]
+name = "multi_buffer"
+version = "0.1.0"
+dependencies = [
+ "aho-corasick",
+ "anyhow",
+ "client",
+ "clock",
+ "collections",
+ "context_menu",
+ "convert_case 0.6.0",
+ "copilot",
+ "ctor",
+ "env_logger 0.9.3",
+ "futures 0.3.28",
+ "git",
+ "gpui",
+ "indoc",
+ "itertools 0.10.5",
+ "language",
+ "lazy_static",
+ "log",
+ "lsp",
+ "ordered-float 2.10.0",
+ "parking_lot 0.11.2",
+ "postage",
+ "project",
+ "pulldown-cmark",
+ "rand 0.8.5",
+ "rich_text",
+ "schemars",
+ "serde",
+ "serde_derive",
+ "settings",
+ "smallvec",
+ "smol",
+ "snippet",
+ "sum_tree",
+ "text",
+ "theme",
+ "tree-sitter",
+ "tree-sitter-html",
+ "tree-sitter-rust",
+ "tree-sitter-typescript",
+ "unindent",
+ "util",
+ "workspace",
+]
+
[[package]]
name = "multimap"
version = "0.8.3"
@@ -5070,6 +5184,26 @@ dependencies = [
"minimal-lexical",
]
+[[package]]
+name = "notifications"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "channel",
+ "client",
+ "clock",
+ "collections",
+ "db",
+ "feature_flags",
+ "gpui",
+ "rpc",
+ "settings",
+ "sum_tree",
+ "text",
+ "time",
+ "util",
+]
+
[[package]]
name = "ntapi"
version = "0.3.7"
@@ -5886,6 +6020,7 @@ dependencies = [
"log",
"lsp",
"node_runtime",
+ "parking_lot 0.11.2",
"serde",
"serde_derive",
"serde_json",
@@ -6831,8 +6966,10 @@ dependencies = [
"rsa 0.4.0",
"serde",
"serde_derive",
+ "serde_json",
"smol",
"smol-timeout",
+ "strum",
"tempdir",
"tracing",
"util",
@@ -7407,7 +7544,7 @@ dependencies = [
"smol",
"tempdir",
"theme",
- "tiktoken-rs 0.5.4",
+ "tiktoken-rs",
"tree-sitter",
"tree-sitter-cpp",
"tree-sitter-elixir",
@@ -7421,7 +7558,6 @@ dependencies = [
"unindent",
"util",
"workspace",
- "zed",
]
[[package]]
@@ -8638,6 +8774,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"clap 4.4.4",
+ "convert_case 0.6.0",
"gpui2",
"log",
"rust-embed",
@@ -8713,21 +8850,6 @@ dependencies = [
"weezl",
]
-[[package]]
-name = "tiktoken-rs"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52aacc1cff93ba9d5f198c62c49c77fa0355025c729eed3326beaf7f33bc8614"
-dependencies = [
- "anyhow",
- "base64 0.21.4",
- "bstr",
- "fancy-regex",
- "lazy_static",
- "parking_lot 0.12.1",
- "rustc-hash",
-]
-
[[package]]
name = "tiktoken-rs"
version = "0.5.4"
@@ -9148,8 +9270,8 @@ dependencies = [
[[package]]
name = "tree-sitter-bash"
-version = "0.19.0"
-source = "git+https://github.com/tree-sitter/tree-sitter-bash?rev=1b0321ee85701d5036c334a6f04761cdc672e64c#1b0321ee85701d5036c334a6f04761cdc672e64c"
+version = "0.20.4"
+source = "git+https://github.com/tree-sitter/tree-sitter-bash?rev=7331995b19b8f8aba2d5e26deb51d2195c18bc94#7331995b19b8f8aba2d5e26deb51d2195c18bc94"
dependencies = [
"cc",
"tree-sitter",
@@ -9388,6 +9510,15 @@ dependencies = [
"tree-sitter",
]
+[[package]]
+name = "tree-sitter-vue"
+version = "0.0.1"
+source = "git+https://github.com/zed-industries/tree-sitter-vue?rev=95b2890#95b28908d90e928c308866f7631e73ef6e1d4b5f"
+dependencies = [
+ "cc",
+ "tree-sitter",
+]
+
[[package]]
name = "tree-sitter-yaml"
version = "0.0.1"
@@ -9469,10 +9600,8 @@ dependencies = [
"itertools 0.11.0",
"rand 0.8.5",
"serde",
- "settings",
"smallvec",
"strum",
- "theme",
"theme2",
]
@@ -9714,6 +9843,7 @@ name = "vcs_menu"
version = "0.1.0"
dependencies = [
"anyhow",
+ "fs",
"fuzzy",
"gpui",
"picker",
@@ -10658,9 +10788,10 @@ dependencies = [
[[package]]
name = "zed"
-version = "0.109.0"
+version = "0.111.0"
dependencies = [
"activity_indicator",
+ "ai",
"anyhow",
"assistant",
"async-compression",
@@ -10712,6 +10843,7 @@ dependencies = [
"log",
"lsp",
"node_runtime",
+ "notifications",
"num_cpus",
"outline",
"parking_lot 0.11.2",
@@ -10773,6 +10905,7 @@ dependencies = [
"tree-sitter-svelte",
"tree-sitter-toml",
"tree-sitter-typescript",
+ "tree-sitter-vue",
"tree-sitter-yaml",
"unindent",
"url",
@@ -10790,12 +10923,14 @@ name = "zed-actions"
version = "0.1.0"
dependencies = [
"gpui",
+ "serde",
]
[[package]]
name = "zed2"
version = "0.109.0"
dependencies = [
+ "ai2",
"anyhow",
"async-compression",
"async-recursion 0.3.2",
@@ -10811,7 +10946,7 @@ dependencies = [
"ctor",
"db2",
"env_logger 0.9.3",
- "feature_flags",
+ "feature_flags2",
"fs2",
"fsevent",
"futures 0.3.28",
@@ -10822,12 +10957,13 @@ dependencies = [
"indexmap 1.9.3",
"install_cli",
"isahc",
+ "journal2",
"language2",
"language_tools",
"lazy_static",
"libc",
"log",
- "lsp",
+ "lsp2",
"node_runtime",
"num_cpus",
"parking_lot 0.11.2",
@@ -10880,6 +11016,7 @@ dependencies = [
"tree-sitter-svelte",
"tree-sitter-toml",
"tree-sitter-typescript",
+ "tree-sitter-vue",
"tree-sitter-yaml",
"unindent",
"url",
diff --git a/Cargo.toml b/Cargo.toml
index 82af9265dd..ac490ce935 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -48,6 +48,7 @@ members = [
"crates/install_cli",
"crates/install_cli2",
"crates/journal",
+ "crates/journal2",
"crates/language",
"crates/language2",
"crates/language_selector",
@@ -58,7 +59,10 @@ members = [
"crates/lsp2",
"crates/media",
"crates/menu",
+ "crates/menu2",
+ "crates/multi_buffer",
"crates/node_runtime",
+ "crates/notifications",
"crates/outline",
"crates/picker",
"crates/plugin",
@@ -133,6 +137,7 @@ serde_derive = { version = "1.0", features = ["deserialize_in_place"] }
serde_json = { version = "1.0", features = ["preserve_order", "raw_value"] }
smallvec = { version = "1.6", features = ["union"] }
smol = { version = "1.2" }
+strum = { version = "0.25.0", features = ["derive"] }
sysinfo = "0.29.10"
tempdir = { version = "0.3.7" }
thiserror = { version = "1.0.29" }
@@ -144,7 +149,7 @@ pretty_assertions = "1.3.0"
git2 = { version = "0.15", default-features = false}
uuid = { version = "1.1.2", features = ["v4"] }
-tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "1b0321ee85701d5036c334a6f04761cdc672e64c" }
+tree-sitter-bash = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "7331995b19b8f8aba2d5e26deb51d2195c18bc94" }
tree-sitter-c = "0.20.1"
tree-sitter-cpp = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev="f44509141e7e483323d2ec178f2d2e6c0fc041c1" }
tree-sitter-css = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "769203d0f9abe1a9a691ac2b9fe4bb4397a73c51" }
@@ -170,7 +175,7 @@ tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml",
tree-sitter-lua = "0.0.14"
tree-sitter-nix = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "66e3e9ce9180ae08fc57372061006ef83f0abde7" }
tree-sitter-nu = { git = "https://github.com/nushell/tree-sitter-nu", rev = "786689b0562b9799ce53e824cb45a1a2a04dc673"}
-
+tree-sitter-vue = {git = "https://github.com/zed-industries/tree-sitter-vue", rev = "95b2890"}
[patch.crates-io]
tree-sitter = { git = "https://github.com/tree-sitter/tree-sitter", rev = "35a6052fbcafc5e5fc0f9415b8652be7dcaf7222" }
async-task = { git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e" }
diff --git a/Procfile b/Procfile
index 2eb7de20fb..3f42c3a967 100644
--- a/Procfile
+++ b/Procfile
@@ -1,4 +1,4 @@
web: cd ../zed.dev && PORT=3000 npm run dev
-collab: cd crates/collab && RUST_LOG=${RUST_LOG:-collab=info} cargo run serve
+collab: cd crates/collab && RUST_LOG=${RUST_LOG:-warn,collab=info} cargo run serve
livekit: livekit-server --dev
postgrest: postgrest crates/collab/admin_api.conf
diff --git a/assets/icons/bell.svg b/assets/icons/bell.svg
new file mode 100644
index 0000000000..ea1c6dd42e
--- /dev/null
+++ b/assets/icons/bell.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/icons/link.svg b/assets/icons/link.svg
new file mode 100644
index 0000000000..4925bd8e00
--- /dev/null
+++ b/assets/icons/link.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/public.svg b/assets/icons/public.svg
new file mode 100644
index 0000000000..38278cdaba
--- /dev/null
+++ b/assets/icons/public.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/update.svg b/assets/icons/update.svg
new file mode 100644
index 0000000000..b529b2b08b
--- /dev/null
+++ b/assets/icons/update.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json
index 8422d53abc..ef6a655bdc 100644
--- a/assets/keymaps/default.json
+++ b/assets/keymaps/default.json
@@ -370,42 +370,15 @@
{
"context": "Pane",
"bindings": {
- "ctrl-1": [
- "pane::ActivateItem",
- 0
- ],
- "ctrl-2": [
- "pane::ActivateItem",
- 1
- ],
- "ctrl-3": [
- "pane::ActivateItem",
- 2
- ],
- "ctrl-4": [
- "pane::ActivateItem",
- 3
- ],
- "ctrl-5": [
- "pane::ActivateItem",
- 4
- ],
- "ctrl-6": [
- "pane::ActivateItem",
- 5
- ],
- "ctrl-7": [
- "pane::ActivateItem",
- 6
- ],
- "ctrl-8": [
- "pane::ActivateItem",
- 7
- ],
- "ctrl-9": [
- "pane::ActivateItem",
- 8
- ],
+ "ctrl-1": ["pane::ActivateItem", 0],
+ "ctrl-2": ["pane::ActivateItem", 1],
+ "ctrl-3": ["pane::ActivateItem", 2],
+ "ctrl-4": ["pane::ActivateItem", 3],
+ "ctrl-5": ["pane::ActivateItem", 4],
+ "ctrl-6": ["pane::ActivateItem", 5],
+ "ctrl-7": ["pane::ActivateItem", 6],
+ "ctrl-8": ["pane::ActivateItem", 7],
+ "ctrl-9": ["pane::ActivateItem", 8],
"ctrl-0": "pane::ActivateLastItem",
"ctrl--": "pane::GoBack",
"ctrl-_": "pane::GoForward",
@@ -416,42 +389,15 @@
{
"context": "Workspace",
"bindings": {
- "cmd-1": [
- "workspace::ActivatePane",
- 0
- ],
- "cmd-2": [
- "workspace::ActivatePane",
- 1
- ],
- "cmd-3": [
- "workspace::ActivatePane",
- 2
- ],
- "cmd-4": [
- "workspace::ActivatePane",
- 3
- ],
- "cmd-5": [
- "workspace::ActivatePane",
- 4
- ],
- "cmd-6": [
- "workspace::ActivatePane",
- 5
- ],
- "cmd-7": [
- "workspace::ActivatePane",
- 6
- ],
- "cmd-8": [
- "workspace::ActivatePane",
- 7
- ],
- "cmd-9": [
- "workspace::ActivatePane",
- 8
- ],
+ "cmd-1": ["workspace::ActivatePane", 0],
+ "cmd-2": ["workspace::ActivatePane", 1],
+ "cmd-3": ["workspace::ActivatePane", 2],
+ "cmd-4": ["workspace::ActivatePane", 3],
+ "cmd-5": ["workspace::ActivatePane", 4],
+ "cmd-6": ["workspace::ActivatePane", 5],
+ "cmd-7": ["workspace::ActivatePane", 6],
+ "cmd-8": ["workspace::ActivatePane", 7],
+ "cmd-9": ["workspace::ActivatePane", 8],
"cmd-b": "workspace::ToggleLeftDock",
"cmd-r": "workspace::ToggleRightDock",
"cmd-j": "workspace::ToggleBottomDock",
@@ -494,38 +440,14 @@
},
{
"bindings": {
- "cmd-k cmd-left": [
- "workspace::ActivatePaneInDirection",
- "Left"
- ],
- "cmd-k cmd-right": [
- "workspace::ActivatePaneInDirection",
- "Right"
- ],
- "cmd-k cmd-up": [
- "workspace::ActivatePaneInDirection",
- "Up"
- ],
- "cmd-k cmd-down": [
- "workspace::ActivatePaneInDirection",
- "Down"
- ],
- "cmd-k shift-left": [
- "workspace::SwapPaneInDirection",
- "Left"
- ],
- "cmd-k shift-right": [
- "workspace::SwapPaneInDirection",
- "Right"
- ],
- "cmd-k shift-up": [
- "workspace::SwapPaneInDirection",
- "Up"
- ],
- "cmd-k shift-down": [
- "workspace::SwapPaneInDirection",
- "Down"
- ]
+ "cmd-k cmd-left": ["workspace::ActivatePaneInDirection", "Left"],
+ "cmd-k cmd-right": ["workspace::ActivatePaneInDirection", "Right"],
+ "cmd-k cmd-up": ["workspace::ActivatePaneInDirection", "Up"],
+ "cmd-k cmd-down": ["workspace::ActivatePaneInDirection", "Down"],
+ "cmd-k shift-left": ["workspace::SwapPaneInDirection", "Left"],
+ "cmd-k shift-right": ["workspace::SwapPaneInDirection", "Right"],
+ "cmd-k shift-up": ["workspace::SwapPaneInDirection", "Up"],
+ "cmd-k shift-down": ["workspace::SwapPaneInDirection", "Down"]
}
},
// Bindings from Atom
@@ -627,14 +549,6 @@
"space": "collab_panel::InsertSpace"
}
},
- {
- "context": "(CollabPanel && not_editing) > Editor",
- "bindings": {
- "cmd-c": "collab_panel::StartLinkChannel",
- "cmd-x": "collab_panel::StartMoveChannel",
- "cmd-v": "collab_panel::MoveOrLinkToSelected"
- }
- },
{
"context": "ChannelModal",
"bindings": {
@@ -655,57 +569,21 @@
"cmd-v": "terminal::Paste",
"cmd-k": "terminal::Clear",
// Some nice conveniences
- "cmd-backspace": [
- "terminal::SendText",
- "\u0015"
- ],
- "cmd-right": [
- "terminal::SendText",
- "\u0005"
- ],
- "cmd-left": [
- "terminal::SendText",
- "\u0001"
- ],
+ "cmd-backspace": ["terminal::SendText", "\u0015"],
+ "cmd-right": ["terminal::SendText", "\u0005"],
+ "cmd-left": ["terminal::SendText", "\u0001"],
// Terminal.app compatibility
- "alt-left": [
- "terminal::SendText",
- "\u001bb"
- ],
- "alt-right": [
- "terminal::SendText",
- "\u001bf"
- ],
+ "alt-left": ["terminal::SendText", "\u001bb"],
+ "alt-right": ["terminal::SendText", "\u001bf"],
// There are conflicting bindings for these keys in the global context.
// these bindings override them, remove at your own risk:
- "up": [
- "terminal::SendKeystroke",
- "up"
- ],
- "pageup": [
- "terminal::SendKeystroke",
- "pageup"
- ],
- "down": [
- "terminal::SendKeystroke",
- "down"
- ],
- "pagedown": [
- "terminal::SendKeystroke",
- "pagedown"
- ],
- "escape": [
- "terminal::SendKeystroke",
- "escape"
- ],
- "enter": [
- "terminal::SendKeystroke",
- "enter"
- ],
- "ctrl-c": [
- "terminal::SendKeystroke",
- "ctrl-c"
- ]
+ "up": ["terminal::SendKeystroke", "up"],
+ "pageup": ["terminal::SendKeystroke", "pageup"],
+ "down": ["terminal::SendKeystroke", "down"],
+ "pagedown": ["terminal::SendKeystroke", "pagedown"],
+ "escape": ["terminal::SendKeystroke", "escape"],
+ "enter": ["terminal::SendKeystroke", "enter"],
+ "ctrl-c": ["terminal::SendKeystroke", "ctrl-c"]
}
}
]
diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json
index ea025747d8..81235bb72a 100644
--- a/assets/keymaps/vim.json
+++ b/assets/keymaps/vim.json
@@ -39,6 +39,7 @@
"w": "vim::NextWordStart",
"{": "vim::StartOfParagraph",
"}": "vim::EndOfParagraph",
+ "|": "vim::GoToColumn",
"shift-w": [
"vim::NextWordStart",
{
@@ -97,14 +98,8 @@
"ctrl-o": "pane::GoBack",
"ctrl-i": "pane::GoForward",
"ctrl-]": "editor::GoToDefinition",
- "escape": [
- "vim::SwitchMode",
- "Normal"
- ],
- "ctrl+[": [
- "vim::SwitchMode",
- "Normal"
- ],
+ "escape": ["vim::SwitchMode", "Normal"],
+ "ctrl+[": ["vim::SwitchMode", "Normal"],
"v": "vim::ToggleVisual",
"shift-v": "vim::ToggleVisualLine",
"ctrl-v": "vim::ToggleVisualBlock",
@@ -233,123 +228,36 @@
}
],
// Count support
- "1": [
- "vim::Number",
- 1
- ],
- "2": [
- "vim::Number",
- 2
- ],
- "3": [
- "vim::Number",
- 3
- ],
- "4": [
- "vim::Number",
- 4
- ],
- "5": [
- "vim::Number",
- 5
- ],
- "6": [
- "vim::Number",
- 6
- ],
- "7": [
- "vim::Number",
- 7
- ],
- "8": [
- "vim::Number",
- 8
- ],
- "9": [
- "vim::Number",
- 9
- ],
+ "1": ["vim::Number", 1],
+ "2": ["vim::Number", 2],
+ "3": ["vim::Number", 3],
+ "4": ["vim::Number", 4],
+ "5": ["vim::Number", 5],
+ "6": ["vim::Number", 6],
+ "7": ["vim::Number", 7],
+ "8": ["vim::Number", 8],
+ "9": ["vim::Number", 9],
// window related commands (ctrl-w X)
- "ctrl-w left": [
- "workspace::ActivatePaneInDirection",
- "Left"
- ],
- "ctrl-w right": [
- "workspace::ActivatePaneInDirection",
- "Right"
- ],
- "ctrl-w up": [
- "workspace::ActivatePaneInDirection",
- "Up"
- ],
- "ctrl-w down": [
- "workspace::ActivatePaneInDirection",
- "Down"
- ],
- "ctrl-w h": [
- "workspace::ActivatePaneInDirection",
- "Left"
- ],
- "ctrl-w l": [
- "workspace::ActivatePaneInDirection",
- "Right"
- ],
- "ctrl-w k": [
- "workspace::ActivatePaneInDirection",
- "Up"
- ],
- "ctrl-w j": [
- "workspace::ActivatePaneInDirection",
- "Down"
- ],
- "ctrl-w ctrl-h": [
- "workspace::ActivatePaneInDirection",
- "Left"
- ],
- "ctrl-w ctrl-l": [
- "workspace::ActivatePaneInDirection",
- "Right"
- ],
- "ctrl-w ctrl-k": [
- "workspace::ActivatePaneInDirection",
- "Up"
- ],
- "ctrl-w ctrl-j": [
- "workspace::ActivatePaneInDirection",
- "Down"
- ],
- "ctrl-w shift-left": [
- "workspace::SwapPaneInDirection",
- "Left"
- ],
- "ctrl-w shift-right": [
- "workspace::SwapPaneInDirection",
- "Right"
- ],
- "ctrl-w shift-up": [
- "workspace::SwapPaneInDirection",
- "Up"
- ],
- "ctrl-w shift-down": [
- "workspace::SwapPaneInDirection",
- "Down"
- ],
- "ctrl-w shift-h": [
- "workspace::SwapPaneInDirection",
- "Left"
- ],
- "ctrl-w shift-l": [
- "workspace::SwapPaneInDirection",
- "Right"
- ],
- "ctrl-w shift-k": [
- "workspace::SwapPaneInDirection",
- "Up"
- ],
- "ctrl-w shift-j": [
- "workspace::SwapPaneInDirection",
- "Down"
- ],
+ "ctrl-w left": ["workspace::ActivatePaneInDirection", "Left"],
+ "ctrl-w right": ["workspace::ActivatePaneInDirection", "Right"],
+ "ctrl-w up": ["workspace::ActivatePaneInDirection", "Up"],
+ "ctrl-w down": ["workspace::ActivatePaneInDirection", "Down"],
+ "ctrl-w h": ["workspace::ActivatePaneInDirection", "Left"],
+ "ctrl-w l": ["workspace::ActivatePaneInDirection", "Right"],
+ "ctrl-w k": ["workspace::ActivatePaneInDirection", "Up"],
+ "ctrl-w j": ["workspace::ActivatePaneInDirection", "Down"],
+ "ctrl-w ctrl-h": ["workspace::ActivatePaneInDirection", "Left"],
+ "ctrl-w ctrl-l": ["workspace::ActivatePaneInDirection", "Right"],
+ "ctrl-w ctrl-k": ["workspace::ActivatePaneInDirection", "Up"],
+ "ctrl-w ctrl-j": ["workspace::ActivatePaneInDirection", "Down"],
+ "ctrl-w shift-left": ["workspace::SwapPaneInDirection", "Left"],
+ "ctrl-w shift-right": ["workspace::SwapPaneInDirection", "Right"],
+ "ctrl-w shift-up": ["workspace::SwapPaneInDirection", "Up"],
+ "ctrl-w shift-down": ["workspace::SwapPaneInDirection", "Down"],
+ "ctrl-w shift-h": ["workspace::SwapPaneInDirection", "Left"],
+ "ctrl-w shift-l": ["workspace::SwapPaneInDirection", "Right"],
+ "ctrl-w shift-k": ["workspace::SwapPaneInDirection", "Up"],
+ "ctrl-w shift-j": ["workspace::SwapPaneInDirection", "Down"],
"ctrl-w g t": "pane::ActivateNextItem",
"ctrl-w ctrl-g t": "pane::ActivateNextItem",
"ctrl-w g shift-t": "pane::ActivatePrevItem",
@@ -371,14 +279,8 @@
"ctrl-w ctrl-q": "pane::CloseAllItems",
"ctrl-w o": "workspace::CloseInactiveTabsAndPanes",
"ctrl-w ctrl-o": "workspace::CloseInactiveTabsAndPanes",
- "ctrl-w n": [
- "workspace::NewFileInDirection",
- "Up"
- ],
- "ctrl-w ctrl-n": [
- "workspace::NewFileInDirection",
- "Up"
- ]
+ "ctrl-w n": ["workspace::NewFileInDirection", "Up"],
+ "ctrl-w ctrl-n": ["workspace::NewFileInDirection", "Up"]
}
},
{
@@ -393,21 +295,12 @@
"context": "Editor && vim_mode == normal && vim_operator == none && !VimWaiting",
"bindings": {
".": "vim::Repeat",
- "c": [
- "vim::PushOperator",
- "Change"
- ],
+ "c": ["vim::PushOperator", "Change"],
"shift-c": "vim::ChangeToEndOfLine",
- "d": [
- "vim::PushOperator",
- "Delete"
- ],
+ "d": ["vim::PushOperator", "Delete"],
"shift-d": "vim::DeleteToEndOfLine",
"shift-j": "vim::JoinLines",
- "y": [
- "vim::PushOperator",
- "Yank"
- ],
+ "y": ["vim::PushOperator", "Yank"],
"shift-y": "vim::YankLine",
"i": "vim::InsertBefore",
"shift-i": "vim::InsertFirstNonWhitespace",
@@ -443,10 +336,7 @@
"backwards": true
}
],
- "r": [
- "vim::PushOperator",
- "Replace"
- ],
+ "r": ["vim::PushOperator", "Replace"],
"s": "vim::Substitute",
"shift-s": "vim::SubstituteLine",
"> >": "editor::Indent",
@@ -458,10 +348,7 @@
{
"context": "Editor && VimCount",
"bindings": {
- "0": [
- "vim::Number",
- 0
- ]
+ "0": ["vim::Number", 0]
}
},
{
@@ -497,12 +384,15 @@
"'": "vim::Quotes",
"`": "vim::BackQuotes",
"\"": "vim::DoubleQuotes",
+ "|": "vim::VerticalBars",
"(": "vim::Parentheses",
")": "vim::Parentheses",
+ "b": "vim::Parentheses",
"[": "vim::SquareBrackets",
"]": "vim::SquareBrackets",
"{": "vim::CurlyBrackets",
"}": "vim::CurlyBrackets",
+ "shift-b": "vim::CurlyBrackets",
"<": "vim::AngleBrackets",
">": "vim::AngleBrackets"
}
@@ -548,22 +438,10 @@
"shift-i": "vim::InsertBefore",
"shift-a": "vim::InsertAfter",
"shift-j": "vim::JoinLines",
- "r": [
- "vim::PushOperator",
- "Replace"
- ],
- "ctrl-c": [
- "vim::SwitchMode",
- "Normal"
- ],
- "escape": [
- "vim::SwitchMode",
- "Normal"
- ],
- "ctrl+[": [
- "vim::SwitchMode",
- "Normal"
- ],
+ "r": ["vim::PushOperator", "Replace"],
+ "ctrl-c": ["vim::SwitchMode", "Normal"],
+ "escape": ["vim::SwitchMode", "Normal"],
+ "ctrl+[": ["vim::SwitchMode", "Normal"],
">": "editor::Indent",
"<": "editor::Outdent",
"i": [
@@ -602,14 +480,8 @@
"bindings": {
"tab": "vim::Tab",
"enter": "vim::Enter",
- "escape": [
- "vim::SwitchMode",
- "Normal"
- ],
- "ctrl+[": [
- "vim::SwitchMode",
- "Normal"
- ]
+ "escape": ["vim::SwitchMode", "Normal"],
+ "ctrl+[": ["vim::SwitchMode", "Normal"]
}
},
{
diff --git a/assets/settings/default.json b/assets/settings/default.json
index 1611d80e2f..19c73ca021 100644
--- a/assets/settings/default.json
+++ b/assets/settings/default.json
@@ -50,6 +50,9 @@
// Whether to pop the completions menu while typing in an editor without
// explicitly requesting it.
"show_completions_on_input": true,
+ // Whether to display inline and alongside documentation for items in the
+ // completions menu
+ "show_completion_documentation": true,
// Whether to show wrap guides in the editor. Setting this to true will
// show a guide at the 'preferred_line_length' value if softwrap is set to
// 'preferred_line_length', and will show any additional guides as specified
@@ -139,6 +142,14 @@
// Default width of the channels panel.
"default_width": 240
},
+ "notification_panel": {
+ // Whether to show the collaboration panel button in the status bar.
+ "button": true,
+ // Where to dock channels panel. Can be 'left' or 'right'.
+ "dock": "right",
+ // Default width of the channels panel.
+ "default_width": 380
+ },
"assistant": {
// Whether to show the assistant panel button in the status bar.
"button": true,
diff --git a/crates/Cargo.toml b/crates/Cargo.toml
new file mode 100644
index 0000000000..fb49a4b515
--- /dev/null
+++ b/crates/Cargo.toml
@@ -0,0 +1,38 @@
+[package]
+name = "ai"
+version = "0.1.0"
+edition = "2021"
+publish = false
+
+[lib]
+path = "src/ai.rs"
+doctest = false
+
+[features]
+test-support = []
+
+[dependencies]
+gpui = { path = "../gpui" }
+util = { path = "../util" }
+language = { path = "../language" }
+async-trait.workspace = true
+anyhow.workspace = true
+futures.workspace = true
+lazy_static.workspace = true
+ordered-float.workspace = true
+parking_lot.workspace = true
+isahc.workspace = true
+regex.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+postage.workspace = true
+rand.workspace = true
+log.workspace = true
+parse_duration = "2.1.1"
+tiktoken-rs = "0.5.0"
+matrixmultiply = "0.3.7"
+rusqlite = { version = "0.29.0", features = ["blob", "array", "modern_sqlite"] }
+bincode = "1.3.3"
+
+[dev-dependencies]
+gpui = { path = "../gpui", features = ["test-support"] }
diff --git a/crates/ai/Cargo.toml b/crates/ai/Cargo.toml
index 542d7f422f..fb49a4b515 100644
--- a/crates/ai/Cargo.toml
+++ b/crates/ai/Cargo.toml
@@ -8,9 +8,13 @@ publish = false
path = "src/ai.rs"
doctest = false
+[features]
+test-support = []
+
[dependencies]
gpui = { path = "../gpui" }
util = { path = "../util" }
+language = { path = "../language" }
async-trait.workspace = true
anyhow.workspace = true
futures.workspace = true
diff --git a/crates/ai/src/ai.rs b/crates/ai/src/ai.rs
index 5256a6a643..dda22d2a1d 100644
--- a/crates/ai/src/ai.rs
+++ b/crates/ai/src/ai.rs
@@ -1,2 +1,8 @@
+pub mod auth;
pub mod completion;
pub mod embedding;
+pub mod models;
+pub mod prompts;
+pub mod providers;
+#[cfg(any(test, feature = "test-support"))]
+pub mod test;
diff --git a/crates/ai/src/auth.rs b/crates/ai/src/auth.rs
new file mode 100644
index 0000000000..c6256df216
--- /dev/null
+++ b/crates/ai/src/auth.rs
@@ -0,0 +1,15 @@
+use gpui::AppContext;
+
+#[derive(Clone, Debug)]
+pub enum ProviderCredential {
+ Credentials { api_key: String },
+ NoCredentials,
+ NotNeeded,
+}
+
+pub trait CredentialProvider: Send + Sync {
+ fn has_credentials(&self) -> bool;
+ fn retrieve_credentials(&self, cx: &AppContext) -> ProviderCredential;
+ fn save_credentials(&self, cx: &AppContext, credential: ProviderCredential);
+ fn delete_credentials(&self, cx: &AppContext);
+}
diff --git a/crates/ai/src/completion.rs b/crates/ai/src/completion.rs
index 170b2268f9..30a60fcf1d 100644
--- a/crates/ai/src/completion.rs
+++ b/crates/ai/src/completion.rs
@@ -1,212 +1,23 @@
-use anyhow::{anyhow, Result};
-use futures::{
- future::BoxFuture, io::BufReader, stream::BoxStream, AsyncBufReadExt, AsyncReadExt, FutureExt,
- Stream, StreamExt,
-};
-use gpui::executor::Background;
-use isahc::{http::StatusCode, Request, RequestExt};
-use serde::{Deserialize, Serialize};
-use std::{
- fmt::{self, Display},
- io,
- sync::Arc,
-};
+use anyhow::Result;
+use futures::{future::BoxFuture, stream::BoxStream};
-pub const OPENAI_API_URL: &'static str = "https://api.openai.com/v1";
+use crate::{auth::CredentialProvider, models::LanguageModel};
-#[derive(Clone, Copy, Serialize, Deserialize, Debug, Eq, PartialEq)]
-#[serde(rename_all = "lowercase")]
-pub enum Role {
- User,
- Assistant,
- System,
+pub trait CompletionRequest: Send + Sync {
+ fn data(&self) -> serde_json::Result;
}
-impl Role {
- pub fn cycle(&mut self) {
- *self = match self {
- Role::User => Role::Assistant,
- Role::Assistant => Role::System,
- Role::System => Role::User,
- }
- }
-}
-
-impl Display for Role {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
- match self {
- Role::User => write!(f, "User"),
- Role::Assistant => write!(f, "Assistant"),
- Role::System => write!(f, "System"),
- }
- }
-}
-
-#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
-pub struct RequestMessage {
- pub role: Role,
- pub content: String,
-}
-
-#[derive(Debug, Default, Serialize)]
-pub struct OpenAIRequest {
- pub model: String,
- pub messages: Vec,
- pub stream: bool,
-}
-
-#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
-pub struct ResponseMessage {
- pub role: Option,
- pub content: Option,
-}
-
-#[derive(Deserialize, Debug)]
-pub struct OpenAIUsage {
- pub prompt_tokens: u32,
- pub completion_tokens: u32,
- pub total_tokens: u32,
-}
-
-#[derive(Deserialize, Debug)]
-pub struct ChatChoiceDelta {
- pub index: u32,
- pub delta: ResponseMessage,
- pub finish_reason: Option,
-}
-
-#[derive(Deserialize, Debug)]
-pub struct OpenAIResponseStreamEvent {
- pub id: Option,
- pub object: String,
- pub created: u32,
- pub model: String,
- pub choices: Vec,
- pub usage: Option,
-}
-
-pub async fn stream_completion(
- api_key: String,
- executor: Arc,
- mut request: OpenAIRequest,
-) -> Result>> {
- request.stream = true;
-
- let (tx, rx) = futures::channel::mpsc::unbounded::>();
-
- let json_data = serde_json::to_string(&request)?;
- let mut response = Request::post(format!("{OPENAI_API_URL}/chat/completions"))
- .header("Content-Type", "application/json")
- .header("Authorization", format!("Bearer {}", api_key))
- .body(json_data)?
- .send_async()
- .await?;
-
- let status = response.status();
- if status == StatusCode::OK {
- executor
- .spawn(async move {
- let mut lines = BufReader::new(response.body_mut()).lines();
-
- fn parse_line(
- line: Result,
- ) -> Result