Rename zed2 -> zed

Max Brunsfeld and Mikayla created

Co-authored-by: Mikayla <mikayla@zed.dev>

Change summary

.github/workflows/release_nightly.yml                  |    2 
Cargo.lock                                             |  522 --
Cargo.toml                                             |    1 
crates/zed/Cargo.toml                                  |  144 
crates/zed/build.rs                                    |   50 
crates/zed/examples/semantic_index_eval.rs             |  533 --
crates/zed/src/app_menus.rs                            |    0 
crates/zed/src/assets.rs                               |   18 
crates/zed/src/languages.rs                            |   22 
crates/zed/src/languages/c.rs                          |   14 
crates/zed/src/languages/elixir.rs                     |   10 
crates/zed/src/languages/elixir/embedding.scm          |    4 
crates/zed/src/languages/go.rs                         |   18 
crates/zed/src/languages/json.rs                       |    2 
crates/zed/src/languages/language_plugin.rs            |    4 
crates/zed/src/languages/nu.rs                         |   30 
crates/zed/src/languages/python.rs                     |   14 
crates/zed/src/languages/rust.rs                       |   34 
crates/zed/src/languages/typescript.rs                 |    8 
crates/zed/src/languages/uiua/config.toml              |    2 
crates/zed/src/main.rs                                 |  530 +-
crates/zed/src/menus.rs                                |  174 
crates/zed/src/open_listener.rs                        |  170 
crates/zed/src/test.rs                                 |    7 
crates/zed/src/zed.rs                                  |  937 ++--
crates/zed2/Cargo.toml                                 |  192 
crates/zed2/build.rs                                   |   44 
crates/zed2/contents/dev/embedded.provisionprofile     |    0 
crates/zed2/contents/nightly/embedded.provisionprofile |    0 
crates/zed2/contents/preview/embedded.provisionprofile |    0 
crates/zed2/contents/stable/embedded.provisionprofile  |    0 
crates/zed2/resources/app-icon-nightly.png             |    0 
crates/zed2/resources/app-icon-nightly@2x.png          |    0 
crates/zed2/resources/app-icon-preview.png             |    0 
crates/zed2/resources/app-icon-preview@2x.png          |    0 
crates/zed2/resources/app-icon.png                     |    0 
crates/zed2/resources/app-icon@2x.png                  |    0 
crates/zed2/resources/info/DocumentTypes.plist         |   62 
crates/zed2/resources/info/Permissions.plist           |   24 
crates/zed2/resources/zed.entitlements                 |   24 
crates/zed2/src/assets.rs                              |   35 
crates/zed2/src/languages.rs                           |  299 -
crates/zed2/src/languages/bash/brackets.scm            |    3 
crates/zed2/src/languages/bash/config.toml             |    9 
crates/zed2/src/languages/bash/highlights.scm          |   59 
crates/zed2/src/languages/c.rs                         |  321 -
crates/zed2/src/languages/c/brackets.scm               |    3 
crates/zed2/src/languages/c/config.toml                |   12 
crates/zed2/src/languages/c/embedding.scm              |   43 
crates/zed2/src/languages/c/highlights.scm             |  109 
crates/zed2/src/languages/c/indents.scm                |    9 
crates/zed2/src/languages/c/injections.scm             |    7 
crates/zed2/src/languages/c/outline.scm                |   70 
crates/zed2/src/languages/c/overrides.scm              |    2 
crates/zed2/src/languages/cpp/brackets.scm             |    3 
crates/zed2/src/languages/cpp/config.toml              |   12 
crates/zed2/src/languages/cpp/embedding.scm            |   61 
crates/zed2/src/languages/cpp/highlights.scm           |  158 
crates/zed2/src/languages/cpp/indents.scm              |    7 
crates/zed2/src/languages/cpp/injections.scm           |    7 
crates/zed2/src/languages/cpp/outline.scm              |  149 
crates/zed2/src/languages/cpp/overrides.scm            |    2 
crates/zed2/src/languages/css.rs                       |  130 
crates/zed2/src/languages/css/brackets.scm             |    3 
crates/zed2/src/languages/css/config.toml              |   13 
crates/zed2/src/languages/css/highlights.scm           |   78 
crates/zed2/src/languages/css/indents.scm              |    1 
crates/zed2/src/languages/css/overrides.scm            |    2 
crates/zed2/src/languages/elixir.rs                    |  542 --
crates/zed2/src/languages/elixir/brackets.scm          |    5 
crates/zed2/src/languages/elixir/config.toml           |   16 
crates/zed2/src/languages/elixir/embedding.scm         |   27 
crates/zed2/src/languages/elixir/highlights.scm        |  153 
crates/zed2/src/languages/elixir/indents.scm           |    6 
crates/zed2/src/languages/elixir/injections.scm        |    7 
crates/zed2/src/languages/elixir/outline.scm           |   26 
crates/zed2/src/languages/elixir/overrides.scm         |    2 
crates/zed2/src/languages/elm/config.toml              |   11 
crates/zed2/src/languages/elm/highlights.scm           |   72 
crates/zed2/src/languages/elm/injections.scm           |    2 
crates/zed2/src/languages/elm/outline.scm              |   22 
crates/zed2/src/languages/erb/config.toml              |    8 
crates/zed2/src/languages/erb/highlights.scm           |   12 
crates/zed2/src/languages/erb/injections.scm           |    7 
crates/zed2/src/languages/glsl/config.toml             |    9 
crates/zed2/src/languages/glsl/highlights.scm          |  118 
crates/zed2/src/languages/go.rs                        |  461 --
crates/zed2/src/languages/go/brackets.scm              |    3 
crates/zed2/src/languages/go/config.toml               |   12 
crates/zed2/src/languages/go/embedding.scm             |   24 
crates/zed2/src/languages/go/highlights.scm            |  107 
crates/zed2/src/languages/go/indents.scm               |    9 
crates/zed2/src/languages/go/outline.scm               |   43 
crates/zed2/src/languages/go/overrides.scm             |    6 
crates/zed2/src/languages/heex/config.toml             |   12 
crates/zed2/src/languages/heex/highlights.scm          |   57 
crates/zed2/src/languages/heex/injections.scm          |   13 
crates/zed2/src/languages/heex/overrides.scm           |    4 
crates/zed2/src/languages/html.rs                      |  130 
crates/zed2/src/languages/html/brackets.scm            |    2 
crates/zed2/src/languages/html/config.toml             |   14 
crates/zed2/src/languages/html/highlights.scm          |   15 
crates/zed2/src/languages/html/indents.scm             |    6 
crates/zed2/src/languages/html/injections.scm          |    7 
crates/zed2/src/languages/html/outline.scm             |    0 
crates/zed2/src/languages/html/overrides.scm           |    2 
crates/zed2/src/languages/javascript/brackets.scm      |    5 
crates/zed2/src/languages/javascript/config.toml       |   26 
crates/zed2/src/languages/javascript/contexts.scm      |    0 
crates/zed2/src/languages/javascript/embedding.scm     |   71 
crates/zed2/src/languages/javascript/highlights.scm    |  217 -
crates/zed2/src/languages/javascript/indents.scm       |   15 
crates/zed2/src/languages/javascript/outline.scm       |   62 
crates/zed2/src/languages/javascript/overrides.scm     |   18 
crates/zed2/src/languages/json.rs                      |  185 
crates/zed2/src/languages/json/brackets.scm            |    3 
crates/zed2/src/languages/json/config.toml             |   10 
crates/zed2/src/languages/json/embedding.scm           |   14 
crates/zed2/src/languages/json/highlights.scm          |   21 
crates/zed2/src/languages/json/indents.scm             |    2 
crates/zed2/src/languages/json/outline.scm             |    2 
crates/zed2/src/languages/json/overrides.scm           |    1 
crates/zed2/src/languages/language_plugin.rs           |  168 
crates/zed2/src/languages/lua.rs                       |  135 
crates/zed2/src/languages/lua/brackets.scm             |    3 
crates/zed2/src/languages/lua/config.toml              |   10 
crates/zed2/src/languages/lua/embedding.scm            |   10 
crates/zed2/src/languages/lua/highlights.scm           |  198 
crates/zed2/src/languages/lua/indents.scm              |   10 
crates/zed2/src/languages/lua/outline.scm              |    3 
crates/zed2/src/languages/markdown/config.toml         |   11 
crates/zed2/src/languages/markdown/highlights.scm      |   24 
crates/zed2/src/languages/markdown/injections.scm      |    4 
crates/zed2/src/languages/nix/config.toml              |   11 
crates/zed2/src/languages/nix/highlights.scm           |   89 
crates/zed2/src/languages/nu.rs                        |   55 
crates/zed2/src/languages/nu/brackets.scm              |    4 
crates/zed2/src/languages/nu/config.toml               |    9 
crates/zed2/src/languages/nu/highlights.scm            |  302 -
crates/zed2/src/languages/nu/indents.scm               |    3 
crates/zed2/src/languages/php.rs                       |  136 
crates/zed2/src/languages/php/config.toml              |   14 
crates/zed2/src/languages/php/embedding.scm            |   36 
crates/zed2/src/languages/php/highlights.scm           |  123 
crates/zed2/src/languages/php/injections.scm           |    3 
crates/zed2/src/languages/php/outline.scm              |   29 
crates/zed2/src/languages/php/tags.scm                 |   40 
crates/zed2/src/languages/python.rs                    |  296 -
crates/zed2/src/languages/python/brackets.scm          |    3 
crates/zed2/src/languages/python/config.toml           |   16 
crates/zed2/src/languages/python/embedding.scm         |    9 
crates/zed2/src/languages/python/highlights.scm        |  125 
crates/zed2/src/languages/python/indents.scm           |    3 
crates/zed2/src/languages/python/outline.scm           |    9 
crates/zed2/src/languages/python/overrides.scm         |    2 
crates/zed2/src/languages/racket/brackets.scm          |    3 
crates/zed2/src/languages/racket/config.toml           |    9 
crates/zed2/src/languages/racket/highlights.scm        |   34 
crates/zed2/src/languages/racket/indents.scm           |    3 
crates/zed2/src/languages/racket/outline.scm           |   10 
crates/zed2/src/languages/ruby.rs                      |  160 
crates/zed2/src/languages/ruby/brackets.scm            |   14 
crates/zed2/src/languages/ruby/config.toml             |   13 
crates/zed2/src/languages/ruby/embedding.scm           |   22 
crates/zed2/src/languages/ruby/highlights.scm          |  181 
crates/zed2/src/languages/ruby/indents.scm             |   17 
crates/zed2/src/languages/ruby/outline.scm             |   17 
crates/zed2/src/languages/ruby/overrides.scm           |    2 
crates/zed2/src/languages/rust.rs                      |  568 --
crates/zed2/src/languages/rust/brackets.scm            |    6 
crates/zed2/src/languages/rust/config.toml             |   13 
crates/zed2/src/languages/rust/embedding.scm           |   32 
crates/zed2/src/languages/rust/highlights.scm          |  116 
crates/zed2/src/languages/rust/indents.scm             |   14 
crates/zed2/src/languages/rust/injections.scm          |    7 
crates/zed2/src/languages/rust/outline.scm             |   63 
crates/zed2/src/languages/rust/overrides.scm           |    8 
crates/zed2/src/languages/scheme/brackets.scm          |    3 
crates/zed2/src/languages/scheme/config.toml           |    9 
crates/zed2/src/languages/scheme/highlights.scm        |   28 
crates/zed2/src/languages/scheme/indents.scm           |    3 
crates/zed2/src/languages/scheme/outline.scm           |   10 
crates/zed2/src/languages/scheme/overrides.scm         |    6 
crates/zed2/src/languages/svelte.rs                    |  133 
crates/zed2/src/languages/svelte/config.toml           |   20 
crates/zed2/src/languages/svelte/folds.scm             |    9 
crates/zed2/src/languages/svelte/highlights.scm        |   42 
crates/zed2/src/languages/svelte/indents.scm           |    8 
crates/zed2/src/languages/svelte/injections.scm        |   28 
crates/zed2/src/languages/svelte/overrides.scm         |    7 
crates/zed2/src/languages/tailwind.rs                  |  171 
crates/zed2/src/languages/toml/brackets.scm            |    3 
crates/zed2/src/languages/toml/config.toml             |   10 
crates/zed2/src/languages/toml/highlights.scm          |   37 
crates/zed2/src/languages/toml/indents.scm             |    0 
crates/zed2/src/languages/toml/outline.scm             |   15 
crates/zed2/src/languages/toml/overrides.scm           |    2 
crates/zed2/src/languages/tsx/brackets.scm             |    1 
crates/zed2/src/languages/tsx/config.toml              |   25 
crates/zed2/src/languages/tsx/embedding.scm            |   85 
crates/zed2/src/languages/tsx/highlights-jsx.scm       |    0 
crates/zed2/src/languages/tsx/highlights.scm           |    1 
crates/zed2/src/languages/tsx/indents.scm              |    1 
crates/zed2/src/languages/tsx/outline.scm              |    1 
crates/zed2/src/languages/tsx/overrides.scm            |   18 
crates/zed2/src/languages/typescript.rs                |  400 -
crates/zed2/src/languages/typescript/brackets.scm      |    5 
crates/zed2/src/languages/typescript/config.toml       |   16 
crates/zed2/src/languages/typescript/embedding.scm     |   85 
crates/zed2/src/languages/typescript/highlights.scm    |  221 -
crates/zed2/src/languages/typescript/indents.scm       |   15 
crates/zed2/src/languages/typescript/outline.scm       |   65 
crates/zed2/src/languages/typescript/overrides.scm     |    2 
crates/zed2/src/languages/uiua.rs                      |   55 
crates/zed2/src/languages/uiua/config.toml             |   10 
crates/zed2/src/languages/uiua/highlights.scm          |   50 
crates/zed2/src/languages/uiua/indents.scm             |    3 
crates/zed2/src/languages/vue.rs                       |  220 -
crates/zed2/src/languages/vue/brackets.scm             |    2 
crates/zed2/src/languages/vue/config.toml              |   14 
crates/zed2/src/languages/vue/highlights.scm           |   15 
crates/zed2/src/languages/vue/injections.scm           |    7 
crates/zed2/src/languages/yaml.rs                      |  146 
crates/zed2/src/languages/yaml/brackets.scm            |    3 
crates/zed2/src/languages/yaml/config.toml             |   12 
crates/zed2/src/languages/yaml/highlights.scm          |   49 
crates/zed2/src/languages/yaml/outline.scm             |    1 
crates/zed2/src/main.rs                                |  799 ---
crates/zed2/src/only_instance.rs                       |  105 
crates/zed2/src/open_listener.rs                       |  303 -
crates/zed2/src/zed2.rs                                | 2598 ------------
docs/old/local-collaboration.md                        |    2 
docs/src/developing_zed__local_collaboration.md        |    2 
script/bundle                                          |   14 
script/crate-dep-graph                                 |    2 
script/zed-2-progress-report.py                        |   27 
script/zed-local                                       |   10 
237 files changed, 1,077 insertions(+), 15,889 deletions(-)

Detailed changes

.github/workflows/release_nightly.yml 🔗

@@ -92,7 +92,7 @@ jobs:
               run: script/generate-licenses
 
             - name: Create app bundle
-              run: script/bundle -2
+              run: script/bundle
 
             - name: Upload Zed Nightly
               run: script/upload-nightly

Cargo.lock 🔗

@@ -38,22 +38,13 @@ dependencies = [
  "workspace2",
 ]
 
-[[package]]
-name = "addr2line"
-version = "0.17.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
-dependencies = [
- "gimli 0.26.2",
-]
-
 [[package]]
 name = "addr2line"
 version = "0.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
 dependencies = [
- "gimli 0.28.0",
+ "gimli",
 ]
 
 [[package]]
@@ -237,12 +228,6 @@ dependencies = [
  "pkg-config",
 ]
 
-[[package]]
-name = "ambient-authority"
-version = "0.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec8ad6edb4840b78c5c3d88de606b22252d552b55f3a4699fbb10fc070ec3049"
-
 [[package]]
 name = "android-tzdata"
 version = "0.1.1"
@@ -368,7 +353,7 @@ dependencies = [
  "collections",
  "ctor",
  "editor",
- "env_logger 0.9.3",
+ "env_logger",
  "fs",
  "futures 0.3.28",
  "gpui",
@@ -408,7 +393,7 @@ dependencies = [
  "collections",
  "ctor",
  "editor2",
- "env_logger 0.9.3",
+ "env_logger",
  "fs2",
  "futures 0.3.28",
  "gpui2",
@@ -913,12 +898,12 @@ version = "0.3.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
 dependencies = [
- "addr2line 0.21.0",
+ "addr2line",
  "cc",
  "cfg-if 1.0.0",
  "libc",
  "miniz_oxide 0.7.1",
- "object 0.32.1",
+ "object",
  "rustc-demangle",
 ]
 
@@ -1307,71 +1292,6 @@ dependencies = [
  "util",
 ]
 
-[[package]]
-name = "cap-fs-ext"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b0e103ce36d217d568903ad27b14ec2238ecb5d65bad2e756a8f3c0d651506e"
-dependencies = [
- "cap-primitives",
- "cap-std",
- "io-lifetimes 0.7.5",
- "windows-sys 0.36.1",
-]
-
-[[package]]
-name = "cap-primitives"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af3f336aa91cce16033ed3c94ac91d98956c49b420e6d6cd0dd7d0e386a57085"
-dependencies = [
- "ambient-authority",
- "fs-set-times",
- "io-extras",
- "io-lifetimes 0.7.5",
- "ipnet",
- "maybe-owned",
- "rustix 0.35.16",
- "winapi-util",
- "windows-sys 0.36.1",
- "winx",
-]
-
-[[package]]
-name = "cap-rand"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d14b9606aa9550d34651bc481443203bc014237bdb992d201d2afa62d2ec6dea"
-dependencies = [
- "ambient-authority",
- "rand 0.8.5",
-]
-
-[[package]]
-name = "cap-std"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9d6e70b626eceac9d6fc790fe2d72cc3f2f7bc3c35f467690c54a526b0f56db"
-dependencies = [
- "cap-primitives",
- "io-extras",
- "io-lifetimes 0.7.5",
- "ipnet",
- "rustix 0.35.16",
-]
-
-[[package]]
-name = "cap-time-ext"
-version = "0.26.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3a0524f7c4cff2ea547ae2b652bf7a348fd3e48f76556dc928d8b45ab2f1d50"
-dependencies = [
- "cap-primitives",
- "once_cell",
- "rustix 0.35.16",
- "winx",
-]
-
 [[package]]
 name = "castaway"
 version = "0.1.2"
@@ -1783,7 +1703,7 @@ dependencies = [
  "ctor",
  "dashmap",
  "editor",
- "env_logger 0.9.3",
+ "env_logger",
  "envy",
  "fs",
  "futures 0.3.28",
@@ -1856,7 +1776,7 @@ dependencies = [
  "ctor",
  "dashmap",
  "editor2",
- "env_logger 0.9.3",
+ "env_logger",
  "envy",
  "fs2",
  "futures 0.3.28",
@@ -2037,7 +1957,7 @@ dependencies = [
  "collections",
  "ctor",
  "editor",
- "env_logger 0.9.3",
+ "env_logger",
  "fuzzy",
  "gpui",
  "language",
@@ -2059,7 +1979,7 @@ dependencies = [
  "collections",
  "ctor",
  "editor2",
- "env_logger 0.9.3",
+ "env_logger",
  "fuzzy2",
  "go_to_line2",
  "gpui2",
@@ -2352,15 +2272,6 @@ dependencies = [
  "windows 0.46.0",
 ]
 
-[[package]]
-name = "cpp_demangle"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eeaa953eaad386a53111e47172c2fedba671e5684c8dd601a5f474f4f118710f"
-dependencies = [
- "cfg-if 1.0.0",
-]
-
 [[package]]
 name = "cpufeatures"
 version = "0.2.9"
@@ -2370,41 +2281,12 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "cranelift-bforest"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "593b398dd0c5b1e2e3a9c3dae8584e287894ea84e361949ad506376e99196265"
-dependencies = [
- "cranelift-entity 0.89.2",
-]
-
 [[package]]
 name = "cranelift-bforest"
 version = "0.103.0"
 source = "git+https://github.com/bytecodealliance/wasmtime?rev=v16.0.0#6613acd1e4817957a4a7745125ef063b43c273a7"
 dependencies = [
- "cranelift-entity 0.103.0",
-]
-
-[[package]]
-name = "cranelift-codegen"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afc0d8faabd099ea15ab33d49d150e5572c04cfeb95d675fd41286739b754629"
-dependencies = [
- "arrayvec 0.7.4",
- "bumpalo",
- "cranelift-bforest 0.89.2",
- "cranelift-codegen-meta 0.89.2",
- "cranelift-codegen-shared 0.89.2",
- "cranelift-entity 0.89.2",
- "cranelift-isle 0.89.2",
- "gimli 0.26.2",
- "log",
- "regalloc2 0.4.2",
- "smallvec",
- "target-lexicon",
+ "cranelift-entity",
 ]
 
 [[package]]
@@ -2413,43 +2295,28 @@ version = "0.103.0"
 source = "git+https://github.com/bytecodealliance/wasmtime?rev=v16.0.0#6613acd1e4817957a4a7745125ef063b43c273a7"
 dependencies = [
  "bumpalo",
- "cranelift-bforest 0.103.0",
- "cranelift-codegen-meta 0.103.0",
- "cranelift-codegen-shared 0.103.0",
+ "cranelift-bforest",
+ "cranelift-codegen-meta",
+ "cranelift-codegen-shared",
  "cranelift-control",
- "cranelift-entity 0.103.0",
- "cranelift-isle 0.103.0",
- "gimli 0.28.0",
+ "cranelift-entity",
+ "cranelift-isle",
+ "gimli",
  "hashbrown 0.14.0",
  "log",
- "regalloc2 0.9.3",
+ "regalloc2",
  "smallvec",
  "target-lexicon",
 ]
 
-[[package]]
-name = "cranelift-codegen-meta"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ac1669e42579476f001571d6ba4b825fac686282c97b88b18f8e34242066a81"
-dependencies = [
- "cranelift-codegen-shared 0.89.2",
-]
-
 [[package]]
 name = "cranelift-codegen-meta"
 version = "0.103.0"
 source = "git+https://github.com/bytecodealliance/wasmtime?rev=v16.0.0#6613acd1e4817957a4a7745125ef063b43c273a7"
 dependencies = [
- "cranelift-codegen-shared 0.103.0",
+ "cranelift-codegen-shared",
 ]
 
-[[package]]
-name = "cranelift-codegen-shared"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2a1b1eef9640ab72c1e7b583ac678083855a509da34b4b4378bd99954127c20"
-
 [[package]]
 name = "cranelift-codegen-shared"
 version = "0.103.0"
@@ -2463,15 +2330,6 @@ dependencies = [
  "arbitrary",
 ]
 
-[[package]]
-name = "cranelift-entity"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eea4e17c3791fd8134640b26242a9ddbd7c67db78f0bad98cb778bf563ef81a0"
-dependencies = [
- "serde",
-]
-
 [[package]]
 name = "cranelift-entity"
 version = "0.103.0"
@@ -2481,90 +2339,45 @@ dependencies = [
  "serde_derive",
 ]
 
-[[package]]
-name = "cranelift-frontend"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fca1474b5302348799656d43a40eacd716a3b46169405a3af812832c9edf77b4"
-dependencies = [
- "cranelift-codegen 0.89.2",
- "log",
- "smallvec",
- "target-lexicon",
-]
-
 [[package]]
 name = "cranelift-frontend"
 version = "0.103.0"
 source = "git+https://github.com/bytecodealliance/wasmtime?rev=v16.0.0#6613acd1e4817957a4a7745125ef063b43c273a7"
 dependencies = [
- "cranelift-codegen 0.103.0",
+ "cranelift-codegen",
  "log",
  "smallvec",
  "target-lexicon",
 ]
 
-[[package]]
-name = "cranelift-isle"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77aa537f020ea43483100153278e7215d41695bdcef9eea6642d122675f64249"
-
 [[package]]
 name = "cranelift-isle"
 version = "0.103.0"
 source = "git+https://github.com/bytecodealliance/wasmtime?rev=v16.0.0#6613acd1e4817957a4a7745125ef063b43c273a7"
 
-[[package]]
-name = "cranelift-native"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8bdc6b65241a95b7d8eafbf4e114c082e49b80162a2dcd9c6bcc5989c3310c9e"
-dependencies = [
- "cranelift-codegen 0.89.2",
- "libc",
- "target-lexicon",
-]
-
 [[package]]
 name = "cranelift-native"
 version = "0.103.0"
 source = "git+https://github.com/bytecodealliance/wasmtime?rev=v16.0.0#6613acd1e4817957a4a7745125ef063b43c273a7"
 dependencies = [
- "cranelift-codegen 0.103.0",
+ "cranelift-codegen",
  "libc",
  "target-lexicon",
 ]
 
-[[package]]
-name = "cranelift-wasm"
-version = "0.89.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb6359f606a1c80ccaa04fae9dbbb504615ec7a49b6c212b341080fff7a65dd"
-dependencies = [
- "cranelift-codegen 0.89.2",
- "cranelift-entity 0.89.2",
- "cranelift-frontend 0.89.2",
- "itertools 0.10.5",
- "log",
- "smallvec",
- "wasmparser 0.92.0",
- "wasmtime-types 2.0.2",
-]
-
 [[package]]
 name = "cranelift-wasm"
 version = "0.103.0"
 source = "git+https://github.com/bytecodealliance/wasmtime?rev=v16.0.0#6613acd1e4817957a4a7745125ef063b43c273a7"
 dependencies = [
- "cranelift-codegen 0.103.0",
- "cranelift-entity 0.103.0",
- "cranelift-frontend 0.103.0",
+ "cranelift-codegen",
+ "cranelift-entity",
+ "cranelift-frontend",
  "itertools 0.10.5",
  "log",
  "smallvec",
- "wasmparser 0.118.1",
- "wasmtime-types 16.0.0",
+ "wasmparser",
+ "wasmtime-types",
 ]
 
 [[package]]
@@ -2738,7 +2551,7 @@ dependencies = [
  "anyhow",
  "async-trait",
  "collections",
- "env_logger 0.9.3",
+ "env_logger",
  "gpui",
  "indoc",
  "lazy_static",
@@ -2760,7 +2573,7 @@ dependencies = [
  "anyhow",
  "async-trait",
  "collections",
- "env_logger 0.9.3",
+ "env_logger",
  "gpui2",
  "indoc",
  "lazy_static",
@@ -2950,16 +2763,6 @@ dependencies = [
  "subtle",
 ]
 
-[[package]]
-name = "directories-next"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc"
-dependencies = [
- "cfg-if 1.0.0",
- "dirs-sys-next",
-]
-
 [[package]]
 name = "dirs"
 version = "3.0.2"
@@ -3066,7 +2869,7 @@ dependencies = [
  "ctor",
  "db",
  "drag_and_drop",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "fuzzy",
  "git",
@@ -3118,7 +2921,7 @@ dependencies = [
  "copilot2",
  "ctor",
  "db2",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "fuzzy2",
  "git3",
@@ -3196,19 +2999,6 @@ dependencies = [
  "termcolor",
 ]
 
-[[package]]
-name = "env_logger"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
-dependencies = [
- "humantime",
- "is-terminal 0.4.10",
- "log",
- "regex",
- "termcolor",
-]
-
 [[package]]
 name = "envy"
 version = "0.4.2"
@@ -3233,17 +3023,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "errno"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
-dependencies = [
- "errno-dragonfly",
- "libc",
- "winapi 0.3.9",
-]
-
 [[package]]
 name = "errno"
 version = "0.3.3"
@@ -3431,16 +3210,6 @@ dependencies = [
  "workspace2",
 ]
 
-[[package]]
-name = "file-per-thread-logger"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866"
-dependencies = [
- "env_logger 0.10.1",
- "log",
-]
-
 [[package]]
 name = "file_finder"
 version = "0.1.0"
@@ -3448,7 +3217,7 @@ dependencies = [
  "collections",
  "ctor",
  "editor",
- "env_logger 0.9.3",
+ "env_logger",
  "fuzzy",
  "gpui",
  "language",
@@ -3471,7 +3240,7 @@ dependencies = [
  "collections",
  "ctor",
  "editor2",
- "env_logger 0.9.3",
+ "env_logger",
  "fuzzy2",
  "gpui2",
  "language2",
@@ -3660,17 +3429,6 @@ dependencies = [
  "util",
 ]
 
-[[package]]
-name = "fs-set-times"
-version = "0.17.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a267b6a9304912e018610d53fe07115d8b530b160e85db4d2d3a59f3ddde1aec"
-dependencies = [
- "io-lifetimes 0.7.5",
- "rustix 0.35.16",
- "windows-sys 0.36.1",
-]
-
 [[package]]
 name = "fs2"
 version = "0.1.0"
@@ -3894,15 +3652,6 @@ dependencies = [
  "util",
 ]
 
-[[package]]
-name = "fxhash"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
-dependencies = [
- "byteorder",
-]
-
 [[package]]
 name = "generic-array"
 version = "0.14.7"
@@ -3945,17 +3694,6 @@ dependencies = [
  "weezl",
 ]
 
-[[package]]
-name = "gimli"
-version = "0.26.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
-dependencies = [
- "fallible-iterator 0.2.0",
- "indexmap 1.9.3",
- "stable_deref_trait",
-]
-
 [[package]]
 name = "gimli"
 version = "0.28.0"
@@ -4101,7 +3839,7 @@ dependencies = [
  "ctor",
  "derive_more",
  "dhat",
- "env_logger 0.9.3",
+ "env_logger",
  "etagere",
  "font-kit",
  "foreign-types",
@@ -4164,7 +3902,7 @@ dependencies = [
  "ctor",
  "derive_more",
  "dhat",
- "env_logger 0.9.3",
+ "env_logger",
  "etagere",
  "font-kit",
  "foreign-types",
@@ -4347,15 +4085,6 @@ dependencies = [
  "libc",
 ]
 
-[[package]]
-name = "hermit-abi"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
-dependencies = [
- "libc",
-]
-
 [[package]]
 name = "hermit-abi"
 version = "0.3.3"
@@ -4652,26 +4381,6 @@ dependencies = [
  "cfg-if 1.0.0",
 ]
 
-[[package]]
-name = "io-extras"
-version = "0.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a5d8c2ab5becd8720e30fd25f8fa5500d8dc3fceadd8378f05859bd7b46fc49"
-dependencies = [
- "io-lifetimes 0.7.5",
- "windows-sys 0.36.1",
-]
-
-[[package]]
-name = "io-lifetimes"
-version = "0.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59ce5ef949d49ee85593fc4d3f3f95ad61657076395cbbce23e2121fc5542074"
-dependencies = [
- "libc",
- "windows-sys 0.42.0",
-]
-
 [[package]]
 name = "io-lifetimes"
 version = "1.0.11"
@@ -4717,29 +4426,6 @@ version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
 
-[[package]]
-name = "is-terminal"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d508111813f9af3afd2f92758f77e4ed2cc9371b642112c6a48d22eb73105c5"
-dependencies = [
- "hermit-abi 0.2.6",
- "io-lifetimes 0.7.5",
- "rustix 0.35.16",
- "windows-sys 0.36.1",
-]
-
-[[package]]
-name = "is-terminal"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
-dependencies = [
- "hermit-abi 0.3.3",
- "rustix 0.38.21",
- "windows-sys 0.52.0",
-]
-
 [[package]]
 name = "isahc"
 version = "1.7.2"
@@ -4791,26 +4477,6 @@ version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
 
-[[package]]
-name = "ittapi"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25a5c0b993601cad796222ea076565c5d9f337d35592f8622c753724f06d7271"
-dependencies = [
- "anyhow",
- "ittapi-sys",
- "log",
-]
-
-[[package]]
-name = "ittapi-sys"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb7b5e473765060536a660eed127f758cf1a810c73e49063264959c60d1727d9"
-dependencies = [
- "cc",
-]
-
 [[package]]
 name = "jni"
 version = "0.19.0"
@@ -4959,7 +4625,7 @@ dependencies = [
  "clock",
  "collections",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "fs",
  "futures 0.3.28",
  "fuzzy",
@@ -5014,7 +4680,7 @@ dependencies = [
  "clock",
  "collections",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "fuzzy2",
  "git3",
@@ -5100,7 +4766,7 @@ dependencies = [
  "client",
  "collections",
  "editor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "gpui",
  "language",
@@ -5123,7 +4789,7 @@ dependencies = [
  "client2",
  "collections",
  "editor2",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "gpui2",
  "language2",
@@ -5262,12 +4928,6 @@ dependencies = [
  "syn 2.0.37",
 ]
 
-[[package]]
-name = "linux-raw-sys"
-version = "0.0.46"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4d2456c373231a208ad294c33dc5bff30051eafd954cd4caae83a712b12854d"
-
 [[package]]
 name = "linux-raw-sys"
 version = "0.3.8"
@@ -5403,7 +5063,7 @@ dependencies = [
  "async-pipe",
  "collections",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "gpui",
  "log",
@@ -5438,7 +5098,7 @@ dependencies = [
  "async-pipe",
  "collections",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "gpui2",
  "log",
@@ -5511,12 +5171,6 @@ dependencies = [
  "rawpointer",
 ]
 
-[[package]]
-name = "maybe-owned"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4"
-
 [[package]]
 name = "md-5"
 version = "0.10.5"
@@ -5761,7 +5415,7 @@ dependencies = [
  "convert_case 0.6.0",
  "copilot",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "git",
  "gpui",
@@ -5809,7 +5463,7 @@ dependencies = [
  "convert_case 0.6.0",
  "copilot2",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "git3",
  "gpui2",
@@ -6280,18 +5934,6 @@ dependencies = [
  "cc",
 ]
 
-[[package]]
-name = "object"
-version = "0.29.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
-dependencies = [
- "crc32fast",
- "hashbrown 0.12.3",
- "indexmap 1.9.3",
- "memchr",
-]
-
 [[package]]
 name = "object"
 version = "0.32.1"
@@ -6678,7 +6320,7 @@ version = "0.1.0"
 dependencies = [
  "ctor",
  "editor",
- "env_logger 0.9.3",
+ "env_logger",
  "gpui",
  "menu",
  "parking_lot 0.11.2",
@@ -6695,7 +6337,7 @@ version = "0.1.0"
 dependencies = [
  "ctor",
  "editor2",
- "env_logger 0.9.3",
+ "env_logger",
  "gpui2",
  "menu2",
  "parking_lot 0.11.2",
@@ -6814,22 +6456,6 @@ dependencies = [
  "syn 1.0.109",
 ]
 
-[[package]]
-name = "plugin_runtime"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "bincode",
- "pollster",
- "serde",
- "serde_derive",
- "serde_json",
- "smol",
- "wasi-common",
- "wasmtime 2.0.2",
- "wasmtime-wasi",
-]
-
 [[package]]
 name = "png"
 version = "0.16.8"
@@ -7026,7 +6652,7 @@ dependencies = [
  "copilot",
  "ctor",
  "db",
- "env_logger 0.9.3",
+ "env_logger",
  "fs",
  "fsevent",
  "futures 0.3.28",
@@ -7081,7 +6707,7 @@ dependencies = [
  "copilot2",
  "ctor",
  "db2",
- "env_logger 0.9.3",
+ "env_logger",
  "fs2",
  "fsevent",
  "futures 0.3.28",
@@ -7384,19 +7010,7 @@ dependencies = [
 ]
 
 [[package]]
-name = "quick_action_bar"
-version = "0.1.0"
-dependencies = [
- "assistant",
- "editor",
- "gpui",
- "search",
- "theme",
- "workspace",
-]
-
-[[package]]
-name = "quick_action_bar2"
+name = "quick_action_bar2"
 version = "0.1.0"
 dependencies = [
  "assistant2",
@@ -7649,18 +7263,6 @@ dependencies = [
  "syn 1.0.109",
 ]
 
-[[package]]
-name = "regalloc2"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91b2eab54204ea0117fe9a060537e0b07a4e72f7c7d182361ecc346cab2240e5"
-dependencies = [
- "fxhash",
- "log",
- "slice-group-by",
- "smallvec",
-]
-
 [[package]]
 name = "regalloc2"
 version = "0.9.3"
@@ -7956,7 +7558,7 @@ dependencies = [
  "clock",
  "collections",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "gpui",
  "parking_lot 0.11.2",
@@ -7987,7 +7589,7 @@ dependencies = [
  "clock",
  "collections",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "gpui2",
  "parking_lot 0.11.2",
@@ -8135,22 +7737,6 @@ dependencies = [
  "semver",
 ]
 
-[[package]]
-name = "rustix"
-version = "0.35.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5363f616a5244fd47fc1dd0a0b24c28a5c0154f5010c16332a7ad6f78f2e8b62"
-dependencies = [
- "bitflags 1.3.2",
- "errno 0.2.8",
- "io-lifetimes 0.7.5",
- "itoa",
- "libc",
- "linux-raw-sys 0.0.46",
- "once_cell",
- "windows-sys 0.42.0",
-]
-
 [[package]]
 name = "rustix"
 version = "0.37.23"
@@ -8158,8 +7744,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
 dependencies = [
  "bitflags 1.3.2",
- "errno 0.3.3",
- "io-lifetimes 1.0.11",
+ "errno",
+ "io-lifetimes",
  "libc",
  "linux-raw-sys 0.3.8",
  "windows-sys 0.48.0",
@@ -8172,7 +7758,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
 dependencies = [
  "bitflags 2.4.1",
- "errno 0.3.3",
+ "errno",
  "libc",
  "linux-raw-sys 0.4.12",
  "windows-sys 0.48.0",
@@ -8548,7 +8134,7 @@ dependencies = [
  "collections",
  "ctor",
  "editor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "globset",
  "gpui",
@@ -8601,7 +8187,7 @@ dependencies = [
  "client2",
  "collections",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "futures 0.3.28",
  "globset",
  "gpui2",
@@ -9491,7 +9077,7 @@ version = "0.1.0"
 dependencies = [
  "arrayvec 0.7.4",
  "ctor",
- "env_logger 0.9.3",
+ "env_logger",
  "log",
  "rand 0.8.5",
 ]

Cargo.toml 🔗

@@ -129,7 +129,6 @@ members = [
     "crates/welcome2",
     "crates/xtask",
     "crates/zed",
-    "crates/zed2",
     "crates/zed-actions",
     "crates/zed_actions2"
 ]

crates/zed/Cargo.toml 🔗

@@ -1,5 +1,4 @@
 [package]
-authors = ["Nathan Sobo <nathansobo@gmail.com>"]
 description = "The fast, collaborative code editor."
 edition = "2021"
 name = "zed"
@@ -12,71 +11,69 @@ path = "src/zed.rs"
 doctest = false
 
 [[bin]]
-name = "Zed"
+name = "zed"
 path = "src/main.rs"
 
-[[example]]
-name = "semantic_index_eval"
-
 [dependencies]
-audio = { path = "../audio" }
-activity_indicator = { path = "../activity_indicator" }
-auto_update = { path = "../auto_update" }
-breadcrumbs = { path = "../breadcrumbs" }
-call = { path = "../call" }
-channel = { path = "../channel" }
+ai = { package = "ai2", path = "../ai2"}
+audio = { package = "audio2", path = "../audio2" }
+activity_indicator = { package = "activity_indicator2", path = "../activity_indicator2"}
+auto_update = { package = "auto_update2", path = "../auto_update2" }
+breadcrumbs = { package = "breadcrumbs2", path = "../breadcrumbs2" }
+call = { package = "call2", path = "../call2" }
+channel = { package = "channel2", path = "../channel2" }
 cli = { path = "../cli" }
-collab_ui = { path = "../collab_ui" }
+collab_ui = { package = "collab_ui2", path = "../collab_ui2" }
 collections = { path = "../collections" }
-command_palette = { path = "../command_palette" }
-component_test = { path = "../component_test" }
-context_menu = { path = "../context_menu" }
-client = { path = "../client" }
-clock = { path = "../clock" }
-copilot = { path = "../copilot" }
-copilot_button = { path = "../copilot_button" }
-diagnostics = { path = "../diagnostics" }
-db = { path = "../db" }
-editor = { path = "../editor" }
-feedback = { path = "../feedback" }
-file_finder = { path = "../file_finder" }
-search = { path = "../search" }
-fs = { path = "../fs" }
+command_palette = { package="command_palette2", path = "../command_palette2" }
+# component_test = { path = "../component_test" }
+client = { package = "client2", path = "../client2" }
+# clock = { path = "../clock" }
+copilot = { package = "copilot2", path = "../copilot2" }
+copilot_button = { package = "copilot_button2", path = "../copilot_button2" }
+diagnostics = { package = "diagnostics2", path = "../diagnostics2" }
+db = { package = "db2", path = "../db2" }
+editor = { package="editor2", path = "../editor2" }
+feedback = { package="feedback2", path = "../feedback2" }
+file_finder = { package="file_finder2", path = "../file_finder2" }
+search = { package = "search2", path = "../search2" }
+fs = { package = "fs2", path = "../fs2" }
 fsevent = { path = "../fsevent" }
-fuzzy = { path = "../fuzzy" }
-go_to_line = { path = "../go_to_line" }
-gpui = { path = "../gpui" }
-install_cli = { path = "../install_cli" }
-journal = { path = "../journal" }
-language = { path = "../language" }
-language_selector = { path = "../language_selector" }
-lsp = { path = "../lsp" }
-language_tools = { path = "../language_tools" }
+go_to_line = { package = "go_to_line2", path = "../go_to_line2" }
+gpui = { package = "gpui2", path = "../gpui2" }
+install_cli = { package = "install_cli2", path = "../install_cli2" }
+journal = { package = "journal2", path = "../journal2" }
+language = { package = "language2", path = "../language2" }
+language_selector = { package = "language_selector2", path = "../language_selector2" }
+lsp = { package = "lsp2", path = "../lsp2" }
+menu = { package = "menu2", path = "../menu2" }
+language_tools = { package = "language_tools2", path = "../language_tools2" }
 node_runtime = { path = "../node_runtime" }
-notifications = { path = "../notifications" }
-assistant = { path = "../assistant" }
-outline = { path = "../outline" }
-plugin_runtime = { path = "../plugin_runtime",optional = true }
-project = { path = "../project" }
-project_panel = { path = "../project_panel" }
-project_symbols = { path = "../project_symbols" }
-quick_action_bar = { path = "../quick_action_bar" }
-recent_projects = { path = "../recent_projects" }
-rpc = { path = "../rpc" }
-settings = { path = "../settings" }
-feature_flags = { path = "../feature_flags" }
+notifications = { package = "notifications2", path = "../notifications2" }
+assistant = { package = "assistant2", path = "../assistant2" }
+outline = { package = "outline2", path = "../outline2" }
+# plugin_runtime = { path = "../plugin_runtime",optional = true }
+project = { package = "project2", path = "../project2" }
+project_panel = { package = "project_panel2", path = "../project_panel2" }
+project_symbols = { package = "project_symbols2", path = "../project_symbols2" }
+quick_action_bar = { package = "quick_action_bar2", path = "../quick_action_bar2" }
+recent_projects = { package = "recent_projects2", path = "../recent_projects2" }
+rope = { package = "rope2", path = "../rope2"}
+rpc = { package = "rpc2", path = "../rpc2" }
+settings = { package = "settings2", path = "../settings2" }
+feature_flags = { package = "feature_flags2", path = "../feature_flags2" }
 sum_tree = { path = "../sum_tree" }
 shellexpand = "2.1.0"
-text = { path = "../text" }
-terminal_view = { path = "../terminal_view" }
-theme = { path = "../theme" }
-theme_selector = { path = "../theme_selector" }
+text = { package = "text2", path = "../text2" }
+terminal_view = { package = "terminal_view2", path = "../terminal_view2" }
+theme = { package = "theme2", path = "../theme2" }
+theme_selector = { package = "theme_selector2", path = "../theme_selector2" }
 util = { path = "../util" }
-semantic_index = { path = "../semantic_index" }
-vim = { path = "../vim" }
-workspace = { path = "../workspace" }
-welcome = { path = "../welcome" }
-zed-actions = {path = "../zed-actions"}
+semantic_index = { package = "semantic_index2", path = "../semantic_index2" }
+vim = { package = "vim2", path = "../vim2" }
+workspace = { package = "workspace2", path = "../workspace2" }
+welcome = { package = "welcome2", path = "../welcome2" }
+zed_actions = {package = "zed_actions2", path = "../zed_actions2"}
 anyhow.workspace = true
 async-compression.workspace = true
 async-tar = "0.4.2"
@@ -147,20 +144,19 @@ urlencoding = "2.1.2"
 uuid.workspace = true
 
 [dev-dependencies]
-ai = { path = "../ai" }
-call = { path = "../call", features = ["test-support"] }
-client = { path = "../client", features = ["test-support"] }
-editor = { path = "../editor", features = ["test-support"] }
-gpui = { path = "../gpui", features = ["test-support"] }
-language = { path = "../language", features = ["test-support"] }
-lsp = { path = "../lsp", features = ["test-support"] }
-project = { path = "../project", features = ["test-support"] }
-rpc = { path = "../rpc", features = ["test-support"] }
-settings = { path = "../settings", features = ["test-support"] }
-text = { path = "../text", features = ["test-support"] }
-util = { path = "../util", features = ["test-support"] }
-workspace = { path = "../workspace", features = ["test-support"] }
-
+call = { package = "call2", path = "../call2", features = ["test-support"] }
+# client = { path = "../client", features = ["test-support"] }
+# editor = { path = "../editor", features = ["test-support"] }
+# gpui = { path = "../gpui", features = ["test-support"] }
+gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
+language = { package = "language2", path = "../language2", features = ["test-support"] }
+# lsp = { path = "../lsp", features = ["test-support"] }
+project = { package = "project2", path = "../project2", features = ["test-support"] }
+# rpc = { path = "../rpc", features = ["test-support"] }
+# settings = { path = "../settings", features = ["test-support"] }
+text = { package = "text2", path = "../text2", features = ["test-support"] }
+# util = { path = "../util", features = ["test-support"] }
+# workspace = { path = "../workspace", features = ["test-support"] }
 unindent.workspace = true
 
 [package.metadata.bundle-dev]
@@ -171,6 +167,14 @@ osx_minimum_system_version = "10.15.7"
 osx_info_plist_exts = ["resources/info/*"]
 osx_url_schemes = ["zed-dev"]
 
+[package.metadata.bundle-nightly]
+icon = ["resources/app-icon-nightly@2x.png", "resources/app-icon-nightly.png"]
+identifier = "dev.zed.Zed-Nightly"
+name = "Zed Nightly"
+osx_minimum_system_version = "10.15.7"
+osx_info_plist_exts = ["resources/info/*"]
+osx_url_schemes = ["zed-nightly"]
+
 [package.metadata.bundle-preview]
 icon = ["resources/app-icon-preview@2x.png", "resources/app-icon-preview.png"]
 identifier = "dev.zed.Zed-Preview"

crates/zed/build.rs 🔗

@@ -3,10 +3,7 @@ use std::process::Command;
 fn main() {
     println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.15.7");
 
-    if let Ok(value) = std::env::var("ZED_PREVIEW_CHANNEL") {
-        println!("cargo:rustc-env=ZED_PREVIEW_CHANNEL={value}");
-    }
-
+    println!("cargo:rerun-if-env-changed=ZED_BUNDLE");
     if std::env::var("ZED_BUNDLE").ok().as_deref() == Some("true") {
         // Find WebRTC.framework in the Frameworks folder when running as part of an application bundle.
         println!("cargo:rustc-link-arg=-Wl,-rpath,@executable_path/../Frameworks");
@@ -24,31 +21,24 @@ fn main() {
     // Register exported Objective-C selectors, protocols, etc
     println!("cargo:rustc-link-arg=-Wl,-ObjC");
 
-    // Install dependencies for theme-generation
-    let output = Command::new("npm")
-        .current_dir("../../styles")
-        .args(["install", "--no-save"])
-        .output()
-        .expect("failed to run npm");
-    if !output.status.success() {
-        panic!(
-            "failed to install theme dependencies {}",
-            String::from_utf8_lossy(&output.stderr)
-        );
+    // Populate git sha environment variable if git is available
+    println!("cargo:rerun-if-changed=.git/logs/HEAD");
+    if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
+        if output.status.success() {
+            let git_sha = String::from_utf8_lossy(&output.stdout);
+            let git_sha = git_sha.trim();
+
+            println!("cargo:rustc-env=ZED_COMMIT_SHA={git_sha}");
+
+            if let Ok(build_profile) = std::env::var("PROFILE") {
+                if build_profile == "release" {
+                    // This is currently the best way to make `cargo build ...`'s build script
+                    // to print something to stdout without extra verbosity.
+                    println!(
+                        "cargo:warning=Info: using '{git_sha}' hash for ZED_COMMIT_SHA env var"
+                    );
+                }
+            }
+        }
     }
-
-    // Regenerate themes
-    let output = Command::new("npm")
-        .current_dir("../../styles")
-        .args(["run", "build"])
-        .output()
-        .expect("failed to run npm");
-    if !output.status.success() {
-        panic!(
-            "build script failed {}",
-            String::from_utf8_lossy(&output.stderr)
-        );
-    }
-
-    println!("cargo:rerun-if-changed=../../styles/src");
 }

crates/zed/examples/semantic_index_eval.rs 🔗

@@ -1,533 +0,0 @@
-use ai::providers::open_ai::OpenAIEmbeddingProvider;
-use anyhow::{anyhow, Result};
-use client::{self, UserStore};
-use gpui::{AsyncAppContext, ModelHandle, Task};
-use language::LanguageRegistry;
-use node_runtime::RealNodeRuntime;
-use project::{Project, RealFs};
-use semantic_index::semantic_index_settings::SemanticIndexSettings;
-use semantic_index::{SearchResult, SemanticIndex};
-use serde::{Deserialize, Serialize};
-use settings::{default_settings, SettingsStore};
-use std::path::{Path, PathBuf};
-use std::process::Command;
-use std::sync::Arc;
-use std::time::{Duration, Instant};
-use std::{cmp, env, fs};
-use util::channel::{RELEASE_CHANNEL, RELEASE_CHANNEL_NAME};
-use util::http::{self};
-use util::paths::EMBEDDINGS_DIR;
-use zed::languages;
-
-#[derive(Deserialize, Clone, Serialize)]
-struct EvaluationQuery {
-    query: String,
-    matches: Vec<String>,
-}
-
-impl EvaluationQuery {
-    fn match_pairs(&self) -> Vec<(PathBuf, u32)> {
-        let mut pairs = Vec::new();
-        for match_identifier in self.matches.iter() {
-            let mut match_parts = match_identifier.split(":");
-
-            if let Some(file_path) = match_parts.next() {
-                if let Some(row_number) = match_parts.next() {
-                    pairs.push((PathBuf::from(file_path), row_number.parse::<u32>().unwrap()));
-                }
-            }
-        }
-        pairs
-    }
-}
-
-#[derive(Deserialize, Clone)]
-struct RepoEval {
-    repo: String,
-    commit: String,
-    assertions: Vec<EvaluationQuery>,
-}
-
-const TMP_REPO_PATH: &str = "eval_repos";
-
-fn parse_eval() -> anyhow::Result<Vec<RepoEval>> {
-    let eval_folder = env::current_dir()?
-        .as_path()
-        .parent()
-        .unwrap()
-        .join("zed/crates/semantic_index/eval");
-
-    let mut repo_evals: Vec<RepoEval> = Vec::new();
-    for entry in fs::read_dir(eval_folder)? {
-        let file_path = entry.unwrap().path();
-        if let Some(extension) = file_path.extension() {
-            if extension == "json" {
-                if let Ok(file) = fs::read_to_string(file_path) {
-                    let repo_eval = serde_json::from_str(file.as_str());
-
-                    match repo_eval {
-                        Ok(repo_eval) => {
-                            repo_evals.push(repo_eval);
-                        }
-                        Err(err) => {
-                            println!("Err: {:?}", err);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    Ok(repo_evals)
-}
-
-fn clone_repo(repo_eval: RepoEval) -> anyhow::Result<(String, PathBuf)> {
-    let repo_name = Path::new(repo_eval.repo.as_str())
-        .file_name()
-        .unwrap()
-        .to_str()
-        .unwrap()
-        .to_owned()
-        .replace(".git", "");
-
-    let clone_path = fs::canonicalize(env::current_dir()?)?
-        .parent()
-        .ok_or(anyhow!("path canonicalization failed"))?
-        .parent()
-        .unwrap()
-        .join(TMP_REPO_PATH);
-
-    // Delete Clone Path if already exists
-    let _ = fs::remove_dir_all(&clone_path);
-    let _ = fs::create_dir(&clone_path);
-
-    let _ = Command::new("git")
-        .args(["clone", repo_eval.repo.as_str()])
-        .current_dir(clone_path.clone())
-        .output()?;
-    // Update clone path to be new directory housing the repo.
-    let clone_path = clone_path.join(repo_name.clone());
-    let _ = Command::new("git")
-        .args(["checkout", repo_eval.commit.as_str()])
-        .current_dir(clone_path.clone())
-        .output()?;
-
-    Ok((repo_name, clone_path))
-}
-
-fn dcg(hits: Vec<usize>) -> f32 {
-    let mut result = 0.0;
-    for (idx, hit) in hits.iter().enumerate() {
-        result += *hit as f32 / (2.0 + idx as f32).log2();
-    }
-
-    result
-}
-
-fn get_hits(
-    eval_query: EvaluationQuery,
-    search_results: Vec<SearchResult>,
-    k: usize,
-    cx: &AsyncAppContext,
-) -> (Vec<usize>, Vec<usize>) {
-    let ideal = vec![1; cmp::min(eval_query.matches.len(), k)];
-
-    let mut hits = Vec::new();
-    for result in search_results {
-        let (path, start_row, end_row) = result.buffer.read_with(cx, |buffer, _cx| {
-            let path = buffer.file().unwrap().path().to_path_buf();
-            let start_row = buffer.offset_to_point(result.range.start.offset).row;
-            let end_row = buffer.offset_to_point(result.range.end.offset).row;
-            (path, start_row, end_row)
-        });
-
-        let match_pairs = eval_query.match_pairs();
-        let mut found = 0;
-        for (match_path, match_row) in match_pairs {
-            if match_path == path {
-                if match_row >= start_row && match_row <= end_row {
-                    found = 1;
-                    break;
-                }
-            }
-        }
-
-        hits.push(found);
-    }
-
-    // For now, we are calculating ideal_hits a bit different, as technically
-    // with overlapping ranges, one match can result in more than result.
-    let mut ideal_hits = hits.clone();
-    ideal_hits.retain(|x| x == &1);
-
-    let ideal = if ideal.len() > ideal_hits.len() {
-        ideal
-    } else {
-        ideal_hits
-    };
-
-    // Fill ideal to 10 length
-    let mut filled_ideal = [0; 10];
-    for (idx, i) in ideal.to_vec().into_iter().enumerate() {
-        filled_ideal[idx] = i;
-    }
-
-    (filled_ideal.to_vec(), hits)
-}
-
-fn evaluate_ndcg(hits: Vec<usize>, ideal: Vec<usize>) -> Vec<f32> {
-    // NDCG or Normalized Discounted Cumulative Gain, is determined by comparing the relevance of
-    // items returned by the search engine relative to the hypothetical ideal.
-    // Relevance is represented as a series of booleans, in which each search result returned
-    // is identified as being inside the test set of matches (1) or not (0).
-
-    // For example, if result 1, 3 and 5 match the 3 relevant results provided
-    // actual dcg is calculated against a vector of [1, 0, 1, 0, 1]
-    // whereas ideal dcg is calculated against a vector of [1, 1, 1, 0, 0]
-    // as this ideal vector assumes the 3 relevant results provided were returned first
-    // normalized dcg is then calculated as actual dcg / ideal dcg.
-
-    // NDCG ranges from 0 to 1, which higher values indicating better performance
-    // Commonly NDCG is expressed as NDCG@k, in which k represents the metric calculated
-    // including only the top k values returned.
-    // The @k metrics can help you identify, at what point does the relevant results start to fall off.
-    // Ie. a NDCG@1 of 0.9 and a NDCG@3 of 0.5 may indicate that the first result returned in usually
-    // very high quality, whereas rank results quickly drop off after the first result.
-
-    let mut ndcg = Vec::new();
-    for idx in 1..(hits.len() + 1) {
-        let hits_at_k = hits[0..idx].to_vec();
-        let ideal_at_k = ideal[0..idx].to_vec();
-
-        let at_k = dcg(hits_at_k.clone()) / dcg(ideal_at_k.clone());
-
-        ndcg.push(at_k);
-    }
-
-    ndcg
-}
-
-fn evaluate_map(hits: Vec<usize>) -> Vec<f32> {
-    let mut map_at_k = Vec::new();
-
-    let non_zero = hits.iter().sum::<usize>() as f32;
-    if non_zero == 0.0 {
-        return vec![0.0; hits.len()];
-    }
-
-    let mut rolling_non_zero = 0.0;
-    let mut rolling_map = 0.0;
-    for (idx, h) in hits.into_iter().enumerate() {
-        rolling_non_zero += h as f32;
-        if h == 1 {
-            rolling_map += rolling_non_zero / (idx + 1) as f32;
-        }
-        map_at_k.push(rolling_map / non_zero);
-    }
-
-    map_at_k
-}
-
-fn evaluate_mrr(hits: Vec<usize>) -> f32 {
-    for (idx, h) in hits.into_iter().enumerate() {
-        if h == 1 {
-            return 1.0 / (idx + 1) as f32;
-        }
-    }
-
-    return 0.0;
-}
-
-fn init_logger() {
-    env_logger::init();
-}
-
-#[derive(Serialize)]
-struct QueryMetrics {
-    query: EvaluationQuery,
-    millis_to_search: Duration,
-    ndcg: Vec<f32>,
-    map: Vec<f32>,
-    mrr: f32,
-    hits: Vec<usize>,
-    precision: Vec<f32>,
-    recall: Vec<f32>,
-}
-
-#[derive(Serialize)]
-struct SummaryMetrics {
-    millis_to_search: f32,
-    ndcg: Vec<f32>,
-    map: Vec<f32>,
-    mrr: f32,
-    precision: Vec<f32>,
-    recall: Vec<f32>,
-}
-
-#[derive(Serialize)]
-struct RepoEvaluationMetrics {
-    millis_to_index: Duration,
-    query_metrics: Vec<QueryMetrics>,
-    repo_metrics: Option<SummaryMetrics>,
-}
-
-impl RepoEvaluationMetrics {
-    fn new(millis_to_index: Duration) -> Self {
-        RepoEvaluationMetrics {
-            millis_to_index,
-            query_metrics: Vec::new(),
-            repo_metrics: None,
-        }
-    }
-
-    fn save(&self, repo_name: String) -> Result<()> {
-        let results_string = serde_json::to_string(&self)?;
-        fs::write(format!("./{}_evaluation.json", repo_name), results_string)
-            .expect("Unable to write file");
-        Ok(())
-    }
-
-    fn summarize(&mut self) {
-        let l = self.query_metrics.len() as f32;
-        let millis_to_search: f32 = self
-            .query_metrics
-            .iter()
-            .map(|metrics| metrics.millis_to_search.as_millis())
-            .sum::<u128>() as f32
-            / l;
-
-        let mut ndcg_sum = vec![0.0; 10];
-        let mut map_sum = vec![0.0; 10];
-        let mut precision_sum = vec![0.0; 10];
-        let mut recall_sum = vec![0.0; 10];
-        let mut mmr_sum = 0.0;
-
-        for query_metric in self.query_metrics.iter() {
-            for (ndcg, query_ndcg) in ndcg_sum.iter_mut().zip(query_metric.ndcg.clone()) {
-                *ndcg += query_ndcg;
-            }
-
-            for (mapp, query_map) in map_sum.iter_mut().zip(query_metric.map.clone()) {
-                *mapp += query_map;
-            }
-
-            for (pre, query_pre) in precision_sum.iter_mut().zip(query_metric.precision.clone()) {
-                *pre += query_pre;
-            }
-
-            for (rec, query_rec) in recall_sum.iter_mut().zip(query_metric.recall.clone()) {
-                *rec += query_rec;
-            }
-
-            mmr_sum += query_metric.mrr;
-        }
-
-        let ndcg = ndcg_sum.iter().map(|val| val / l).collect::<Vec<f32>>();
-        let map = map_sum.iter().map(|val| val / l).collect::<Vec<f32>>();
-        let precision = precision_sum
-            .iter()
-            .map(|val| val / l)
-            .collect::<Vec<f32>>();
-        let recall = recall_sum.iter().map(|val| val / l).collect::<Vec<f32>>();
-        let mrr = mmr_sum / l;
-
-        self.repo_metrics = Some(SummaryMetrics {
-            millis_to_search,
-            ndcg,
-            map,
-            mrr,
-            precision,
-            recall,
-        })
-    }
-}
-
-fn evaluate_precision(hits: Vec<usize>) -> Vec<f32> {
-    let mut rolling_hit: f32 = 0.0;
-    let mut precision = Vec::new();
-    for (idx, hit) in hits.into_iter().enumerate() {
-        rolling_hit += hit as f32;
-        precision.push(rolling_hit / ((idx as f32) + 1.0));
-    }
-
-    precision
-}
-
-fn evaluate_recall(hits: Vec<usize>, ideal: Vec<usize>) -> Vec<f32> {
-    let total_relevant = ideal.iter().sum::<usize>() as f32;
-    let mut recall = Vec::new();
-    let mut rolling_hit: f32 = 0.0;
-    for hit in hits {
-        rolling_hit += hit as f32;
-        recall.push(rolling_hit / total_relevant);
-    }
-
-    recall
-}
-
-async fn evaluate_repo(
-    repo_name: String,
-    index: ModelHandle<SemanticIndex>,
-    project: ModelHandle<Project>,
-    query_matches: Vec<EvaluationQuery>,
-    cx: &mut AsyncAppContext,
-) -> Result<RepoEvaluationMetrics> {
-    // Index Project
-    let index_t0 = Instant::now();
-    index
-        .update(cx, |index, cx| index.index_project(project.clone(), cx))
-        .await?;
-    let mut repo_metrics = RepoEvaluationMetrics::new(index_t0.elapsed());
-
-    for query in query_matches {
-        // Query each match in order
-        let search_t0 = Instant::now();
-        let search_results = index
-            .update(cx, |index, cx| {
-                index.search_project(project.clone(), query.clone().query, 10, vec![], vec![], cx)
-            })
-            .await?;
-        let millis_to_search = search_t0.elapsed();
-
-        // Get Hits/Ideal
-        let k = 10;
-        let (ideal, hits) = self::get_hits(query.clone(), search_results, k, cx);
-
-        // Evaluate ndcg@k, for k = 1, 3, 5, 10
-        let ndcg = evaluate_ndcg(hits.clone(), ideal.clone());
-
-        // Evaluate map@k, for k = 1, 3, 5, 10
-        let map = evaluate_map(hits.clone());
-
-        // Evaluate mrr
-        let mrr = evaluate_mrr(hits.clone());
-
-        // Evaluate precision
-        let precision = evaluate_precision(hits.clone());
-
-        // Evaluate Recall
-        let recall = evaluate_recall(hits.clone(), ideal);
-
-        let query_metrics = QueryMetrics {
-            query,
-            millis_to_search,
-            ndcg,
-            map,
-            mrr,
-            hits,
-            precision,
-            recall,
-        };
-
-        repo_metrics.query_metrics.push(query_metrics);
-    }
-
-    repo_metrics.summarize();
-    let _ = repo_metrics.save(repo_name);
-
-    anyhow::Ok(repo_metrics)
-}
-
-fn main() {
-    // Launch new repo as a new Zed workspace/project
-    let app = gpui::App::new(()).unwrap();
-    let fs = Arc::new(RealFs);
-    let http = http::client();
-    let http_client = http::client();
-    init_logger();
-
-    app.run(move |cx| {
-        cx.set_global(*RELEASE_CHANNEL);
-
-        let client = client::Client::new(http.clone(), cx);
-        let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http_client.clone(), cx));
-
-        // Initialize Settings
-        let mut store = SettingsStore::default();
-        store
-            .set_default_settings(default_settings().as_ref(), cx)
-            .unwrap();
-        cx.set_global(store);
-
-        // Initialize Languages
-        let login_shell_env_loaded = Task::ready(());
-        let mut languages = LanguageRegistry::new(login_shell_env_loaded);
-        languages.set_executor(cx.background().clone());
-        let languages = Arc::new(languages);
-
-        let node_runtime = RealNodeRuntime::new(http.clone());
-        languages::init(languages.clone(), node_runtime.clone(), cx);
-        language::init(cx);
-
-        project::Project::init(&client, cx);
-        semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx);
-
-        settings::register::<SemanticIndexSettings>(cx);
-
-        let db_file_path = EMBEDDINGS_DIR
-            .join(Path::new(RELEASE_CHANNEL_NAME.as_str()))
-            .join("embeddings_db");
-
-        let languages = languages.clone();
-
-        let fs = fs.clone();
-        cx.spawn(|mut cx| async move {
-            let semantic_index = SemanticIndex::new(
-                fs.clone(),
-                db_file_path,
-                Arc::new(OpenAIEmbeddingProvider::new(http_client, cx.background())),
-                languages.clone(),
-                cx.clone(),
-            )
-            .await?;
-
-            if let Ok(repo_evals) = parse_eval() {
-                for repo in repo_evals {
-                    let cloned = clone_repo(repo.clone());
-                    match cloned {
-                        Ok((repo_name, clone_path)) => {
-                            println!(
-                                "Cloned {:?} @ {:?} into {:?}",
-                                repo.repo, repo.commit, &clone_path
-                            );
-
-                            // Create Project
-                            let project = cx.update(|cx| {
-                                Project::local(
-                                    client.clone(),
-                                    node_runtime::FakeNodeRuntime::new(),
-                                    user_store.clone(),
-                                    languages.clone(),
-                                    fs.clone(),
-                                    cx,
-                                )
-                            });
-
-                            // Register Worktree
-                            let _ = project
-                                .update(&mut cx, |project, cx| {
-                                    project.find_or_create_local_worktree(clone_path, true, cx)
-                                })
-                                .await;
-
-                            let _ = evaluate_repo(
-                                repo_name,
-                                semantic_index.clone(),
-                                project,
-                                repo.assertions,
-                                &mut cx,
-                            )
-                            .await?;
-                        }
-                        Err(err) => {
-                            println!("Error cloning: {:?}", err);
-                        }
-                    }
-                }
-            }
-
-            anyhow::Ok(())
-        })
-        .detach();
-    });
-}

crates/zed/src/assets.rs 🔗

@@ -1,5 +1,6 @@
-use anyhow::{anyhow, Result};
-use gpui::AssetSource;
+use anyhow::anyhow;
+
+use gpui::{AssetSource, Result, SharedString};
 use rust_embed::RustEmbed;
 
 #[derive(RustEmbed)]
@@ -7,6 +8,7 @@ use rust_embed::RustEmbed;
 #[include = "fonts/**/*"]
 #[include = "icons/**/*"]
 #[include = "themes/**/*"]
+#[exclude = "themes/src/*"]
 #[include = "sounds/**/*"]
 #[include = "*.md"]
 #[exclude = "*.DS_Store"]
@@ -19,7 +21,15 @@ impl AssetSource for Assets {
             .ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
     }
 
-    fn list(&self, path: &str) -> Vec<std::borrow::Cow<'static, str>> {
-        Self::iter().filter(|p| p.starts_with(path)).collect()
+    fn list(&self, path: &str) -> Result<Vec<SharedString>> {
+        Ok(Self::iter()
+            .filter_map(|p| {
+                if p.starts_with(path) {
+                    Some(p.into())
+                } else {
+                    None
+                }
+            })
+            .collect())
     }
 }

crates/zed/src/languages.rs 🔗

@@ -3,8 +3,9 @@ use gpui::AppContext;
 pub use language::*;
 use node_runtime::NodeRuntime;
 use rust_embed::RustEmbed;
+use settings::Settings;
 use std::{borrow::Cow, str, sync::Arc};
-use util::asset_str;
+use util::{asset_str, paths::PLUGINS_DIR};
 
 use self::elixir::ElixirSettings;
 
@@ -48,7 +49,7 @@ pub fn init(
     node_runtime: Arc<dyn NodeRuntime>,
     cx: &mut AppContext,
 ) {
-    settings::register::<elixir::ElixirSettings>(cx);
+    ElixirSettings::register(cx);
 
     let language = |name, grammar, adapters| {
         languages.register(name, load_config(name), grammar, adapters, load_queries)
@@ -74,7 +75,7 @@ pub fn init(
         ],
     );
 
-    match &settings::get::<ElixirSettings>(cx).lsp {
+    match &ElixirSettings::get(None, cx).lsp {
         elixir::ElixirLspSetting::ElixirLs => language(
             "elixir",
             tree_sitter_elixir::language(),
@@ -227,6 +228,21 @@ pub fn init(
         tree_sitter_uiua::language(),
         vec![Arc::new(uiua::UiuaLanguageServer {})],
     );
+
+    if let Ok(children) = std::fs::read_dir(&*PLUGINS_DIR) {
+        for child in children {
+            if let Ok(child) = child {
+                let path = child.path();
+                let config_path = path.join("config.toml");
+                if let Ok(config) = std::fs::read(&config_path) {
+                    let config: LanguageConfig = toml::from_slice(&config).unwrap();
+                    if let Some(grammar_name) = config.grammar_name.clone() {
+                        languages.register_wasm(path.into(), grammar_name, config);
+                    }
+                }
+            }
+        }
+    }
 }
 
 #[cfg(any(test, feature = "test-support"))]

crates/zed/src/languages/c.rs 🔗

@@ -273,18 +273,19 @@ async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServ
 
 #[cfg(test)]
 mod tests {
-    use gpui::TestAppContext;
+    use gpui::{Context, TestAppContext};
     use language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer};
     use settings::SettingsStore;
     use std::num::NonZeroU32;
 
     #[gpui::test]
     async fn test_c_autoindent(cx: &mut TestAppContext) {
-        cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX);
+        // cx.executor().set_block_on_ticks(usize::MAX..=usize::MAX);
         cx.update(|cx| {
-            cx.set_global(SettingsStore::test(cx));
+            let test_settings = SettingsStore::test(cx);
+            cx.set_global(test_settings);
             language::init(cx);
-            cx.update_global::<SettingsStore, _, _>(|store, cx| {
+            cx.update_global::<SettingsStore, _>(|store, cx| {
                 store.update_user_settings::<AllLanguageSettings>(cx, |s| {
                     s.defaults.tab_size = NonZeroU32::new(2);
                 });
@@ -292,8 +293,9 @@ mod tests {
         });
         let language = crate::languages::language("c", tree_sitter_c::language(), None).await;
 
-        cx.add_model(|cx| {
-            let mut buffer = Buffer::new(0, cx.model_id() as u64, "").with_language(language, cx);
+        cx.new_model(|cx| {
+            let mut buffer =
+                Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
 
             // empty function
             buffer.edit([(0..0, "int main() {}")], None, cx);

crates/zed/src/languages/elixir.rs 🔗

@@ -6,7 +6,7 @@ pub use language::*;
 use lsp::{CompletionItemKind, LanguageServerBinary, SymbolKind};
 use schemars::JsonSchema;
 use serde_derive::{Deserialize, Serialize};
-use settings::Setting;
+use settings::Settings;
 use smol::fs::{self, File};
 use std::{
     any::Any,
@@ -46,7 +46,7 @@ pub struct ElixirSettingsContent {
     lsp: Option<ElixirLspSetting>,
 }
 
-impl Setting for ElixirSettings {
+impl Settings for ElixirSettings {
     const KEY: Option<&'static str> = Some("elixir");
 
     type FileContent = ElixirSettingsContent;
@@ -54,7 +54,7 @@ impl Setting for ElixirSettings {
     fn load(
         default_value: &Self::FileContent,
         user_values: &[&Self::FileContent],
-        _: &gpui::AppContext,
+        _: &mut gpui::AppContext,
     ) -> Result<Self>
     where
         Self: Sized,
@@ -85,7 +85,7 @@ impl LspAdapter for ElixirLspAdapter {
         const NOTIFICATION_MESSAGE: &str = "Could not run the elixir language server, `elixir-ls`, because `elixir` was not found.";
 
         let delegate = delegate.clone();
-        Some(cx.spawn(|mut cx| async move {
+        Some(cx.spawn(|cx| async move {
             let elixir_output = smol::process::Command::new("elixir")
                 .args(["--version"])
                 .output()
@@ -97,7 +97,7 @@ impl LspAdapter for ElixirLspAdapter {
                 {
                     cx.update(|cx| {
                         delegate.show_notification(NOTIFICATION_MESSAGE, cx);
-                    })
+                    })?
                 }
                 return Err(anyhow!("cannot run elixir-ls"));
             }

crates/zed/src/languages/elixir/embedding.scm 🔗

@@ -18,10 +18,10 @@
                     target: (identifier) @name)
                     operator: "when")
             ])
-        (#any-match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item
+        (#match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item
         )
 
     (call
         target: (identifier) @name
         (arguments (alias) @name)
-        (#any-match? @name "^(defmodule|defprotocol)$")) @item
+        (#match? @name "^(defmodule|defprotocol)$")) @item

crates/zed/src/languages/go.rs 🔗

@@ -67,7 +67,7 @@ impl super::LspAdapter for GoLspAdapter {
             "Could not install the Go language server `gopls`, because `go` was not found.";
 
         let delegate = delegate.clone();
-        Some(cx.spawn(|mut cx| async move {
+        Some(cx.spawn(|cx| async move {
             let install_output = process::Command::new("go").args(["version"]).output().await;
             if install_output.is_err() {
                 if DID_SHOW_NOTIFICATION
@@ -76,7 +76,7 @@ impl super::LspAdapter for GoLspAdapter {
                 {
                     cx.update(|cx| {
                         delegate.show_notification(NOTIFICATION_MESSAGE, cx);
-                    })
+                    })?
                 }
                 return Err(anyhow!("cannot install gopls"));
             }
@@ -372,7 +372,7 @@ fn adjust_runs(
 mod tests {
     use super::*;
     use crate::languages::language;
-    use gpui::color::Color;
+    use gpui::Hsla;
     use theme::SyntaxTheme;
 
     #[gpui::test]
@@ -384,12 +384,12 @@ mod tests {
         )
         .await;
 
-        let theme = SyntaxTheme::new(vec![
-            ("type".into(), Color::green().into()),
-            ("keyword".into(), Color::blue().into()),
-            ("function".into(), Color::red().into()),
-            ("number".into(), Color::yellow().into()),
-            ("property".into(), Color::white().into()),
+        let theme = SyntaxTheme::new_test([
+            ("type", Hsla::default()),
+            ("keyword", Hsla::default()),
+            ("function", Hsla::default()),
+            ("number", Hsla::default()),
+            ("property", Hsla::default()),
         ]);
         language.set_theme(&theme);
 

crates/zed/src/languages/json.rs 🔗

@@ -108,7 +108,7 @@ impl LspAdapter for JsonLspAdapter {
         _workspace_root: &Path,
         cx: &mut AppContext,
     ) -> BoxFuture<'static, serde_json::Value> {
-        let action_names = cx.all_action_names().collect::<Vec<_>>();
+        let action_names = cx.all_action_names();
         let staff_mode = cx.is_staff();
         let language_names = &self.languages.language_names();
         let settings_schema = cx.global::<SettingsStore>().json_schema(

crates/zed/src/languages/language_plugin.rs 🔗

@@ -3,8 +3,8 @@ use async_trait::async_trait;
 use collections::HashMap;
 use futures::lock::Mutex;
 use gpui::executor::Background;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
+use language2::{LanguageServerName, LspAdapter, LspAdapterDelegate};
+use lsp2::LanguageServerBinary;
 use plugin_runtime::{Plugin, PluginBinary, PluginBuilder, WasiFn};
 use std::{any::Any, path::PathBuf, sync::Arc};
 use util::ResultExt;

crates/zed/src/languages/nu.rs 🔗

@@ -1,8 +1,8 @@
 use anyhow::{anyhow, Result};
 use async_trait::async_trait;
-use language::{CodeLabel, Language, LanguageServerName, LspAdapter, LspAdapterDelegate};
+use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
 use lsp::LanguageServerBinary;
-use std::{any::Any, path::PathBuf, sync::Arc};
+use std::{any::Any, path::PathBuf};
 
 pub struct NuLanguageServer;
 
@@ -52,30 +52,4 @@ impl LspAdapter for NuLanguageServer {
     async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
         None
     }
-
-    async fn label_for_completion(
-        &self,
-        completion: &lsp::CompletionItem,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        return Some(CodeLabel {
-            runs: language
-                .highlight_text(&completion.label.clone().into(), 0..completion.label.len()),
-            text: completion.label.clone(),
-            filter_range: 0..completion.label.len(),
-        });
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        _: lsp::SymbolKind,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        Some(CodeLabel {
-            runs: language.highlight_text(&name.into(), 0..name.len()),
-            text: name.to_string(),
-            filter_range: 0..name.len(),
-        })
-    }
 }

crates/zed/src/languages/python.rs 🔗

@@ -177,28 +177,30 @@ async fn get_cached_server_binary(
 
 #[cfg(test)]
 mod tests {
-    use gpui::{ModelContext, TestAppContext};
+    use gpui::{Context, ModelContext, TestAppContext};
     use language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer};
     use settings::SettingsStore;
     use std::num::NonZeroU32;
 
     #[gpui::test]
     async fn test_python_autoindent(cx: &mut TestAppContext) {
-        cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX);
+        // cx.executor().set_block_on_ticks(usize::MAX..=usize::MAX);
         let language =
             crate::languages::language("python", tree_sitter_python::language(), None).await;
         cx.update(|cx| {
-            cx.set_global(SettingsStore::test(cx));
+            let test_settings = SettingsStore::test(cx);
+            cx.set_global(test_settings);
             language::init(cx);
-            cx.update_global::<SettingsStore, _, _>(|store, cx| {
+            cx.update_global::<SettingsStore, _>(|store, cx| {
                 store.update_user_settings::<AllLanguageSettings>(cx, |s| {
                     s.defaults.tab_size = NonZeroU32::new(2);
                 });
             });
         });
 
-        cx.add_model(|cx| {
-            let mut buffer = Buffer::new(0, cx.model_id() as u64, "").with_language(language, cx);
+        cx.new_model(|cx| {
+            let mut buffer =
+                Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
             let append = |buffer: &mut Buffer, text: &str, cx: &mut ModelContext<Buffer>| {
                 let ix = buffer.len();
                 buffer.edit([(ix..ix, text)], Some(AutoindentMode::EachLine), cx);

crates/zed/src/languages/rust.rs 🔗

@@ -294,7 +294,7 @@ mod tests {
 
     use super::*;
     use crate::languages::language;
-    use gpui::{color::Color, TestAppContext};
+    use gpui::{Context, Hsla, TestAppContext};
     use language::language_settings::AllLanguageSettings;
     use settings::SettingsStore;
     use theme::SyntaxTheme;
@@ -349,11 +349,11 @@ mod tests {
         )
         .await;
         let grammar = language.grammar().unwrap();
-        let theme = SyntaxTheme::new(vec![
-            ("type".into(), Color::green().into()),
-            ("keyword".into(), Color::blue().into()),
-            ("function".into(), Color::red().into()),
-            ("property".into(), Color::white().into()),
+        let theme = SyntaxTheme::new_test([
+            ("type", Hsla::default()),
+            ("keyword", Hsla::default()),
+            ("function", Hsla::default()),
+            ("property", Hsla::default()),
         ]);
 
         language.set_theme(&theme);
@@ -456,11 +456,11 @@ mod tests {
         )
         .await;
         let grammar = language.grammar().unwrap();
-        let theme = SyntaxTheme::new(vec![
-            ("type".into(), Color::green().into()),
-            ("keyword".into(), Color::blue().into()),
-            ("function".into(), Color::red().into()),
-            ("property".into(), Color::white().into()),
+        let theme = SyntaxTheme::new_test([
+            ("type", Hsla::default()),
+            ("keyword", Hsla::default()),
+            ("function", Hsla::default()),
+            ("property", Hsla::default()),
         ]);
 
         language.set_theme(&theme);
@@ -494,11 +494,12 @@ mod tests {
 
     #[gpui::test]
     async fn test_rust_autoindent(cx: &mut TestAppContext) {
-        cx.foreground().set_block_on_ticks(usize::MAX..=usize::MAX);
+        // cx.executor().set_block_on_ticks(usize::MAX..=usize::MAX);
         cx.update(|cx| {
-            cx.set_global(SettingsStore::test(cx));
+            let test_settings = SettingsStore::test(cx);
+            cx.set_global(test_settings);
             language::init(cx);
-            cx.update_global::<SettingsStore, _, _>(|store, cx| {
+            cx.update_global::<SettingsStore, _>(|store, cx| {
                 store.update_user_settings::<AllLanguageSettings>(cx, |s| {
                     s.defaults.tab_size = NonZeroU32::new(2);
                 });
@@ -507,8 +508,9 @@ mod tests {
 
         let language = crate::languages::language("rust", tree_sitter_rust::language(), None).await;
 
-        cx.add_model(|cx| {
-            let mut buffer = Buffer::new(0, cx.model_id() as u64, "").with_language(language, cx);
+        cx.new_model(|cx| {
+            let mut buffer =
+                Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
 
             // indent between braces
             buffer.set_text("fn a() {}", cx);

crates/zed/src/languages/typescript.rs 🔗

@@ -351,7 +351,7 @@ async fn get_cached_eslint_server_binary(
 
 #[cfg(test)]
 mod tests {
-    use gpui::TestAppContext;
+    use gpui::{Context, TestAppContext};
     use unindent::Unindent;
 
     #[gpui::test]
@@ -378,10 +378,10 @@ mod tests {
         "#
         .unindent();
 
-        let buffer = cx.add_model(|cx| {
-            language::Buffer::new(0, cx.model_id() as u64, text).with_language(language, cx)
+        let buffer = cx.new_model(|cx| {
+            language::Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
         });
-        let outline = buffer.read_with(cx, |buffer, _| buffer.snapshot().outline(None).unwrap());
+        let outline = buffer.update(cx, |buffer, _| buffer.snapshot().outline(None).unwrap());
         assert_eq!(
             outline
                 .items

crates/zed/src/languages/uiua/config.toml 🔗

@@ -3,7 +3,7 @@ path_suffixes = ["ua"]
 line_comment = "# "
 autoclose_before = ")]}\""
 brackets = [
-    { start = "{", end = "}", close = true, newline = false },
+    { start = "{", end = "}", close = true, newline = false},
     { start = "[", end = "]", close = true, newline = false },
     { start = "(", end = ")", close = true, newline = false },
     { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },

crates/zed/src/main.rs 🔗

@@ -1,59 +1,62 @@
 // Allow binary to be called Zed for a nice application menu when running executable directly
 #![allow(non_snake_case)]
 
-use anyhow::{anyhow, Context, Result};
+use anyhow::{anyhow, Context as _, Result};
 use backtrace::Backtrace;
 use chrono::Utc;
 use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
-use client::{
-    self, Client, TelemetrySettings, UserStore, ZED_APP_VERSION, ZED_SECRET_CLIENT_TOKEN,
-};
+use client::{Client, UserStore};
 use collab_ui::channel_view::ChannelView;
 use db::kvp::KEY_VALUE_STORE;
 use editor::Editor;
+use fs::RealFs;
 use futures::StreamExt;
-use gpui::{Action, App, AppContext, AssetSource, AsyncAppContext, Task};
-use isahc::{config::Configurable, Request};
+use gpui::{App, AppContext, AsyncAppContext, Context, SemanticVersion, Task};
+use isahc::{prelude::Configurable, Request};
 use language::LanguageRegistry;
 use log::LevelFilter;
+
 use node_runtime::RealNodeRuntime;
 use parking_lot::Mutex;
-use project::Fs;
 use serde::{Deserialize, Serialize};
-use settings::{default_settings, handle_settings_file_changes, watch_config_file, SettingsStore};
+use settings::{
+    default_settings, handle_settings_file_changes, watch_config_file, Settings, SettingsStore,
+};
 use simplelog::ConfigBuilder;
 use smol::process::Command;
 use std::{
     env,
     ffi::OsStr,
     fs::OpenOptions,
-    io::{IsTerminal, Write as _},
+    io::{IsTerminal, Write},
     panic,
-    path::Path,
+    path::{Path, PathBuf},
     sync::{
         atomic::{AtomicU32, Ordering},
         Arc, Weak,
     },
     thread,
 };
+use theme::ActiveTheme;
 use util::{
-    channel::{parse_zed_link, ReleaseChannel},
+    async_maybe,
+    channel::{parse_zed_link, AppCommitSha, ReleaseChannel, RELEASE_CHANNEL},
     http::{self, HttpClient},
+    paths, ResultExt,
 };
 use uuid::Uuid;
-use welcome::{show_welcome_experience, FIRST_OPEN};
-
-use fs::RealFs;
-use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt};
+use welcome::{show_welcome_view, FIRST_OPEN};
 use workspace::{AppState, WorkspaceStore};
 use zed::{
-    assets::Assets,
-    build_window_options, handle_keymap_file_changes, initialize_workspace, languages, menus,
-    only_instance::{ensure_only_instance, IsOnlyInstance},
-    open_listener::{handle_cli_connection, OpenListener, OpenRequest},
+    app_menus, build_window_options, ensure_only_instance, handle_cli_connection,
+    handle_keymap_file_changes, initialize_workspace, languages, Assets, IsOnlyInstance,
+    OpenListener, OpenRequest,
 };
 
 fn main() {
+    menu::init();
+    zed_actions::init();
+
     let http = http::client();
     init_paths();
     init_logger();
@@ -63,48 +66,61 @@ fn main() {
     }
 
     log::info!("========== starting zed ==========");
-    let mut app = gpui::App::new(Assets).unwrap();
+    let app = App::production(Arc::new(Assets));
 
-    let (installation_id, existing_installation_id_found) =
-        app.background().block(installation_id()).ok().unzip();
+    let (installation_id, existing_installation_id_found) = app
+        .background_executor()
+        .block(installation_id())
+        .ok()
+        .unzip();
     let session_id = Uuid::new_v4().to_string();
     init_panic_hook(&app, installation_id.clone(), session_id.clone());
 
-    load_embedded_fonts(&app);
-
     let fs = Arc::new(RealFs);
-    let user_settings_file_rx =
-        watch_config_file(app.background(), fs.clone(), paths::SETTINGS.clone());
-    let user_keymap_file_rx =
-        watch_config_file(app.background(), fs.clone(), paths::KEYMAP.clone());
+    let user_settings_file_rx = watch_config_file(
+        &app.background_executor(),
+        fs.clone(),
+        paths::SETTINGS.clone(),
+    );
+    let user_keymap_file_rx = watch_config_file(
+        &app.background_executor(),
+        fs.clone(),
+        paths::KEYMAP.clone(),
+    );
 
     let login_shell_env_loaded = if stdout_is_a_pty() {
         Task::ready(())
     } else {
-        app.background().spawn(async {
+        app.background_executor().spawn(async {
             load_login_shell_environment().await.log_err();
         })
     };
 
     let (listener, mut open_rx) = OpenListener::new();
     let listener = Arc::new(listener);
-    let callback_listener = listener.clone();
-    app.on_open_urls(move |urls, _| callback_listener.open_urls(urls))
-        .on_reopen(move |cx| {
-            if cx.has_global::<Weak<AppState>>() {
-                if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
-                    workspace::open_new(&app_state, cx, |workspace, cx| {
-                        Editor::new_file(workspace, &Default::default(), cx)
-                    })
-                    .detach();
-                }
+    let open_listener = listener.clone();
+    app.on_open_urls(move |urls, _| open_listener.open_urls(&urls));
+    app.on_reopen(move |cx| {
+        if cx.has_global::<Weak<AppState>>() {
+            if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
+                workspace::open_new(&app_state, cx, |workspace, cx| {
+                    Editor::new_file(workspace, &Default::default(), cx)
+                })
+                .detach();
             }
-        });
+        }
+    });
 
     app.run(move |cx| {
         cx.set_global(*RELEASE_CHANNEL);
+        if let Some(build_sha) = option_env!("ZED_COMMIT_SHA") {
+            cx.set_global(AppCommitSha(build_sha.into()))
+        }
+
         cx.set_global(listener.clone());
 
+        load_embedded_fonts(cx);
+
         let mut store = SettingsStore::default();
         store
             .set_default_settings(default_settings().as_ref(), cx)
@@ -116,35 +132,25 @@ fn main() {
         let client = client::Client::new(http.clone(), cx);
         let mut languages = LanguageRegistry::new(login_shell_env_loaded);
         let copilot_language_server_id = languages.next_language_server_id();
-        languages.set_executor(cx.background().clone());
+        languages.set_executor(cx.background_executor().clone());
         languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone());
         let languages = Arc::new(languages);
         let node_runtime = RealNodeRuntime::new(http.clone());
 
+        language::init(cx);
         languages::init(languages.clone(), node_runtime.clone(), cx);
-        let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
-        let workspace_store = cx.add_model(|cx| WorkspaceStore::new(client.clone(), cx));
+        let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
+        let workspace_store = cx.new_model(|cx| WorkspaceStore::new(client.clone(), cx));
 
         cx.set_global(client.clone());
 
-        theme::init(Assets, cx);
-        context_menu::init(cx);
+        theme::init(theme::LoadThemes::All, cx);
         project::Project::init(&client, cx);
         client::init(&client, cx);
         command_palette::init(cx);
         language::init(cx);
         editor::init(cx);
-        go_to_line::init(cx);
-        file_finder::init(cx);
-        outline::init(cx);
-        project_symbols::init(cx);
-        project_panel::init(Assets, cx);
-        channel::init(&client, user_store.clone(), cx);
         diagnostics::init(cx);
-        search::init(cx);
-        semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx);
-        vim::init(cx);
-        terminal_view::init(cx);
         copilot::init(
             copilot_language_server_id,
             http.clone(),
@@ -152,26 +158,25 @@ fn main() {
             cx,
         );
         assistant::init(cx);
-        component_test::init(cx);
+        // component_test::init(cx);
 
-        cx.spawn(|cx| watch_themes(fs.clone(), cx)).detach();
         cx.spawn(|_| watch_languages(fs.clone(), languages.clone()))
             .detach();
         watch_file_types(fs.clone(), cx);
 
-        languages.set_theme(theme::current(cx).clone());
-        cx.observe_global::<SettingsStore, _>({
+        languages.set_theme(cx.theme().clone());
+        cx.observe_global::<SettingsStore>({
             let languages = languages.clone();
-            move |cx| languages.set_theme(theme::current(cx).clone())
+            move |cx| languages.set_theme(cx.theme().clone())
         })
         .detach();
 
         client.telemetry().start(installation_id, session_id, cx);
-        let telemetry_settings = *settings::get::<TelemetrySettings>(cx);
+        let telemetry_settings = *client::TelemetrySettings::get_global(cx);
         client.telemetry().report_setting_event(
             telemetry_settings,
             "theme",
-            theme::current(cx).meta.name.to_string(),
+            cx.theme().name.to_string(),
         );
         let event_operation = match existing_installation_id_found {
             Some(false) => "first open",
@@ -182,13 +187,11 @@ fn main() {
             .report_app_event(telemetry_settings, event_operation, true);
 
         let app_state = Arc::new(AppState {
-            languages,
+            languages: languages.clone(),
             client: client.clone(),
-            user_store,
-            fs,
+            user_store: user_store.clone(),
+            fs: fs.clone(),
             build_window_options,
-            initialize_workspace,
-            background_actions,
             workspace_store,
             node_runtime,
         });
@@ -200,25 +203,35 @@ fn main() {
         workspace::init(app_state.clone(), cx);
         recent_projects::init(cx);
 
+        go_to_line::init(cx);
+        file_finder::init(cx);
+        outline::init(cx);
+        project_symbols::init(cx);
+        project_panel::init(Assets, cx);
+        channel::init(&client, user_store.clone(), cx);
+        search::init(cx);
+        semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx);
+        vim::init(cx);
+        terminal_view::init(cx);
+
         journal::init(app_state.clone(), cx);
         language_selector::init(cx);
         theme_selector::init(cx);
-        activity_indicator::init(cx);
         language_tools::init(cx);
         call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
         notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx);
         collab_ui::init(&app_state, cx);
         feedback::init(cx);
         welcome::init(cx);
-        zed::init(&app_state, cx);
 
-        cx.set_menus(menus::menus());
+        cx.set_menus(app_menus());
+        initialize_workspace(app_state.clone(), cx);
 
         if stdout_is_a_pty() {
-            cx.platform().activate(true);
+            cx.activate(true);
             let urls = collect_url_args();
             if !urls.is_empty() {
-                listener.open_urls(urls)
+                listener.open_urls(&urls)
             }
         } else {
             upload_previous_panics(http.clone(), cx);
@@ -228,32 +241,51 @@ fn main() {
             if std::env::var(FORCE_CLI_MODE_ENV_VAR_NAME).ok().is_some()
                 && !listener.triggered.load(Ordering::Acquire)
             {
-                listener.open_urls(collect_url_args())
+                listener.open_urls(&collect_url_args())
             }
         }
 
         let mut triggered_authentication = false;
 
+        fn open_paths_and_log_errs(
+            paths: &[PathBuf],
+            app_state: &Arc<AppState>,
+            cx: &mut AppContext,
+        ) {
+            let task = workspace::open_paths(&paths, &app_state, None, cx);
+            cx.spawn(|_| async move {
+                if let Some((_window, results)) = task.await.log_err() {
+                    for result in results {
+                        if let Some(Err(e)) = result {
+                            log::error!("Error opening path: {}", e);
+                        }
+                    }
+                }
+            })
+            .detach();
+        }
+
         match open_rx.try_next() {
             Ok(Some(OpenRequest::Paths { paths })) => {
-                cx.update(|cx| workspace::open_paths(&paths, &app_state, None, cx))
-                    .detach();
+                open_paths_and_log_errs(&paths, &app_state, cx)
             }
             Ok(Some(OpenRequest::CliConnection { connection })) => {
-                cx.spawn(|cx| handle_cli_connection(connection, app_state.clone(), cx))
+                let app_state = app_state.clone();
+                cx.spawn(move |cx| handle_cli_connection(connection, app_state, cx))
                     .detach();
             }
             Ok(Some(OpenRequest::JoinChannel { channel_id })) => {
                 triggered_authentication = true;
                 let app_state = app_state.clone();
                 let client = client.clone();
-                cx.spawn(|mut cx| async move {
+                cx.spawn(|cx| async move {
                     // ignore errors here, we'll show a generic "not signed in"
                     let _ = authenticate(client, &cx).await;
-                    cx.update(|cx| workspace::join_channel(channel_id, app_state, None, cx))
-                        .await
+                    cx.update(|cx| workspace::join_channel(channel_id, app_state, None, cx))?
+                        .await?;
+                    anyhow::Ok(())
                 })
-                .detach_and_log_err(cx)
+                .detach_and_log_err(cx);
             }
             Ok(Some(OpenRequest::OpenChannelNotes { channel_id })) => {
                 triggered_authentication = true;
@@ -262,12 +294,16 @@ fn main() {
                 cx.spawn(|mut cx| async move {
                     // ignore errors here, we'll show a generic "not signed in"
                     let _ = authenticate(client, &cx).await;
-                    let workspace =
+                    let workspace_window =
                         workspace::get_any_active_workspace(app_state, cx.clone()).await?;
-                    cx.update(|cx| ChannelView::open(channel_id, workspace, cx))
-                        .await
+                    let _ = workspace_window
+                        .update(&mut cx, |_, cx| {
+                            ChannelView::open(channel_id, cx.view().clone(), cx)
+                        })?
+                        .await?;
+                    anyhow::Ok(())
                 })
-                .detach_and_log_err(cx)
+                .detach_and_log_err(cx);
             }
             Ok(None) | Err(_) => cx
                 .spawn({
@@ -277,36 +313,49 @@ fn main() {
                 .detach(),
         }
 
-        cx.spawn(|mut cx| {
-            let app_state = app_state.clone();
-            async move {
-                while let Some(request) = open_rx.next().await {
-                    match request {
-                        OpenRequest::Paths { paths } => {
-                            cx.update(|cx| {
-                                workspace::open_paths(&paths, &app_state.clone(), None, cx)
-                            })
-                            .detach();
-                        }
-                        OpenRequest::CliConnection { connection } => {
-                            cx.spawn(|cx| handle_cli_connection(connection, app_state.clone(), cx))
-                                .detach();
-                        }
-                        OpenRequest::JoinChannel { channel_id } => cx
-                            .update(|cx| {
-                                workspace::join_channel(channel_id, app_state.clone(), None, cx)
-                            })
-                            .detach(),
-                        OpenRequest::OpenChannelNotes { channel_id } => {
-                            let app_state = app_state.clone();
-                            if let Ok(workspace) =
-                                workspace::get_any_active_workspace(app_state, cx.clone()).await
-                            {
+        let app_state = app_state.clone();
+        cx.spawn(move |cx| async move {
+            while let Some(request) = open_rx.next().await {
+                match request {
+                    OpenRequest::Paths { paths } => {
+                        cx.update(|cx| open_paths_and_log_errs(&paths, &app_state, cx))
+                            .ok();
+                    }
+                    OpenRequest::CliConnection { connection } => {
+                        let app_state = app_state.clone();
+                        cx.spawn(move |cx| {
+                            handle_cli_connection(connection, app_state.clone(), cx)
+                        })
+                        .detach();
+                    }
+                    OpenRequest::JoinChannel { channel_id } => {
+                        let app_state = app_state.clone();
+                        cx.update(|mut cx| {
+                            cx.spawn(|cx| async move {
                                 cx.update(|cx| {
-                                    ChannelView::open(channel_id, workspace, cx).detach();
-                                })
-                            }
-                        }
+                                    workspace::join_channel(channel_id, app_state, None, cx)
+                                })?
+                                .await?;
+                                anyhow::Ok(())
+                            })
+                            .detach_and_log_err(&mut cx);
+                        })
+                        .log_err();
+                    }
+                    OpenRequest::OpenChannelNotes { channel_id } => {
+                        let app_state = app_state.clone();
+                        let open_notes_task = cx.spawn(|mut cx| async move {
+                            let workspace_window =
+                                workspace::get_any_active_workspace(app_state, cx.clone()).await?;
+                            let _ = workspace_window
+                                .update(&mut cx, |_, cx| {
+                                    ChannelView::open(channel_id, cx.view().clone(), cx)
+                                })?
+                                .await?;
+                            anyhow::Ok(())
+                        });
+                        cx.update(|cx| open_notes_task.detach_and_log_err(cx))
+                            .log_err();
                     }
                 }
             }
@@ -357,21 +406,26 @@ async fn installation_id() -> Result<(String, bool)> {
     Ok((installation_id, false))
 }
 
-async fn restore_or_create_workspace(app_state: &Arc<AppState>, mut cx: AsyncAppContext) {
-    if let Some(location) = workspace::last_opened_workspace_paths().await {
-        cx.update(|cx| workspace::open_paths(location.paths().as_ref(), app_state, None, cx))
-            .await
-            .log_err();
-    } else if matches!(KEY_VALUE_STORE.read_kvp(FIRST_OPEN), Ok(None)) {
-        cx.update(|cx| show_welcome_experience(app_state, cx));
-    } else {
-        cx.update(|cx| {
-            workspace::open_new(app_state, cx, |workspace, cx| {
-                Editor::new_file(workspace, &Default::default(), cx)
-            })
-            .detach();
-        });
-    }
+async fn restore_or_create_workspace(app_state: &Arc<AppState>, cx: AsyncAppContext) {
+    async_maybe!({
+        if let Some(location) = workspace::last_opened_workspace_paths().await {
+            cx.update(|cx| workspace::open_paths(location.paths().as_ref(), app_state, None, cx))?
+                .await
+                .log_err();
+        } else if matches!(KEY_VALUE_STORE.read_kvp(FIRST_OPEN), Ok(None)) {
+            cx.update(|cx| show_welcome_view(app_state, cx)).log_err();
+        } else {
+            cx.update(|cx| {
+                workspace::open_new(app_state, cx, |workspace, cx| {
+                    Editor::new_file(workspace, &Default::default(), cx)
+                })
+                .detach();
+            })?;
+        }
+        anyhow::Ok(())
+    })
+    .await
+    .log_err();
 }
 
 fn init_paths() {
@@ -444,7 +498,7 @@ static PANIC_COUNT: AtomicU32 = AtomicU32::new(0);
 
 fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: String) {
     let is_pty = stdout_is_a_pty();
-    let platform = app.platform();
+    let app_metadata = app.metadata();
 
     panic::set_hook(Box::new(move |info| {
         let prior_panic_count = PANIC_COUNT.fetch_add(1, Ordering::SeqCst);
@@ -480,8 +534,8 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
             std::process::exit(-1);
         }
 
-        let app_version = ZED_APP_VERSION
-            .or_else(|| platform.app_version().ok())
+        let app_version = client::ZED_APP_VERSION
+            .or(app_metadata.app_version)
             .map_or("dev".to_string(), |v| v.to_string());
 
         let backtrace = Backtrace::new();
@@ -508,11 +562,11 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
             }),
             app_version: app_version.clone(),
             release_channel: RELEASE_CHANNEL.display_name().into(),
-            os_name: platform.os_name().into(),
-            os_version: platform
-                .os_version()
-                .ok()
-                .map(|os_version| os_version.to_string()),
+            os_name: app_metadata.os_name.into(),
+            os_version: app_metadata
+                .os_version
+                .as_ref()
+                .map(SemanticVersion::to_string),
             architecture: env::consts::ARCH.into(),
             panicked_on: Utc::now().timestamp_millis(),
             backtrace,
@@ -545,83 +599,76 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
 }
 
 fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut AppContext) {
-    let telemetry_settings = *settings::get::<TelemetrySettings>(cx);
-
-    cx.background()
-        .spawn({
-            async move {
-                let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL);
-                let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
-                while let Some(child) = children.next().await {
-                    let child = child?;
-                    let child_path = child.path();
-
-                    if child_path.extension() != Some(OsStr::new("panic")) {
-                        continue;
-                    }
-                    let filename = if let Some(filename) = child_path.file_name() {
-                        filename.to_string_lossy()
-                    } else {
-                        continue;
-                    };
-
-                    if !filename.starts_with("zed") {
-                        continue;
-                    }
+    let telemetry_settings = *client::TelemetrySettings::get_global(cx);
+
+    cx.background_executor()
+        .spawn(async move {
+            let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL);
+            let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
+            while let Some(child) = children.next().await {
+                let child = child?;
+                let child_path = child.path();
+
+                if child_path.extension() != Some(OsStr::new("panic")) {
+                    continue;
+                }
+                let filename = if let Some(filename) = child_path.file_name() {
+                    filename.to_string_lossy()
+                } else {
+                    continue;
+                };
 
-                    if telemetry_settings.diagnostics {
-                        let panic_file_content = smol::fs::read_to_string(&child_path)
-                            .await
-                            .context("error reading panic file")?;
+                if !filename.starts_with("zed") {
+                    continue;
+                }
 
-                        let panic = serde_json::from_str(&panic_file_content)
-                            .ok()
-                            .or_else(|| {
+                if telemetry_settings.diagnostics {
+                    let panic_file_content = smol::fs::read_to_string(&child_path)
+                        .await
+                        .context("error reading panic file")?;
+
+                    let panic = serde_json::from_str(&panic_file_content)
+                        .ok()
+                        .or_else(|| {
+                            panic_file_content
+                                .lines()
+                                .next()
+                                .and_then(|line| serde_json::from_str(line).ok())
+                        })
+                        .unwrap_or_else(|| {
+                            log::error!(
+                                "failed to deserialize panic file {:?}",
                                 panic_file_content
-                                    .lines()
-                                    .next()
-                                    .and_then(|line| serde_json::from_str(line).ok())
-                            })
-                            .unwrap_or_else(|| {
-                                log::error!(
-                                    "failed to deserialize panic file {:?}",
-                                    panic_file_content
-                                );
-                                None
-                            });
-
-                        if let Some(panic) = panic {
-                            let body = serde_json::to_string(&PanicRequest {
-                                panic,
-                                token: ZED_SECRET_CLIENT_TOKEN.into(),
-                            })
-                            .unwrap();
-
-                            let request = Request::post(&panic_report_url)
-                                .redirect_policy(isahc::config::RedirectPolicy::Follow)
-                                .header("Content-Type", "application/json")
-                                .body(body.into())?;
-                            let response =
-                                http.send(request).await.context("error sending panic")?;
-                            if !response.status().is_success() {
-                                log::error!(
-                                    "Error uploading panic to server: {}",
-                                    response.status()
-                                );
-                            }
+                            );
+                            None
+                        });
+
+                    if let Some(panic) = panic {
+                        let body = serde_json::to_string(&PanicRequest {
+                            panic,
+                            token: client::ZED_SECRET_CLIENT_TOKEN.into(),
+                        })
+                        .unwrap();
+
+                        let request = Request::post(&panic_report_url)
+                            .redirect_policy(isahc::config::RedirectPolicy::Follow)
+                            .header("Content-Type", "application/json")
+                            .body(body.into())?;
+                        let response = http.send(request).await.context("error sending panic")?;
+                        if !response.status().is_success() {
+                            log::error!("Error uploading panic to server: {}", response.status());
                         }
                     }
-
-                    // We've done what we can, delete the file
-                    std::fs::remove_file(child_path)
-                        .context("error removing panic")
-                        .log_err();
                 }
-                Ok::<_, anyhow::Error>(())
+
+                // We've done what we can, delete the file
+                std::fs::remove_file(child_path)
+                    .context("error removing panic")
+                    .log_err();
             }
-            .log_err()
+            Ok::<_, anyhow::Error>(())
         })
-        .detach();
+        .detach_and_log_err(cx);
 }
 
 async fn load_login_shell_environment() -> Result<()> {
@@ -680,58 +727,38 @@ fn collect_url_args() -> Vec<String> {
         .collect()
 }
 
-fn load_embedded_fonts(app: &App) {
-    let font_paths = Assets.list("fonts");
+fn load_embedded_fonts(cx: &AppContext) {
+    let asset_source = cx.asset_source();
+    let font_paths = asset_source.list("fonts").unwrap();
     let embedded_fonts = Mutex::new(Vec::new());
-    smol::block_on(app.background().scoped(|scope| {
+    let executor = cx.background_executor();
+
+    executor.block(executor.scoped(|scope| {
         for font_path in &font_paths {
             if !font_path.ends_with(".ttf") {
                 continue;
             }
 
             scope.spawn(async {
-                let font_path = &*font_path;
-                let font_bytes = Assets.load(font_path).unwrap().to_vec();
+                let font_bytes = asset_source.load(font_path).unwrap().to_vec();
                 embedded_fonts.lock().push(Arc::from(font_bytes));
             });
         }
     }));
-    app.platform()
-        .fonts()
+
+    cx.text_system()
         .add_fonts(&embedded_fonts.into_inner())
         .unwrap();
 }
 
 #[cfg(debug_assertions)]
-async fn watch_themes(fs: Arc<dyn Fs>, mut cx: AsyncAppContext) -> Option<()> {
-    let mut events = fs
-        .watch("styles/src".as_ref(), std::time::Duration::from_millis(100))
-        .await;
-    while (events.next().await).is_some() {
-        let output = Command::new("npm")
-            .current_dir("styles")
-            .args(["run", "build"])
-            .output()
-            .await
-            .log_err()?;
-        if output.status.success() {
-            cx.update(|cx| theme_selector::reload(cx))
-        } else {
-            eprintln!(
-                "build script failed {}",
-                String::from_utf8_lossy(&output.stderr)
-            );
-        }
-    }
-    Some(())
-}
+async fn watch_languages(fs: Arc<dyn fs::Fs>, languages: Arc<LanguageRegistry>) -> Option<()> {
+    use std::time::Duration;
 
-#[cfg(debug_assertions)]
-async fn watch_languages(fs: Arc<dyn Fs>, languages: Arc<LanguageRegistry>) -> Option<()> {
     let mut events = fs
         .watch(
-            "crates/zed/src/languages".as_ref(),
-            std::time::Duration::from_millis(100),
+            "crates/zed2/src/languages".as_ref(),
+            Duration::from_millis(100),
         )
         .await;
     while (events.next().await).is_some() {
@@ -741,12 +768,14 @@ async fn watch_languages(fs: Arc<dyn Fs>, languages: Arc<LanguageRegistry>) -> O
 }
 
 #[cfg(debug_assertions)]
-fn watch_file_types(fs: Arc<dyn Fs>, cx: &mut AppContext) {
-    cx.spawn(|mut cx| async move {
+fn watch_file_types(fs: Arc<dyn fs::Fs>, cx: &mut AppContext) {
+    use std::time::Duration;
+
+    cx.spawn(|cx| async move {
         let mut events = fs
             .watch(
                 "assets/icons/file_icons/file_types.json".as_ref(),
-                std::time::Duration::from_millis(100),
+                Duration::from_millis(100),
             )
             .await;
         while (events.next().await).is_some() {
@@ -755,29 +784,16 @@ fn watch_file_types(fs: Arc<dyn Fs>, cx: &mut AppContext) {
                     *file_types = project_panel::file_associations::FileAssociations::new(Assets);
                 });
             })
+            .ok();
         }
     })
     .detach()
 }
 
 #[cfg(not(debug_assertions))]
-async fn watch_themes(_fs: Arc<dyn Fs>, _cx: AsyncAppContext) -> Option<()> {
-    None
-}
-
-#[cfg(not(debug_assertions))]
-async fn watch_languages(_: Arc<dyn Fs>, _: Arc<LanguageRegistry>) -> Option<()> {
+async fn watch_languages(_: Arc<dyn fs::Fs>, _: Arc<LanguageRegistry>) -> Option<()> {
     None
 }
 
 #[cfg(not(debug_assertions))]
-fn watch_file_types(_fs: Arc<dyn Fs>, _cx: &mut AppContext) {}
-
-pub fn background_actions() -> &'static [(&'static str, &'static dyn Action)] {
-    &[
-        ("Go to file", &file_finder::Toggle),
-        ("Open command palette", &command_palette::Toggle),
-        ("Open recent projects", &recent_projects::OpenRecent),
-        ("Change your settings", &zed_actions::OpenSettings),
-    ]
-}
+fn watch_file_types(_fs: Arc<dyn fs::Fs>, _cx: &mut AppContext) {}

crates/zed/src/menus.rs 🔗

@@ -1,174 +0,0 @@
-use gpui::{Menu, MenuItem, OsAction};
-
-#[cfg(target_os = "macos")]
-pub fn menus() -> Vec<Menu<'static>> {
-    vec![
-        Menu {
-            name: "Zed",
-            items: vec![
-                MenuItem::action("About Zed…", super::About),
-                MenuItem::action("Check for Updates", auto_update::Check),
-                MenuItem::separator(),
-                MenuItem::submenu(Menu {
-                    name: "Preferences",
-                    items: vec![
-                        MenuItem::action("Open Settings", super::OpenSettings),
-                        MenuItem::action("Open Key Bindings", super::OpenKeymap),
-                        MenuItem::action("Open Default Settings", super::OpenDefaultSettings),
-                        MenuItem::action("Open Default Key Bindings", super::OpenDefaultKeymap),
-                        MenuItem::action("Open Local Settings", super::OpenLocalSettings),
-                        MenuItem::action("Select Theme", theme_selector::Toggle),
-                    ],
-                }),
-                MenuItem::action("Install CLI", install_cli::Install),
-                MenuItem::separator(),
-                MenuItem::action("Hide Zed", super::Hide),
-                MenuItem::action("Hide Others", super::HideOthers),
-                MenuItem::action("Show All", super::ShowAll),
-                MenuItem::action("Quit", super::Quit),
-            ],
-        },
-        Menu {
-            name: "File",
-            items: vec![
-                MenuItem::action("New", workspace::NewFile),
-                MenuItem::action("New Window", workspace::NewWindow),
-                MenuItem::separator(),
-                MenuItem::action("Open…", workspace::Open),
-                MenuItem::action("Open Recent...", recent_projects::OpenRecent),
-                MenuItem::separator(),
-                MenuItem::action("Add Folder to Project…", workspace::AddFolderToProject),
-                MenuItem::action("Save", workspace::Save { save_intent: None }),
-                MenuItem::action("Save As…", workspace::SaveAs),
-                MenuItem::action("Save All", workspace::SaveAll { save_intent: None }),
-                MenuItem::action(
-                    "Close Editor",
-                    workspace::CloseActiveItem { save_intent: None },
-                ),
-                MenuItem::action("Close Window", workspace::CloseWindow),
-            ],
-        },
-        Menu {
-            name: "Edit",
-            items: vec![
-                MenuItem::os_action("Undo", editor::Undo, OsAction::Undo),
-                MenuItem::os_action("Redo", editor::Redo, OsAction::Redo),
-                MenuItem::separator(),
-                MenuItem::os_action("Cut", editor::Cut, OsAction::Cut),
-                MenuItem::os_action("Copy", editor::Copy, OsAction::Copy),
-                MenuItem::os_action("Paste", editor::Paste, OsAction::Paste),
-                MenuItem::separator(),
-                MenuItem::action("Find", search::buffer_search::Deploy { focus: true }),
-                MenuItem::action("Find In Project", workspace::NewSearch),
-                MenuItem::separator(),
-                MenuItem::action("Toggle Line Comment", editor::ToggleComments::default()),
-                MenuItem::action("Emoji & Symbols", editor::ShowCharacterPalette),
-            ],
-        },
-        Menu {
-            name: "Selection",
-            items: vec![
-                MenuItem::os_action("Select All", editor::SelectAll, OsAction::SelectAll),
-                MenuItem::action("Expand Selection", editor::SelectLargerSyntaxNode),
-                MenuItem::action("Shrink Selection", editor::SelectSmallerSyntaxNode),
-                MenuItem::separator(),
-                MenuItem::action("Add Cursor Above", editor::AddSelectionAbove),
-                MenuItem::action("Add Cursor Below", editor::AddSelectionBelow),
-                MenuItem::action(
-                    "Select Next Occurrence",
-                    editor::SelectNext {
-                        replace_newest: false,
-                    },
-                ),
-                MenuItem::separator(),
-                MenuItem::action("Move Line Up", editor::MoveLineUp),
-                MenuItem::action("Move Line Down", editor::MoveLineDown),
-                MenuItem::action("Duplicate Selection", editor::DuplicateLine),
-            ],
-        },
-        Menu {
-            name: "View",
-            items: vec![
-                MenuItem::action("Zoom In", super::IncreaseBufferFontSize),
-                MenuItem::action("Zoom Out", super::DecreaseBufferFontSize),
-                MenuItem::action("Reset Zoom", super::ResetBufferFontSize),
-                MenuItem::separator(),
-                MenuItem::action("Toggle Left Dock", workspace::ToggleLeftDock),
-                MenuItem::action("Toggle Right Dock", workspace::ToggleRightDock),
-                MenuItem::action("Toggle Bottom Dock", workspace::ToggleBottomDock),
-                MenuItem::action("Close All Docks", workspace::CloseAllDocks),
-                MenuItem::submenu(Menu {
-                    name: "Editor Layout",
-                    items: vec![
-                        MenuItem::action("Split Up", workspace::SplitUp),
-                        MenuItem::action("Split Down", workspace::SplitDown),
-                        MenuItem::action("Split Left", workspace::SplitLeft),
-                        MenuItem::action("Split Right", workspace::SplitRight),
-                    ],
-                }),
-                MenuItem::separator(),
-                MenuItem::action("Project Panel", project_panel::ToggleFocus),
-                MenuItem::action("Command Palette", command_palette::Toggle),
-                MenuItem::action("Diagnostics", diagnostics::Deploy),
-                MenuItem::separator(),
-            ],
-        },
-        Menu {
-            name: "Go",
-            items: vec![
-                MenuItem::action("Back", workspace::GoBack),
-                MenuItem::action("Forward", workspace::GoForward),
-                MenuItem::separator(),
-                MenuItem::action("Go to File", file_finder::Toggle),
-                MenuItem::action("Go to Symbol in Project", project_symbols::Toggle),
-                MenuItem::action("Go to Symbol in Editor", outline::Toggle),
-                MenuItem::action("Go to Definition", editor::GoToDefinition),
-                MenuItem::action("Go to Type Definition", editor::GoToTypeDefinition),
-                MenuItem::action("Find All References", editor::FindAllReferences),
-                MenuItem::action("Go to Line/Column", go_to_line::Toggle),
-                MenuItem::separator(),
-                MenuItem::action("Next Problem", editor::GoToDiagnostic),
-                MenuItem::action("Previous Problem", editor::GoToPrevDiagnostic),
-            ],
-        },
-        Menu {
-            name: "Window",
-            items: vec![
-                MenuItem::action("Minimize", super::Minimize),
-                MenuItem::action("Zoom", super::Zoom),
-                MenuItem::separator(),
-            ],
-        },
-        Menu {
-            name: "Help",
-            items: vec![
-                MenuItem::action("Command Palette", command_palette::Toggle),
-                MenuItem::separator(),
-                MenuItem::action("View Telemetry", crate::OpenTelemetryLog),
-                MenuItem::action("View Dependency Licenses", crate::OpenLicenses),
-                MenuItem::action("Show Welcome", workspace::Welcome),
-                MenuItem::separator(),
-                MenuItem::action("Give us feedback", feedback::feedback_editor::GiveFeedback),
-                MenuItem::action(
-                    "Copy System Specs Into Clipboard",
-                    feedback::CopySystemSpecsIntoClipboard,
-                ),
-                MenuItem::action("File Bug Report", feedback::FileBugReport),
-                MenuItem::action("Request Feature", feedback::RequestFeature),
-                MenuItem::separator(),
-                MenuItem::action(
-                    "Documentation",
-                    crate::OpenBrowser {
-                        url: "https://zed.dev/docs".into(),
-                    },
-                ),
-                MenuItem::action(
-                    "Zed Twitter",
-                    crate::OpenBrowser {
-                        url: "https://twitter.com/zeddotdev".into(),
-                    },
-                ),
-            ],
-        },
-    ]
-}

crates/zed/src/open_listener.rs 🔗

@@ -54,7 +54,7 @@ impl OpenListener {
         )
     }
 
-    pub fn open_urls(&self, urls: Vec<String>) {
+    pub fn open_urls(&self, urls: &[String]) {
         self.triggered.store(true, Ordering::Release);
         let request = if let Some(server_name) =
             urls.first().and_then(|url| url.strip_prefix("zed-cli://"))
@@ -101,7 +101,7 @@ impl OpenListener {
         None
     }
 
-    fn handle_file_urls(&self, urls: Vec<String>) -> Option<OpenRequest> {
+    fn handle_file_urls(&self, urls: &[String]) -> Option<OpenRequest> {
         let paths: Vec<_> = urls
             .iter()
             .flat_map(|url| url.strip_prefix("file://"))
@@ -187,105 +187,109 @@ pub async fn handle_cli_connection(
                 };
 
                 let mut errored = false;
-                match cx
-                    .update(|cx| workspace::open_paths(&paths, &app_state, None, cx))
-                    .await
-                {
-                    Ok((workspace, items)) => {
-                        let mut item_release_futures = Vec::new();
 
-                        for (item, path) in items.into_iter().zip(&paths) {
-                            match item {
-                                Some(Ok(item)) => {
-                                    if let Some(point) = caret_positions.remove(path) {
-                                        if let Some(active_editor) = item.downcast::<Editor>() {
-                                            active_editor
-                                                .downgrade()
-                                                .update(&mut cx, |editor, cx| {
-                                                    let snapshot =
-                                                        editor.snapshot(cx).display_snapshot;
-                                                    let point = snapshot
-                                                        .buffer_snapshot
-                                                        .clip_point(point, Bias::Left);
-                                                    editor.change_selections(
-                                                        Some(Autoscroll::center()),
-                                                        cx,
-                                                        |s| s.select_ranges([point..point]),
-                                                    );
-                                                })
-                                                .log_err();
+                match cx.update(|cx| workspace::open_paths(&paths, &app_state, None, cx)) {
+                    Ok(task) => match task.await {
+                        Ok((workspace, items)) => {
+                            let mut item_release_futures = Vec::new();
+
+                            for (item, path) in items.into_iter().zip(&paths) {
+                                match item {
+                                    Some(Ok(item)) => {
+                                        if let Some(point) = caret_positions.remove(path) {
+                                            if let Some(active_editor) = item.downcast::<Editor>() {
+                                                workspace
+                                                    .update(&mut cx, |_, cx| {
+                                                        active_editor.update(cx, |editor, cx| {
+                                                            let snapshot = editor
+                                                                .snapshot(cx)
+                                                                .display_snapshot;
+                                                            let point = snapshot
+                                                                .buffer_snapshot
+                                                                .clip_point(point, Bias::Left);
+                                                            editor.change_selections(
+                                                                Some(Autoscroll::center()),
+                                                                cx,
+                                                                |s| s.select_ranges([point..point]),
+                                                            );
+                                                        });
+                                                    })
+                                                    .log_err();
+                                            }
                                         }
-                                    }
 
-                                    let released = oneshot::channel();
-                                    cx.update(|cx| {
-                                        item.on_release(
-                                            cx,
-                                            Box::new(move |_| {
-                                                let _ = released.0.send(());
-                                            }),
-                                        )
-                                        .detach();
-                                    });
-                                    item_release_futures.push(released.1);
-                                }
-                                Some(Err(err)) => {
-                                    responses
-                                        .send(CliResponse::Stderr {
-                                            message: format!("error opening {:?}: {}", path, err),
+                                        cx.update(|cx| {
+                                            let released = oneshot::channel();
+                                            item.on_release(
+                                                cx,
+                                                Box::new(move |_| {
+                                                    let _ = released.0.send(());
+                                                }),
+                                            )
+                                            .detach();
+                                            item_release_futures.push(released.1);
                                         })
                                         .log_err();
-                                    errored = true;
+                                    }
+                                    Some(Err(err)) => {
+                                        responses
+                                            .send(CliResponse::Stderr {
+                                                message: format!(
+                                                    "error opening {:?}: {}",
+                                                    path, err
+                                                ),
+                                            })
+                                            .log_err();
+                                        errored = true;
+                                    }
+                                    None => {}
                                 }
-                                None => {}
                             }
-                        }
 
-                        if wait {
-                            let background = cx.background();
-                            let wait = async move {
-                                if paths.is_empty() {
-                                    let (done_tx, done_rx) = oneshot::channel();
-                                    if let Some(workspace) = workspace.upgrade(&cx) {
-                                        let _subscription = cx.update(|cx| {
-                                            cx.observe_release(&workspace, move |_, _| {
+                            if wait {
+                                let background = cx.background_executor().clone();
+                                let wait = async move {
+                                    if paths.is_empty() {
+                                        let (done_tx, done_rx) = oneshot::channel();
+                                        let _subscription = workspace.update(&mut cx, |_, cx| {
+                                            cx.on_release(move |_, _, _| {
                                                 let _ = done_tx.send(());
                                             })
                                         });
-                                        drop(workspace);
                                         let _ = done_rx.await;
-                                    }
-                                } else {
-                                    let _ =
-                                        futures::future::try_join_all(item_release_futures).await;
-                                };
-                            }
-                            .fuse();
-                            futures::pin_mut!(wait);
+                                    } else {
+                                        let _ = futures::future::try_join_all(item_release_futures)
+                                            .await;
+                                    };
+                                }
+                                .fuse();
+                                futures::pin_mut!(wait);
 
-                            loop {
-                                // Repeatedly check if CLI is still open to avoid wasting resources
-                                // waiting for files or workspaces to close.
-                                let mut timer = background.timer(Duration::from_secs(1)).fuse();
-                                futures::select_biased! {
-                                    _ = wait => break,
-                                    _ = timer => {
-                                        if responses.send(CliResponse::Ping).is_err() {
-                                            break;
+                                loop {
+                                    // Repeatedly check if CLI is still open to avoid wasting resources
+                                    // waiting for files or workspaces to close.
+                                    let mut timer = background.timer(Duration::from_secs(1)).fuse();
+                                    futures::select_biased! {
+                                        _ = wait => break,
+                                        _ = timer => {
+                                            if responses.send(CliResponse::Ping).is_err() {
+                                                break;
+                                            }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
-                    Err(error) => {
-                        errored = true;
-                        responses
-                            .send(CliResponse::Stderr {
-                                message: format!("error opening {:?}: {}", paths, error),
-                            })
-                            .log_err();
-                    }
+                        Err(error) => {
+                            errored = true;
+                            responses
+                                .send(CliResponse::Stderr {
+                                    message: format!("error opening {:?}: {}", paths, error),
+                                })
+                                .log_err();
+                        }
+                    },
+                    Err(_) => errored = true,
                 }
 
                 responses

crates/zed/src/test.rs 🔗

@@ -1,7 +0,0 @@
-#[cfg(test)]
-#[ctor::ctor]
-fn init_logger() {
-    if std::env::var("RUST_LOG").is_ok() {
-        env_logger::init();
-    }
-}

crates/zed/src/zed.rs 🔗

@@ -1,474 +1,486 @@
-pub mod assets;
+mod app_menus;
+mod assets;
 pub mod languages;
-pub mod menus;
-pub mod only_instance;
-pub mod open_listener;
-#[cfg(any(test, feature = "test-support"))]
-pub mod test;
-
-use anyhow::Context;
-use assets::Assets;
+mod only_instance;
+mod open_listener;
+
+pub use app_menus::*;
+pub use assets::*;
 use assistant::AssistantPanel;
 use breadcrumbs::Breadcrumbs;
-pub use client;
-use collab_ui::CollabTitlebarItem; // TODO: Add back toggle collab ui shortcut
 use collections::VecDeque;
-pub use editor;
 use editor::{Editor, MultiBuffer};
-
-use anyhow::anyhow;
-use feedback::{
-    feedback_info_text::FeedbackInfoText, submit_feedback_button::SubmitFeedbackButton,
-};
-use futures::{channel::mpsc, StreamExt};
 use gpui::{
-    anyhow::{self, Result},
-    geometry::vector::vec2f,
-    impl_actions,
-    platform::{Platform, PromptLevel, TitlebarOptions, WindowBounds, WindowKind, WindowOptions},
-    AppContext, AsyncAppContext, Task, ViewContext, WeakViewHandle,
+    actions, point, px, AppContext, Context, FocusableView, PromptLevel, TitlebarOptions, View,
+    ViewContext, VisualContext, WindowBounds, WindowKind, WindowOptions,
 };
-pub use lsp;
-use open_listener::OpenListener;
-pub use project;
+pub use only_instance::*;
+pub use open_listener::*;
+
+use anyhow::{anyhow, Context as _};
+use futures::{channel::mpsc, StreamExt};
 use project_panel::ProjectPanel;
 use quick_action_bar::QuickActionBar;
-use search::{BufferSearchBar, ProjectSearchBar};
-use serde::Deserialize;
-use serde_json::to_string_pretty;
-use settings::{initial_local_settings_content, KeymapFile, SettingsStore};
-use std::{borrow::Cow, str, sync::Arc};
-use terminal_view::terminal_panel::{self, TerminalPanel};
+use search::project_search::ProjectSearchBar;
+use settings::{initial_local_settings_content, load_default_keymap, KeymapFile, Settings};
+use std::{borrow::Cow, ops::Deref, sync::Arc};
+use terminal_view::terminal_panel::TerminalPanel;
 use util::{
     asset_str,
-    channel::ReleaseChannel,
+    channel::{AppCommitSha, ReleaseChannel},
     paths::{self, LOCAL_SETTINGS_RELATIVE_PATH},
     ResultExt,
 };
 use uuid::Uuid;
-use welcome::BaseKeymap;
-pub use workspace;
+use workspace::Pane;
 use workspace::{
-    create_and_open_local_file, dock::PanelHandle,
-    notifications::simple_message_notification::MessageNotification, open_new, AppState, NewFile,
-    NewWindow, Workspace, WorkspaceSettings,
+    create_and_open_local_file, notifications::simple_message_notification::MessageNotification,
+    open_new, AppState, NewFile, NewWindow, Workspace, WorkspaceSettings,
 };
-use zed_actions::*;
-
-#[derive(Deserialize, Clone, PartialEq)]
-pub struct OpenBrowser {
-    url: Arc<str>,
-}
+use zed_actions::{OpenBrowser, OpenSettings, OpenZedURL, Quit};
+
+actions!(
+    zed,
+    [
+        About,
+        DebugElements,
+        DecreaseBufferFontSize,
+        Hide,
+        HideOthers,
+        IncreaseBufferFontSize,
+        Minimize,
+        OpenDefaultKeymap,
+        OpenDefaultSettings,
+        OpenKeymap,
+        OpenLicenses,
+        OpenLocalSettings,
+        OpenLog,
+        OpenTelemetryLog,
+        ResetBufferFontSize,
+        ResetDatabase,
+        ShowAll,
+        ToggleFullScreen,
+        Zoom,
+    ]
+);
 
-impl_actions!(zed, [OpenBrowser]);
-
-pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
-    cx.add_action(about);
-    cx.add_global_action(|_: &Hide, cx: &mut gpui::AppContext| {
-        cx.platform().hide();
-    });
-    cx.add_global_action(|_: &HideOthers, cx: &mut gpui::AppContext| {
-        cx.platform().hide_other_apps();
-    });
-    cx.add_global_action(|_: &ShowAll, cx: &mut gpui::AppContext| {
-        cx.platform().unhide_other_apps();
-    });
-    cx.add_action(
-        |_: &mut Workspace, _: &Minimize, cx: &mut ViewContext<Workspace>| {
-            cx.minimize_window();
-        },
-    );
-    cx.add_action(
-        |_: &mut Workspace, _: &Zoom, cx: &mut ViewContext<Workspace>| {
-            cx.zoom_window();
-        },
-    );
-    cx.add_action(
-        |_: &mut Workspace, _: &ToggleFullScreen, cx: &mut ViewContext<Workspace>| {
-            cx.toggle_full_screen();
-        },
-    );
-    cx.add_global_action(quit);
-    cx.add_global_action(move |action: &OpenZedURL, cx| {
-        cx.global::<Arc<OpenListener>>()
-            .open_urls(vec![action.url.clone()])
-    });
-    cx.add_global_action(move |action: &OpenBrowser, cx| cx.platform().open_url(&action.url));
-    cx.add_global_action(move |_: &IncreaseBufferFontSize, cx| {
-        theme::adjust_font_size(cx, |size| *size += 1.0)
-    });
-    cx.add_global_action(move |_: &DecreaseBufferFontSize, cx| {
-        theme::adjust_font_size(cx, |size| *size -= 1.0)
-    });
-    cx.add_global_action(move |_: &ResetBufferFontSize, cx| theme::reset_font_size(cx));
-    cx.add_global_action(move |_: &install_cli::Install, cx| {
-        cx.spawn(|cx| async move {
-            install_cli::install_cli(&cx)
-                .await
-                .context("error creating CLI symlink")
-        })
-        .detach_and_log_err(cx);
-    });
-    cx.add_action(
-        move |workspace: &mut Workspace, _: &OpenLog, cx: &mut ViewContext<Workspace>| {
-            open_log_file(workspace, cx);
-        },
-    );
-    cx.add_action(
-        move |workspace: &mut Workspace, _: &OpenLicenses, cx: &mut ViewContext<Workspace>| {
-            open_bundled_file(
-                workspace,
-                asset_str::<Assets>("licenses.md"),
-                "Open Source License Attribution",
-                "Markdown",
-                cx,
-            );
-        },
-    );
-    cx.add_action(
-        move |workspace: &mut Workspace, _: &OpenTelemetryLog, cx: &mut ViewContext<Workspace>| {
-            open_telemetry_log_file(workspace, cx);
-        },
-    );
-    cx.add_action(
-        move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
-            create_and_open_local_file(&paths::KEYMAP, cx, Default::default).detach_and_log_err(cx);
-        },
-    );
-    cx.add_action(
-        move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
-            create_and_open_local_file(&paths::SETTINGS, cx, || {
-                settings::initial_user_settings_content().as_ref().into()
-            })
-            .detach_and_log_err(cx);
-        },
-    );
-    cx.add_action(open_local_settings_file);
-    cx.add_action(
-        move |workspace: &mut Workspace, _: &OpenDefaultKeymap, cx: &mut ViewContext<Workspace>| {
-            open_bundled_file(
-                workspace,
-                settings::default_keymap(),
-                "Default Key Bindings",
-                "JSON",
-                cx,
-            );
-        },
-    );
-    cx.add_action(
-        move |workspace: &mut Workspace,
-              _: &OpenDefaultSettings,
-              cx: &mut ViewContext<Workspace>| {
-            open_bundled_file(
-                workspace,
-                settings::default_settings(),
-                "Default Settings",
-                "JSON",
-                cx,
-            );
-        },
-    );
-    cx.add_action({
-        move |workspace: &mut Workspace, _: &DebugElements, cx: &mut ViewContext<Workspace>| {
-            let app_state = workspace.app_state().clone();
-            let markdown = app_state.languages.language_for_name("JSON");
-            let window = cx.window();
-            cx.spawn(|workspace, mut cx| async move {
-                let markdown = markdown.await.log_err();
-                let content = to_string_pretty(&window.debug_elements(&cx).ok_or_else(|| {
-                    anyhow!("could not debug elements for window {}", window.id())
-                })?)
-                .unwrap();
-                workspace
-                    .update(&mut cx, |workspace, cx| {
-                        workspace.with_local_workspace(cx, move |workspace, cx| {
-                            let project = workspace.project().clone();
-
-                            let buffer = project
-                                .update(cx, |project, cx| {
-                                    project.create_buffer(&content, markdown, cx)
-                                })
-                                .expect("creating buffers on a local workspace always succeeds");
-                            let buffer = cx.add_model(|cx| {
-                                MultiBuffer::singleton(buffer, cx)
-                                    .with_title("Debug Elements".into())
-                            });
-                            workspace.add_item(
-                                Box::new(cx.add_view(|cx| {
-                                    Editor::for_multibuffer(buffer, Some(project.clone()), cx)
-                                })),
-                                cx,
-                            );
-                        })
-                    })?
-                    .await
-            })
-            .detach_and_log_err(cx);
-        }
-    });
-    cx.add_action(
-        |workspace: &mut Workspace,
-         _: &project_panel::ToggleFocus,
-         cx: &mut ViewContext<Workspace>| {
-            workspace.toggle_panel_focus::<ProjectPanel>(cx);
-        },
-    );
-    cx.add_action(
-        |workspace: &mut Workspace,
-         _: &collab_ui::collab_panel::ToggleFocus,
-         cx: &mut ViewContext<Workspace>| {
-            workspace.toggle_panel_focus::<collab_ui::collab_panel::CollabPanel>(cx);
-        },
-    );
-    cx.add_action(
-        |workspace: &mut Workspace,
-         _: &collab_ui::chat_panel::ToggleFocus,
-         cx: &mut ViewContext<Workspace>| {
-            workspace.toggle_panel_focus::<collab_ui::chat_panel::ChatPanel>(cx);
-        },
-    );
-    cx.add_action(
-        |workspace: &mut Workspace,
-         _: &collab_ui::notification_panel::ToggleFocus,
-         cx: &mut ViewContext<Workspace>| {
-            workspace.toggle_panel_focus::<collab_ui::notification_panel::NotificationPanel>(cx);
-        },
-    );
-    cx.add_action(
-        |workspace: &mut Workspace,
-         _: &terminal_panel::ToggleFocus,
-         cx: &mut ViewContext<Workspace>| {
-            workspace.toggle_panel_focus::<TerminalPanel>(cx);
-        },
-    );
-    cx.add_global_action({
-        let app_state = Arc::downgrade(&app_state);
-        move |_: &NewWindow, cx: &mut AppContext| {
-            if let Some(app_state) = app_state.upgrade() {
-                open_new(&app_state, cx, |workspace, cx| {
-                    Editor::new_file(workspace, &Default::default(), cx)
-                })
-                .detach();
-            }
-        }
-    });
-    cx.add_global_action({
-        let app_state = Arc::downgrade(&app_state);
-        move |_: &NewFile, cx: &mut AppContext| {
-            if let Some(app_state) = app_state.upgrade() {
-                open_new(&app_state, cx, |workspace, cx| {
-                    Editor::new_file(workspace, &Default::default(), cx)
-                })
-                .detach();
-            }
-        }
+pub fn build_window_options(
+    bounds: Option<WindowBounds>,
+    display_uuid: Option<Uuid>,
+    cx: &mut AppContext,
+) -> WindowOptions {
+    let bounds = bounds.unwrap_or(WindowBounds::Maximized);
+    let display = display_uuid.and_then(|uuid| {
+        cx.displays()
+            .into_iter()
+            .find(|display| display.uuid().ok() == Some(uuid))
     });
-    load_default_keymap(cx);
+
+    WindowOptions {
+        bounds,
+        titlebar: Some(TitlebarOptions {
+            title: None,
+            appears_transparent: true,
+            traffic_light_position: Some(point(px(8.), px(8.))),
+        }),
+        center: false,
+        focus: false,
+        show: false,
+        kind: WindowKind::Normal,
+        is_movable: true,
+        display_id: display.map(|display| display.id()),
+    }
 }
 
-pub fn initialize_workspace(
-    workspace_handle: WeakViewHandle<Workspace>,
-    was_deserialized: bool,
-    app_state: Arc<AppState>,
-    cx: AsyncAppContext,
-) -> Task<Result<()>> {
-    cx.spawn(|mut cx| async move {
-        workspace_handle.update(&mut cx, |workspace, cx| {
-            let workspace_handle = cx.handle();
-            cx.subscribe(&workspace_handle, {
-                move |workspace, _, event, cx| {
-                    if let workspace::Event::PaneAdded(pane) = event {
-                        pane.update(cx, |pane, cx| {
-                            pane.toolbar().update(cx, |toolbar, cx| {
-                                let breadcrumbs = cx.add_view(|_| Breadcrumbs::new(workspace));
-                                toolbar.add_item(breadcrumbs, cx);
-                                let buffer_search_bar = cx.add_view(BufferSearchBar::new);
-                                toolbar.add_item(buffer_search_bar.clone(), cx);
-                                let quick_action_bar = cx.add_view(|_| {
-                                    QuickActionBar::new(buffer_search_bar, workspace)
-                                });
-                                toolbar.add_item(quick_action_bar, cx);
-                                let diagnostic_editor_controls =
-                                    cx.add_view(|_| diagnostics::ToolbarControls::new());
-                                toolbar.add_item(diagnostic_editor_controls, cx);
-                                let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
-                                toolbar.add_item(project_search_bar, cx);
-                                let submit_feedback_button =
-                                    cx.add_view(|_| SubmitFeedbackButton::new());
-                                toolbar.add_item(submit_feedback_button, cx);
-                                let feedback_info_text = cx.add_view(|_| FeedbackInfoText::new());
-                                toolbar.add_item(feedback_info_text, cx);
-                                let lsp_log_item =
-                                    cx.add_view(|_| language_tools::LspLogToolbarItemView::new());
-                                toolbar.add_item(lsp_log_item, cx);
-                                let syntax_tree_item = cx
-                                    .add_view(|_| language_tools::SyntaxTreeToolbarItemView::new());
-                                toolbar.add_item(syntax_tree_item, cx);
-                            })
-                        });
-                    }
+pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
+    cx.observe_new_views(move |workspace: &mut Workspace, cx| {
+        let workspace_handle = cx.view().clone();
+        let center_pane = workspace.active_pane().clone();
+        initialize_pane(workspace, &center_pane, cx);
+        cx.subscribe(&workspace_handle, {
+            move |workspace, _, event, cx| {
+                if let workspace::Event::PaneAdded(pane) = event {
+                    initialize_pane(workspace, pane, cx);
                 }
-            })
-            .detach();
+            }
+        })
+        .detach();
 
-            cx.emit(workspace::Event::PaneAdded(workspace.active_pane().clone()));
+        //     cx.emit(workspace2::Event::PaneAdded(
+        //         workspace.active_pane().clone(),
+        //     ));
+
+        //     let collab_titlebar_item =
+        //         cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
+        //     workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
+
+        let copilot =
+            cx.new_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
+        let diagnostic_summary =
+            cx.new_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
+        let activity_indicator =
+            activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
+        let active_buffer_language =
+            cx.new_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
+        let vim_mode_indicator = cx.new_view(|cx| vim::ModeIndicator::new(cx));
+        let feedback_button =
+            cx.new_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace));
+        let cursor_position = cx.new_view(|_| editor::items::CursorPosition::new());
+        workspace.status_bar().update(cx, |status_bar, cx| {
+            status_bar.add_left_item(diagnostic_summary, cx);
+            status_bar.add_left_item(activity_indicator, cx);
+            status_bar.add_right_item(feedback_button, cx);
+            // status_bar.add_right_item(copilot, cx);
+            status_bar.add_right_item(copilot, cx);
+            status_bar.add_right_item(active_buffer_language, cx);
+            status_bar.add_right_item(vim_mode_indicator, cx);
+            status_bar.add_right_item(cursor_position, cx);
+        });
 
-            let collab_titlebar_item =
-                cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
-            workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
+        auto_update::notify_of_any_new_update(cx);
 
-            let copilot =
-                cx.add_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
-            let diagnostic_summary =
-                cx.add_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
-            let activity_indicator = activity_indicator::ActivityIndicator::new(
-                workspace,
-                app_state.languages.clone(),
-                cx,
-            );
-            let active_buffer_language =
-                cx.add_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
-            let vim_mode_indicator = cx.add_view(|cx| vim::ModeIndicator::new(cx));
-            let feedback_button = cx.add_view(|_| {
-                feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace)
-            });
-            let cursor_position = cx.add_view(|_| editor::items::CursorPosition::new());
-            workspace.status_bar().update(cx, |status_bar, cx| {
-                status_bar.add_left_item(diagnostic_summary, cx);
-                status_bar.add_left_item(activity_indicator, cx);
-
-                status_bar.add_right_item(feedback_button, cx);
-                status_bar.add_right_item(copilot, cx);
-                status_bar.add_right_item(active_buffer_language, cx);
-                status_bar.add_right_item(vim_mode_indicator, cx);
-                status_bar.add_right_item(cursor_position, cx);
-            });
+        vim::observe_keystrokes(cx);
 
-            auto_update::notify_of_any_new_update(cx.weak_handle(), cx);
+        let handle = cx.view().downgrade();
+        cx.on_window_should_close(move |cx| {
+            handle
+                .update(cx, |workspace, cx| {
+                    workspace.close_window(&Default::default(), cx);
+                    false
+                })
+                .unwrap_or(true)
+        });
 
-            vim::observe_keystrokes(cx);
+        cx.spawn(|workspace_handle, mut cx| async move {
+            let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
+            let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
+            let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
+            let channels_panel =
+                collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
+            let chat_panel =
+                collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
+            let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
+                workspace_handle.clone(),
+                cx.clone(),
+            );
+            let (
+                project_panel,
+                terminal_panel,
+                assistant_panel,
+                channels_panel,
+                chat_panel,
+                notification_panel,
+            ) = futures::try_join!(
+                project_panel,
+                terminal_panel,
+                assistant_panel,
+                channels_panel,
+                chat_panel,
+                notification_panel,
+            )?;
+
+            workspace_handle.update(&mut cx, |workspace, cx| {
+                workspace.add_panel(project_panel, cx);
+                workspace.add_panel(terminal_panel, cx);
+                workspace.add_panel(assistant_panel, cx);
+                workspace.add_panel(channels_panel, cx);
+                workspace.add_panel(chat_panel, cx);
+                workspace.add_panel(notification_panel, cx);
+
+                // if !was_deserialized
+                //     && workspace
+                //         .project()
+                //         .read(cx)
+                //         .visible_worktrees(cx)
+                //         .any(|tree| {
+                //             tree.read(cx)
+                //                 .root_entry()
+                //                 .map_or(false, |entry| entry.is_dir())
+                //         })
+                // {
+                //     workspace.toggle_dock(project_panel_position, cx);
+                // }
+                cx.focus_self();
+            })
+        })
+        .detach();
 
-            cx.on_window_should_close(|workspace, cx| {
-                if let Some(task) = workspace.close(&Default::default(), cx) {
-                    task.detach_and_log_err(cx);
+        workspace
+            .register_action(about)
+            .register_action(|_, _: &Hide, cx| {
+                cx.hide();
+            })
+            .register_action(|_, _: &HideOthers, cx| {
+                cx.hide_other_apps();
+            })
+            .register_action(|_, _: &ShowAll, cx| {
+                cx.unhide_other_apps();
+            })
+            .register_action(|_, _: &Minimize, cx| {
+                cx.minimize_window();
+            })
+            .register_action(|_, _: &Zoom, cx| {
+                cx.zoom_window();
+            })
+            .register_action(|_, _: &ToggleFullScreen, cx| {
+                cx.toggle_full_screen();
+            })
+            .register_action(quit)
+            .register_action(|_, action: &OpenZedURL, cx| {
+                cx.global::<Arc<OpenListener>>()
+                    .open_urls(&[action.url.clone()])
+            })
+            .register_action(|_, action: &OpenBrowser, cx| cx.open_url(&action.url))
+            .register_action(move |_, _: &IncreaseBufferFontSize, cx| {
+                theme::adjust_font_size(cx, |size| *size += px(1.0))
+            })
+            .register_action(move |_, _: &DecreaseBufferFontSize, cx| {
+                theme::adjust_font_size(cx, |size| *size -= px(1.0))
+            })
+            .register_action(move |_, _: &ResetBufferFontSize, cx| theme::reset_font_size(cx))
+            .register_action(|_, _: &install_cli::Install, cx| {
+                cx.spawn(|_, cx| async move {
+                    install_cli::install_cli(cx.deref())
+                        .await
+                        .context("error creating CLI symlink")
+                })
+                .detach_and_log_err(cx);
+            })
+            .register_action(|workspace, _: &OpenLog, cx| {
+                open_log_file(workspace, cx);
+            })
+            .register_action(|workspace, _: &OpenLicenses, cx| {
+                open_bundled_file(
+                    workspace,
+                    asset_str::<Assets>("licenses.md"),
+                    "Open Source License Attribution",
+                    "Markdown",
+                    cx,
+                );
+            })
+            .register_action(
+                move |workspace: &mut Workspace,
+                      _: &OpenTelemetryLog,
+                      cx: &mut ViewContext<Workspace>| {
+                    open_telemetry_log_file(workspace, cx);
+                },
+            )
+            .register_action(
+                move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
+                    create_and_open_local_file(&paths::KEYMAP, cx, Default::default)
+                        .detach_and_log_err(cx);
+                },
+            )
+            .register_action(
+                move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
+                    create_and_open_local_file(&paths::SETTINGS, cx, || {
+                        settings::initial_user_settings_content().as_ref().into()
+                    })
+                    .detach_and_log_err(cx);
+                },
+            )
+            .register_action(open_local_settings_file)
+            .register_action(
+                move |workspace: &mut Workspace,
+                      _: &OpenDefaultKeymap,
+                      cx: &mut ViewContext<Workspace>| {
+                    open_bundled_file(
+                        workspace,
+                        settings::default_keymap(),
+                        "Default Key Bindings",
+                        "JSON",
+                        cx,
+                    );
+                },
+            )
+            .register_action(
+                move |workspace: &mut Workspace,
+                      _: &OpenDefaultSettings,
+                      cx: &mut ViewContext<Workspace>| {
+                    open_bundled_file(
+                        workspace,
+                        settings::default_settings(),
+                        "Default Settings",
+                        "JSON",
+                        cx,
+                    );
+                },
+            )
+            //todo!()
+            // cx.add_action({
+            //     move |workspace: &mut Workspace, _: &DebugElements, cx: &mut ViewContext<Workspace>| {
+            //         let app_state = workspace.app_state().clone();
+            //         let markdown = app_state.languages.language_for_name("JSON");
+            //         let window = cx.window();
+            //         cx.spawn(|workspace, mut cx| async move {
+            //             let markdown = markdown.await.log_err();
+            //             let content = to_string_pretty(&window.debug_elements(&cx).ok_or_else(|| {
+            //                 anyhow!("could not debug elements for window {}", window.id())
+            //             })?)
+            //             .unwrap();
+            //             workspace
+            //                 .update(&mut cx, |workspace, cx| {
+            //                     workspace.with_local_workspace(cx, move |workspace, cx| {
+            //                         let project = workspace.project().clone();
+            //                         let buffer = project
+            //                             .update(cx, |project, cx| {
+            //                                 project.create_buffer(&content, markdown, cx)
+            //                             })
+            //                             .expect("creating buffers on a local workspace always succeeds");
+            //                         let buffer = cx.add_model(|cx| {
+            //                             MultiBuffer::singleton(buffer, cx)
+            //                                 .with_title("Debug Elements".into())
+            //                         });
+            //                         workspace.add_item(
+            //                             Box::new(cx.add_view(|cx| {
+            //                                 Editor::for_multibuffer(buffer, Some(project.clone()), cx)
+            //                             })),
+            //                             cx,
+            //                         );
+            //                     })
+            //                 })?
+            //                 .await
+            //         })
+            //         .detach_and_log_err(cx);
+            //     }
+            // });
+            // .register_action(
+            //     |workspace: &mut Workspace,
+            //      _: &project_panel::ToggleFocus,
+            //      cx: &mut ViewContext<Workspace>| {
+            //         workspace.toggle_panel_focus::<ProjectPanel>(cx);
+            //     },
+            // );
+            // cx.add_action(
+            //     |workspace: &mut Workspace,
+            //      _: &collab_ui::collab_panel::ToggleFocus,
+            //      cx: &mut ViewContext<Workspace>| {
+            //         workspace.toggle_panel_focus::<collab_ui::collab_panel::CollabPanel>(cx);
+            //     },
+            // );
+            // cx.add_action(
+            //     |workspace: &mut Workspace,
+            //      _: &collab_ui::chat_panel::ToggleFocus,
+            //      cx: &mut ViewContext<Workspace>| {
+            //         workspace.toggle_panel_focus::<collab_ui::chat_panel::ChatPanel>(cx);
+            //     },
+            // );
+            // cx.add_action(
+            //     |workspace: &mut Workspace,
+            //      _: &collab_ui::notification_panel::ToggleFocus,
+            //      cx: &mut ViewContext<Workspace>| {
+            //         workspace.toggle_panel_focus::<collab_ui::notification_panel::NotificationPanel>(cx);
+            //     },
+            // );
+            // cx.add_action(
+            //     |workspace: &mut Workspace,
+            //      _: &terminal_panel::ToggleFocus,
+            //      cx: &mut ViewContext<Workspace>| {
+            //         workspace.toggle_panel_focus::<TerminalPanel>(cx);
+            //     },
+            // );
+            .register_action({
+                let app_state = Arc::downgrade(&app_state);
+                move |_, _: &NewWindow, cx| {
+                    if let Some(app_state) = app_state.upgrade() {
+                        open_new(&app_state, cx, |workspace, cx| {
+                            Editor::new_file(workspace, &Default::default(), cx)
+                        })
+                        .detach();
+                    }
+                }
+            })
+            .register_action({
+                let app_state = Arc::downgrade(&app_state);
+                move |_, _: &NewFile, cx| {
+                    if let Some(app_state) = app_state.upgrade() {
+                        open_new(&app_state, cx, |workspace, cx| {
+                            Editor::new_file(workspace, &Default::default(), cx)
+                        })
+                        .detach();
+                    }
                 }
-                false
             });
-        })?;
 
-        let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
-        let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
-        let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
-        let channels_panel =
-            collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
-        let chat_panel =
-            collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
-        let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
-            workspace_handle.clone(),
-            cx.clone(),
-        );
-        let (
-            project_panel,
-            terminal_panel,
-            assistant_panel,
-            channels_panel,
-            chat_panel,
-            notification_panel,
-        ) = futures::try_join!(
-            project_panel,
-            terminal_panel,
-            assistant_panel,
-            channels_panel,
-            chat_panel,
-            notification_panel,
-        )?;
-        workspace_handle.update(&mut cx, |workspace, cx| {
-            let project_panel_position = project_panel.position(cx);
-            workspace.add_panel_with_extra_event_handler(
-                project_panel,
-                cx,
-                |workspace, _, event, cx| match event {
-                    project_panel::Event::NewSearchInDirectory { dir_entry } => {
-                        search::ProjectSearchView::new_search_in_directory(workspace, dir_entry, cx)
-                    }
-                    project_panel::Event::ActivatePanel => {
-                        workspace.focus_panel::<ProjectPanel>(cx);
-                    }
-                    _ => {}
-                },
-            );
-            workspace.add_panel(terminal_panel, cx);
-            workspace.add_panel(assistant_panel, cx);
-            workspace.add_panel(channels_panel, cx);
-            workspace.add_panel(chat_panel, cx);
-            workspace.add_panel(notification_panel, cx);
-
-            if !was_deserialized
-                && workspace
-                    .project()
-                    .read(cx)
-                    .visible_worktrees(cx)
-                    .any(|tree| {
-                        tree.read(cx)
-                            .root_entry()
-                            .map_or(false, |entry| entry.is_dir())
-                    })
-            {
-                workspace.toggle_dock(project_panel_position, cx);
-            }
-            cx.focus_self();
-        })?;
-        Ok(())
+        workspace.focus_handle(cx).focus(cx);
+        //todo!()
+        // load_default_keymap(cx);
     })
+    .detach();
 }
 
-pub fn build_window_options(
-    bounds: Option<WindowBounds>,
-    display: Option<Uuid>,
-    platform: &dyn Platform,
-) -> WindowOptions<'static> {
-    let bounds = bounds.unwrap_or(WindowBounds::Maximized);
-    let screen = display.and_then(|display| platform.screen_by_id(display));
+fn initialize_pane(workspace: &mut Workspace, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
+    pane.update(cx, |pane, cx| {
+        pane.toolbar().update(cx, |toolbar, cx| {
+            let breadcrumbs = cx.new_view(|_| Breadcrumbs::new());
+            toolbar.add_item(breadcrumbs, cx);
+            let buffer_search_bar = cx.new_view(search::BufferSearchBar::new);
+            toolbar.add_item(buffer_search_bar.clone(), cx);
+
+            let quick_action_bar =
+                cx.new_view(|_| QuickActionBar::new(buffer_search_bar, workspace));
+            toolbar.add_item(quick_action_bar, cx);
+            let diagnostic_editor_controls = cx.new_view(|_| diagnostics::ToolbarControls::new());
+            toolbar.add_item(diagnostic_editor_controls, cx);
+            let project_search_bar = cx.new_view(|_| ProjectSearchBar::new());
+            toolbar.add_item(project_search_bar, cx);
+            let lsp_log_item = cx.new_view(|_| language_tools::LspLogToolbarItemView::new());
+            toolbar.add_item(lsp_log_item, cx);
+            let syntax_tree_item =
+                cx.new_view(|_| language_tools::SyntaxTreeToolbarItemView::new());
+            toolbar.add_item(syntax_tree_item, cx);
+        })
+    });
+}
 
-    WindowOptions {
-        titlebar: Some(TitlebarOptions {
-            title: None,
-            appears_transparent: true,
-            traffic_light_position: Some(vec2f(8., 8.)),
-        }),
-        center: false,
-        focus: false,
-        show: false,
-        kind: WindowKind::Normal,
-        is_movable: true,
-        bounds,
-        screen,
+fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
+    use std::fmt::Write as _;
+
+    let app_name = cx.global::<ReleaseChannel>().display_name();
+    let version = env!("CARGO_PKG_VERSION");
+    let mut message = format!("{app_name} {version}");
+    if let Some(sha) = cx.try_global::<AppCommitSha>() {
+        write!(&mut message, "\n\n{}", sha.0).unwrap();
     }
+
+    let prompt = cx.prompt(PromptLevel::Info, &message, &["OK"]);
+    cx.foreground_executor()
+        .spawn(async {
+            prompt.await.ok();
+        })
+        .detach();
 }
 
-fn quit(_: &Quit, cx: &mut gpui::AppContext) {
-    let should_confirm = settings::get::<WorkspaceSettings>(cx).confirm_quit;
-    cx.spawn(|mut cx| async move {
-        let mut workspace_windows = cx
-            .windows()
-            .into_iter()
-            .filter_map(|window| window.downcast::<Workspace>())
-            .collect::<Vec<_>>();
+fn quit(_: &mut Workspace, _: &Quit, cx: &mut gpui::ViewContext<Workspace>) {
+    let should_confirm = WorkspaceSettings::get_global(cx).confirm_quit;
+    cx.spawn(|_, mut cx| async move {
+        let mut workspace_windows = cx.update(|_, cx| {
+            cx.windows()
+                .into_iter()
+                .filter_map(|window| window.downcast::<Workspace>())
+                .collect::<Vec<_>>()
+        })?;
 
         // If multiple windows have unsaved changes, and need a save prompt,
         // prompt in the active window before switching to a different window.
-        workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false));
-
-        if let (true, Some(window)) = (should_confirm, workspace_windows.first().copied()) {
-            let answer = window.prompt(
-                PromptLevel::Info,
-                "Are you sure you want to quit?",
-                &["Quit", "Cancel"],
-                &mut cx,
-            );
+        cx.update(|_, cx| {
+            workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false));
+        })
+        .log_err();
+
+        if let (true, Some(_)) = (should_confirm, workspace_windows.first().copied()) {
+            let answer = cx
+                .update(|_, cx| {
+                    cx.prompt(
+                        PromptLevel::Info,
+                        "Are you sure you want to quit?",
+                        &["Quit", "Cancel"],
+                    )
+                })
+                .log_err();
 
-            if let Some(mut answer) = answer {
-                let answer = answer.next().await;
+            if let Some(answer) = answer {
+                let answer = answer.await.ok();
                 if answer != Some(0) {
                     return Ok(());
                 }
@@ -477,29 +489,27 @@ fn quit(_: &Quit, cx: &mut gpui::AppContext) {
 
         // If the user cancels any save prompt, then keep the app open.
         for window in workspace_windows {
-            if let Some(should_close) = window.update_root(&mut cx, |workspace, cx| {
-                workspace.prepare_to_close(true, cx)
-            }) {
+            if let Some(should_close) = window
+                .update(&mut cx, |workspace, cx| {
+                    workspace.prepare_to_close(true, cx)
+                })
+                .log_err()
+            {
                 if !should_close.await? {
                     return Ok(());
                 }
             }
         }
-        cx.platform().quit();
+        cx.update(|_, cx| {
+            cx.quit();
+        })?;
         anyhow::Ok(())
     })
     .detach_and_log_err(cx);
 }
 
-fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
-    let app_name = cx.global::<ReleaseChannel>().display_name();
-    let version = env!("CARGO_PKG_VERSION");
-    cx.prompt(PromptLevel::Info, &format!("{app_name} {version}"), &["OK"]);
-}
-
 fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
     const MAX_LINES: usize = 1000;
-
     workspace
         .with_local_workspace(cx, move |workspace, cx| {
             let fs = workspace.app_state().fs.clone();
@@ -531,12 +541,12 @@ fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
                             .expect("creating buffers on a local workspace always succeeds");
                         buffer.update(cx, |buffer, cx| buffer.edit([(0..0, log)], None, cx));
 
-                        let buffer = cx.add_model(|cx| {
+                        let buffer = cx.new_model(|cx| {
                             MultiBuffer::singleton(buffer, cx).with_title("Log".into())
                         });
                         workspace.add_item(
                             Box::new(
-                                cx.add_view(|cx| {
+                                cx.new_view(|cx| {
                                     Editor::for_multibuffer(buffer, Some(project), cx)
                                 }),
                             ),
@@ -550,37 +560,28 @@ fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
         .detach();
 }
 
-pub fn load_default_keymap(cx: &mut AppContext) {
-    for path in ["keymaps/default.json", "keymaps/vim.json"] {
-        KeymapFile::load_asset(path, cx).unwrap();
-    }
-
-    if let Some(asset_path) = settings::get::<BaseKeymap>(cx).asset_path() {
-        KeymapFile::load_asset(asset_path, cx).unwrap();
-    }
-}
-
 pub fn handle_keymap_file_changes(
     mut user_keymap_file_rx: mpsc::UnboundedReceiver<String>,
     cx: &mut AppContext,
 ) {
-    cx.spawn(move |mut cx| async move {
-        let mut settings_subscription = None;
+    cx.spawn(move |cx| async move {
+        //  let mut settings_subscription = None;
         while let Some(user_keymap_content) = user_keymap_file_rx.next().await {
-            if let Ok(keymap_content) = KeymapFile::parse(&user_keymap_content) {
-                cx.update(|cx| reload_keymaps(cx, &keymap_content));
-
-                let mut old_base_keymap = cx.read(|cx| *settings::get::<BaseKeymap>(cx));
-                drop(settings_subscription);
-                settings_subscription = Some(cx.update(|cx| {
-                    cx.observe_global::<SettingsStore, _>(move |cx| {
-                        let new_base_keymap = *settings::get::<BaseKeymap>(cx);
-                        if new_base_keymap != old_base_keymap {
-                            old_base_keymap = new_base_keymap.clone();
-                            reload_keymaps(cx, &keymap_content);
-                        }
-                    })
-                }));
+            if let Some(keymap_content) = KeymapFile::parse(&user_keymap_content).log_err() {
+                cx.update(|cx| reload_keymaps(cx, &keymap_content)).ok();
+
+                // todo!()
+                // let mut old_base_keymap = cx.read(|cx| *settings::get::<BaseKeymap>(cx));
+                // drop(settings_subscription);
+                // settings_subscription = Some(cx.update(|cx| {
+                //     cx.observe_global::<SettingsStore, _>(move |cx| {
+                //         let new_base_keymap = *settings::get::<BaseKeymap>(cx);
+                //         if new_base_keymap != old_base_keymap {
+                //             old_base_keymap = new_base_keymap.clone();
+                //             reload_keymaps(cx, &keymap_content);
+                //         }
+                //     })
+                // }));
             }
         }
     })

crates/zed2/Cargo.toml 🔗

@@ -1,192 +0,0 @@
-[package]
-description = "The fast, collaborative code editor."
-edition = "2021"
-name = "zed2"
-version = "2.0.0"
-publish = false
-
-[lib]
-name = "zed2"
-path = "src/zed2.rs"
-doctest = false
-
-[[bin]]
-name = "zed2"
-path = "src/main.rs"
-
-[dependencies]
-ai = { package = "ai2", path = "../ai2"}
-audio = { package = "audio2", path = "../audio2" }
-activity_indicator = { package = "activity_indicator2", path = "../activity_indicator2"}
-auto_update = { package = "auto_update2", path = "../auto_update2" }
-breadcrumbs = { package = "breadcrumbs2", path = "../breadcrumbs2" }
-call = { package = "call2", path = "../call2" }
-channel = { package = "channel2", path = "../channel2" }
-cli = { path = "../cli" }
-collab_ui = { package = "collab_ui2", path = "../collab_ui2" }
-collections = { path = "../collections" }
-command_palette = { package="command_palette2", path = "../command_palette2" }
-# component_test = { path = "../component_test" }
-client = { package = "client2", path = "../client2" }
-# clock = { path = "../clock" }
-copilot = { package = "copilot2", path = "../copilot2" }
-copilot_button = { package = "copilot_button2", path = "../copilot_button2" }
-diagnostics = { package = "diagnostics2", path = "../diagnostics2" }
-db = { package = "db2", path = "../db2" }
-editor = { package="editor2", path = "../editor2" }
-feedback = { package="feedback2", path = "../feedback2" }
-file_finder = { package="file_finder2", path = "../file_finder2" }
-search = { package = "search2", path = "../search2" }
-fs = { package = "fs2", path = "../fs2" }
-fsevent = { path = "../fsevent" }
-go_to_line = { package = "go_to_line2", path = "../go_to_line2" }
-gpui = { package = "gpui2", path = "../gpui2" }
-install_cli = { package = "install_cli2", path = "../install_cli2" }
-journal = { package = "journal2", path = "../journal2" }
-language = { package = "language2", path = "../language2" }
-language_selector = { package = "language_selector2", path = "../language_selector2" }
-lsp = { package = "lsp2", path = "../lsp2" }
-menu = { package = "menu2", path = "../menu2" }
-language_tools = { package = "language_tools2", path = "../language_tools2" }
-node_runtime = { path = "../node_runtime" }
-notifications = { package = "notifications2", path = "../notifications2" }
-assistant = { package = "assistant2", path = "../assistant2" }
-outline = { package = "outline2", path = "../outline2" }
-# plugin_runtime = { path = "../plugin_runtime",optional = true }
-project = { package = "project2", path = "../project2" }
-project_panel = { package = "project_panel2", path = "../project_panel2" }
-project_symbols = { package = "project_symbols2", path = "../project_symbols2" }
-quick_action_bar = { package = "quick_action_bar2", path = "../quick_action_bar2" }
-recent_projects = { package = "recent_projects2", path = "../recent_projects2" }
-rope = { package = "rope2", path = "../rope2"}
-rpc = { package = "rpc2", path = "../rpc2" }
-settings = { package = "settings2", path = "../settings2" }
-feature_flags = { package = "feature_flags2", path = "../feature_flags2" }
-sum_tree = { path = "../sum_tree" }
-shellexpand = "2.1.0"
-text = { package = "text2", path = "../text2" }
-terminal_view = { package = "terminal_view2", path = "../terminal_view2" }
-theme = { package = "theme2", path = "../theme2" }
-theme_selector = { package = "theme_selector2", path = "../theme_selector2" }
-util = { path = "../util" }
-semantic_index = { package = "semantic_index2", path = "../semantic_index2" }
-vim = { package = "vim2", path = "../vim2" }
-workspace = { package = "workspace2", path = "../workspace2" }
-welcome = { package = "welcome2", path = "../welcome2" }
-zed_actions = {package = "zed_actions2", path = "../zed_actions2"}
-anyhow.workspace = true
-async-compression.workspace = true
-async-tar = "0.4.2"
-async-recursion = "0.3"
-async-trait.workspace = true
-backtrace = "0.3"
-chrono = "0.4"
-ctor.workspace = true
-env_logger.workspace = true
-futures.workspace = true
-ignore = "0.4"
-image = "0.23"
-indexmap = "1.6.2"
-isahc.workspace = true
-lazy_static.workspace = true
-libc = "0.2"
-log.workspace = true
-num_cpus = "1.13.0"
-parking_lot.workspace = true
-postage.workspace = true
-rand.workspace = true
-regex.workspace = true
-rsa = "0.4"
-rust-embed.workspace = true
-serde.workspace = true
-serde_derive.workspace = true
-serde_json.workspace = true
-schemars.workspace = true
-simplelog = "0.9"
-smallvec.workspace = true
-smol.workspace = true
-tempdir.workspace = true
-thiserror.workspace = true
-tiny_http = "0.8"
-toml.workspace = true
-tree-sitter.workspace = true
-tree-sitter-bash.workspace = true
-tree-sitter-c.workspace = true
-tree-sitter-cpp.workspace = true
-tree-sitter-css.workspace = true
-tree-sitter-elixir.workspace = true
-tree-sitter-elm.workspace = true
-tree-sitter-embedded-template.workspace = true
-tree-sitter-glsl.workspace = true
-tree-sitter-go.workspace = true
-tree-sitter-heex.workspace = true
-tree-sitter-json.workspace = true
-tree-sitter-rust.workspace = true
-tree-sitter-markdown.workspace = true
-tree-sitter-python.workspace = true
-tree-sitter-toml.workspace = true
-tree-sitter-typescript.workspace = true
-tree-sitter-ruby.workspace = true
-tree-sitter-html.workspace = true
-tree-sitter-php.workspace = true
-tree-sitter-scheme.workspace = true
-tree-sitter-svelte.workspace = true
-tree-sitter-racket.workspace = true
-tree-sitter-yaml.workspace = true
-tree-sitter-lua.workspace = true
-tree-sitter-nix.workspace = true
-tree-sitter-nu.workspace = true
-tree-sitter-vue.workspace = true
-tree-sitter-uiua.workspace = true
-
-url = "2.2"
-urlencoding = "2.1.2"
-uuid.workspace = true
-
-[dev-dependencies]
-call = { package = "call2", path = "../call2", features = ["test-support"] }
-# client = { path = "../client", features = ["test-support"] }
-# editor = { path = "../editor", features = ["test-support"] }
-# gpui = { path = "../gpui", features = ["test-support"] }
-gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
-language = { package = "language2", path = "../language2", features = ["test-support"] }
-# lsp = { path = "../lsp", features = ["test-support"] }
-project = { package = "project2", path = "../project2", features = ["test-support"] }
-# rpc = { path = "../rpc", features = ["test-support"] }
-# settings = { path = "../settings", features = ["test-support"] }
-text = { package = "text2", path = "../text2", features = ["test-support"] }
-# util = { path = "../util", features = ["test-support"] }
-# workspace = { path = "../workspace", features = ["test-support"] }
-unindent.workspace = true
-
-[package.metadata.bundle-dev]
-icon = ["resources/app-icon-preview@2x.png", "resources/app-icon-preview.png"]
-identifier = "dev.zed.Zed-Dev"
-name = "Zed Dev"
-osx_minimum_system_version = "10.15.7"
-osx_info_plist_exts = ["resources/info/*"]
-osx_url_schemes = ["zed-dev"]
-
-[package.metadata.bundle-nightly]
-icon = ["resources/app-icon-nightly@2x.png", "resources/app-icon-nightly.png"]
-identifier = "dev.zed.Zed-Nightly"
-name = "Zed Nightly"
-osx_minimum_system_version = "10.15.7"
-osx_info_plist_exts = ["resources/info/*"]
-osx_url_schemes = ["zed-nightly"]
-
-[package.metadata.bundle-preview]
-icon = ["resources/app-icon-preview@2x.png", "resources/app-icon-preview.png"]
-identifier = "dev.zed.Zed-Preview"
-name = "Zed Preview"
-osx_minimum_system_version = "10.15.7"
-osx_info_plist_exts = ["resources/info/*"]
-osx_url_schemes = ["zed-preview"]
-
-[package.metadata.bundle-stable]
-icon = ["resources/app-icon@2x.png", "resources/app-icon.png"]
-identifier = "dev.zed.Zed"
-name = "Zed"
-osx_minimum_system_version = "10.15.7"
-osx_info_plist_exts = ["resources/info/*"]
-osx_url_schemes = ["zed"]

crates/zed2/build.rs 🔗

@@ -1,44 +0,0 @@
-use std::process::Command;
-
-fn main() {
-    println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.15.7");
-
-    println!("cargo:rerun-if-env-changed=ZED_BUNDLE");
-    if std::env::var("ZED_BUNDLE").ok().as_deref() == Some("true") {
-        // Find WebRTC.framework in the Frameworks folder when running as part of an application bundle.
-        println!("cargo:rustc-link-arg=-Wl,-rpath,@executable_path/../Frameworks");
-    } else {
-        // Find WebRTC.framework as a sibling of the executable when running outside of an application bundle.
-        println!("cargo:rustc-link-arg=-Wl,-rpath,@executable_path");
-    }
-
-    // Weakly link ReplayKit to ensure Zed can be used on macOS 10.15+.
-    println!("cargo:rustc-link-arg=-Wl,-weak_framework,ReplayKit");
-
-    // Seems to be required to enable Swift concurrency
-    println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/lib/swift");
-
-    // Register exported Objective-C selectors, protocols, etc
-    println!("cargo:rustc-link-arg=-Wl,-ObjC");
-
-    // Populate git sha environment variable if git is available
-    println!("cargo:rerun-if-changed=.git/logs/HEAD");
-    if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
-        if output.status.success() {
-            let git_sha = String::from_utf8_lossy(&output.stdout);
-            let git_sha = git_sha.trim();
-
-            println!("cargo:rustc-env=ZED_COMMIT_SHA={git_sha}");
-
-            if let Ok(build_profile) = std::env::var("PROFILE") {
-                if build_profile == "release" {
-                    // This is currently the best way to make `cargo build ...`'s build script
-                    // to print something to stdout without extra verbosity.
-                    println!(
-                        "cargo:warning=Info: using '{git_sha}' hash for ZED_COMMIT_SHA env var"
-                    );
-                }
-            }
-        }
-    }
-}

crates/zed2/resources/info/DocumentTypes.plist 🔗

@@ -1,62 +0,0 @@
-<key>CFBundleDocumentTypes</key>
-<array>
-    <dict>
-        <key>CFBundleTypeIconFile</key>
-        <string>Document</string>
-        <key>CFBundleTypeRole</key>
-        <string>Editor</string>
-        <key>LSHandlerRank</key>
-        <string>Alternate</string>
-        <key>LSItemContentTypes</key>
-        <array>
-            <string>public.text</string>
-            <string>public.plain-text</string>
-            <string>public.utf8-plain-text</string>
-        </array>
-    </dict>
-    <dict>
-        <key>CFBundleTypeIconFile</key>
-        <string>Document</string>
-        <key>CFBundleTypeName</key>
-        <string>Zed Text Document</string>
-        <key>CFBundleTypeRole</key>
-        <string>Editor</string>
-        <key>CFBundleTypeOSTypes</key>
-        <array>
-            <string>****</string>
-        </array>
-        <key>LSHandlerRank</key>
-        <string>Default</string>
-        <key>CFBundleTypeExtensions</key>
-        <array>
-            <string>Gemfile</string>
-            <string>c</string>
-            <string>c++</string>
-            <string>cc</string>
-            <string>cpp</string>
-            <string>css</string>
-            <string>erb</string>
-            <string>ex</string>
-            <string>exs</string>
-            <string>go</string>
-            <string>h</string>
-            <string>h++</string>
-            <string>hh</string>
-            <string>hpp</string>
-            <string>html</string>
-            <string>js</string>
-            <string>json</string>
-            <string>jsx</string>
-            <string>md</string>
-            <string>py</string>
-            <string>rb</string>
-            <string>rkt</string>
-            <string>rs</string>
-            <string>scm</string>
-            <string>toml</string>
-            <string>ts</string>
-            <string>tsx</string>
-            <string>txt</string>
-        </array>
-    </dict>
-</array>

crates/zed2/resources/info/Permissions.plist 🔗

@@ -1,24 +0,0 @@
-<key>NSSystemAdministrationUsageDescription</key>
-<string>The operation being performed by a program in Zed requires elevated permission.</string>
-<key>NSAppleEventsUsageDescription</key>
-<string>An application in Zed wants to use AppleScript.</string>
-<key>NSBluetoothAlwaysUsageDescription</key>
-<string>An application in Zed wants to use Bluetooth.</string>
-<key>NSCalendarsUsageDescription</key>
-<string>An application in Zed wants to use Calendar data.</string>
-<key>NSCameraUsageDescription</key>
-<string>An application in Zed wants to use the camera.</string>
-<key>NSContactsUsageDescription</key>
-<string>An application in Zed wants to use your contacts.</string>
-<key>NSLocationAlwaysUsageDescription</key>
-<string>An application in Zed wants to use your location information, even in the background.</string>
-<key>NSLocationUsageDescription</key>
-<string>An application in Zed wants to use your location information.</string>
-<key>NSLocationWhenInUseUsageDescription</key>
-<string>An application in Zed wants to use your location information while active.</string>
-<key>NSMicrophoneUsageDescription</key>
-<string>An application in Zed wants to use your microphone.</string>
-<key>NSSpeechRecognitionUsageDescription</key>
-<string>An application in Zed wants to use speech recognition.</string>
-<key>NSRemindersUsageDescription</key>
-<string>An application in Zed wants to use your reminders.</string>

crates/zed2/resources/zed.entitlements 🔗

@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>com.apple.security.automation.apple-events</key>
-	<true/>
-	<key>com.apple.security.cs.allow-jit</key>
-	<true/>
-	<key>com.apple.security.device.audio-input</key>
-	<true/>
-	<key>com.apple.security.device.camera</key>
-	<true/>
-	<key>com.apple.security.personal-information.addressbook</key>
-	<true/>
-	<key>com.apple.security.personal-information.calendars</key>
-	<true/>
-	<key>com.apple.security.personal-information.location</key>
-	<true/>
-	<key>com.apple.security.personal-information.photos-library</key>
-	<true/>
-	<!-- <key>com.apple.security.cs.disable-library-validation</key>
-	<true/> -->
-</dict>
-</plist>

crates/zed2/src/assets.rs 🔗

@@ -1,35 +0,0 @@
-use anyhow::anyhow;
-
-use gpui::{AssetSource, Result, SharedString};
-use rust_embed::RustEmbed;
-
-#[derive(RustEmbed)]
-#[folder = "../../assets"]
-#[include = "fonts/**/*"]
-#[include = "icons/**/*"]
-#[include = "themes/**/*"]
-#[exclude = "themes/src/*"]
-#[include = "sounds/**/*"]
-#[include = "*.md"]
-#[exclude = "*.DS_Store"]
-pub struct Assets;
-
-impl AssetSource for Assets {
-    fn load(&self, path: &str) -> Result<std::borrow::Cow<[u8]>> {
-        Self::get(path)
-            .map(|f| f.data)
-            .ok_or_else(|| anyhow!("could not find asset at path \"{}\"", path))
-    }
-
-    fn list(&self, path: &str) -> Result<Vec<SharedString>> {
-        Ok(Self::iter()
-            .filter_map(|p| {
-                if p.starts_with(path) {
-                    Some(p.into())
-                } else {
-                    None
-                }
-            })
-            .collect())
-    }
-}

crates/zed2/src/languages.rs 🔗

@@ -1,299 +0,0 @@
-use anyhow::Context;
-use gpui::AppContext;
-pub use language::*;
-use node_runtime::NodeRuntime;
-use rust_embed::RustEmbed;
-use settings::Settings;
-use std::{borrow::Cow, str, sync::Arc};
-use util::{asset_str, paths::PLUGINS_DIR};
-
-use self::elixir::ElixirSettings;
-
-mod c;
-mod css;
-mod elixir;
-mod go;
-mod html;
-mod json;
-#[cfg(feature = "plugin_runtime")]
-mod language_plugin;
-mod lua;
-mod nu;
-mod php;
-mod python;
-mod ruby;
-mod rust;
-mod svelte;
-mod tailwind;
-mod typescript;
-mod uiua;
-mod vue;
-mod yaml;
-
-// 1. Add tree-sitter-{language} parser to zed crate
-// 2. Create a language directory in zed/crates/zed/src/languages and add the language to init function below
-// 3. Add config.toml to the newly created language directory using existing languages as a template
-// 4. Copy highlights from tree sitter repo for the language into a highlights.scm file.
-//      Note: github highlights take the last match while zed takes the first
-// 5. Add indents.scm, outline.scm, and brackets.scm to implement indent on newline, outline/breadcrumbs,
-//    and autoclosing brackets respectively
-// 6. If the language has injections add an injections.scm query file
-
-#[derive(RustEmbed)]
-#[folder = "src/languages"]
-#[exclude = "*.rs"]
-struct LanguageDir;
-
-pub fn init(
-    languages: Arc<LanguageRegistry>,
-    node_runtime: Arc<dyn NodeRuntime>,
-    cx: &mut AppContext,
-) {
-    ElixirSettings::register(cx);
-
-    let language = |name, grammar, adapters| {
-        languages.register(name, load_config(name), grammar, adapters, load_queries)
-    };
-
-    language("bash", tree_sitter_bash::language(), vec![]);
-    language(
-        "c",
-        tree_sitter_c::language(),
-        vec![Arc::new(c::CLspAdapter) as Arc<dyn LspAdapter>],
-    );
-    language(
-        "cpp",
-        tree_sitter_cpp::language(),
-        vec![Arc::new(c::CLspAdapter)],
-    );
-    language(
-        "css",
-        tree_sitter_css::language(),
-        vec![
-            Arc::new(css::CssLspAdapter::new(node_runtime.clone())),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-
-    match &ElixirSettings::get(None, cx).lsp {
-        elixir::ElixirLspSetting::ElixirLs => language(
-            "elixir",
-            tree_sitter_elixir::language(),
-            vec![
-                Arc::new(elixir::ElixirLspAdapter),
-                Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-            ],
-        ),
-        elixir::ElixirLspSetting::NextLs => language(
-            "elixir",
-            tree_sitter_elixir::language(),
-            vec![Arc::new(elixir::NextLspAdapter)],
-        ),
-        elixir::ElixirLspSetting::Local { path, arguments } => language(
-            "elixir",
-            tree_sitter_elixir::language(),
-            vec![Arc::new(elixir::LocalLspAdapter {
-                path: path.clone(),
-                arguments: arguments.clone(),
-            })],
-        ),
-    }
-
-    language(
-        "go",
-        tree_sitter_go::language(),
-        vec![Arc::new(go::GoLspAdapter)],
-    );
-    language(
-        "heex",
-        tree_sitter_heex::language(),
-        vec![
-            Arc::new(elixir::ElixirLspAdapter),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-    language(
-        "json",
-        tree_sitter_json::language(),
-        vec![Arc::new(json::JsonLspAdapter::new(
-            node_runtime.clone(),
-            languages.clone(),
-        ))],
-    );
-    language("markdown", tree_sitter_markdown::language(), vec![]);
-    language(
-        "python",
-        tree_sitter_python::language(),
-        vec![Arc::new(python::PythonLspAdapter::new(
-            node_runtime.clone(),
-        ))],
-    );
-    language(
-        "rust",
-        tree_sitter_rust::language(),
-        vec![Arc::new(rust::RustLspAdapter)],
-    );
-    language("toml", tree_sitter_toml::language(), vec![]);
-    language(
-        "tsx",
-        tree_sitter_typescript::language_tsx(),
-        vec![
-            Arc::new(typescript::TypeScriptLspAdapter::new(node_runtime.clone())),
-            Arc::new(typescript::EsLintLspAdapter::new(node_runtime.clone())),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-    language(
-        "typescript",
-        tree_sitter_typescript::language_typescript(),
-        vec![
-            Arc::new(typescript::TypeScriptLspAdapter::new(node_runtime.clone())),
-            Arc::new(typescript::EsLintLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-    language(
-        "javascript",
-        tree_sitter_typescript::language_tsx(),
-        vec![
-            Arc::new(typescript::TypeScriptLspAdapter::new(node_runtime.clone())),
-            Arc::new(typescript::EsLintLspAdapter::new(node_runtime.clone())),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-    language(
-        "html",
-        tree_sitter_html::language(),
-        vec![
-            Arc::new(html::HtmlLspAdapter::new(node_runtime.clone())),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-    language(
-        "ruby",
-        tree_sitter_ruby::language(),
-        vec![Arc::new(ruby::RubyLanguageServer)],
-    );
-    language(
-        "erb",
-        tree_sitter_embedded_template::language(),
-        vec![
-            Arc::new(ruby::RubyLanguageServer),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-    language("scheme", tree_sitter_scheme::language(), vec![]);
-    language("racket", tree_sitter_racket::language(), vec![]);
-    language(
-        "lua",
-        tree_sitter_lua::language(),
-        vec![Arc::new(lua::LuaLspAdapter)],
-    );
-    language(
-        "yaml",
-        tree_sitter_yaml::language(),
-        vec![Arc::new(yaml::YamlLspAdapter::new(node_runtime.clone()))],
-    );
-    language(
-        "svelte",
-        tree_sitter_svelte::language(),
-        vec![
-            Arc::new(svelte::SvelteLspAdapter::new(node_runtime.clone())),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-    language(
-        "php",
-        tree_sitter_php::language(),
-        vec![
-            Arc::new(php::IntelephenseLspAdapter::new(node_runtime.clone())),
-            Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
-        ],
-    );
-
-    language("elm", tree_sitter_elm::language(), vec![]);
-    language("glsl", tree_sitter_glsl::language(), vec![]);
-    language("nix", tree_sitter_nix::language(), vec![]);
-    language(
-        "nu",
-        tree_sitter_nu::language(),
-        vec![Arc::new(nu::NuLanguageServer {})],
-    );
-    language(
-        "vue",
-        tree_sitter_vue::language(),
-        vec![Arc::new(vue::VueLspAdapter::new(node_runtime))],
-    );
-    language(
-        "uiua",
-        tree_sitter_uiua::language(),
-        vec![Arc::new(uiua::UiuaLanguageServer {})],
-    );
-
-    if let Ok(children) = std::fs::read_dir(&*PLUGINS_DIR) {
-        for child in children {
-            if let Ok(child) = child {
-                let path = child.path();
-                let config_path = path.join("config.toml");
-                if let Ok(config) = std::fs::read(&config_path) {
-                    let config: LanguageConfig = toml::from_slice(&config).unwrap();
-                    if let Some(grammar_name) = config.grammar_name.clone() {
-                        languages.register_wasm(path.into(), grammar_name, config);
-                    }
-                }
-            }
-        }
-    }
-}
-
-#[cfg(any(test, feature = "test-support"))]
-pub async fn language(
-    name: &str,
-    grammar: tree_sitter::Language,
-    lsp_adapter: Option<Arc<dyn LspAdapter>>,
-) -> Arc<Language> {
-    Arc::new(
-        Language::new(load_config(name), Some(grammar))
-            .with_lsp_adapters(lsp_adapter.into_iter().collect())
-            .await
-            .with_queries(load_queries(name))
-            .unwrap(),
-    )
-}
-
-fn load_config(name: &str) -> LanguageConfig {
-    toml::from_slice(
-        &LanguageDir::get(&format!("{}/config.toml", name))
-            .unwrap()
-            .data,
-    )
-    .with_context(|| format!("failed to load config.toml for language {name:?}"))
-    .unwrap()
-}
-
-fn load_queries(name: &str) -> LanguageQueries {
-    LanguageQueries {
-        highlights: load_query(name, "/highlights"),
-        brackets: load_query(name, "/brackets"),
-        indents: load_query(name, "/indents"),
-        outline: load_query(name, "/outline"),
-        embedding: load_query(name, "/embedding"),
-        injections: load_query(name, "/injections"),
-        overrides: load_query(name, "/overrides"),
-    }
-}
-
-fn load_query(name: &str, filename_prefix: &str) -> Option<Cow<'static, str>> {
-    let mut result = None;
-    for path in LanguageDir::iter() {
-        if let Some(remainder) = path.strip_prefix(name) {
-            if remainder.starts_with(filename_prefix) {
-                let contents = asset_str::<LanguageDir>(path.as_ref());
-                match &mut result {
-                    None => result = Some(contents),
-                    Some(r) => r.to_mut().push_str(contents.as_ref()),
-                }
-            }
-        }
-    }
-    result
-}

crates/zed2/src/languages/bash/config.toml 🔗

@@ -1,9 +0,0 @@
-name = "Shell Script"
-path_suffixes = ["sh", "bash", "bashrc", "bash_profile", "bash_aliases", "bash_logout", "profile", "zsh", "zshrc", "zshenv", "zsh_profile", "zsh_aliases", "zsh_histfile", "zlogin", "zprofile"]
-line_comment = "# "
-first_line_pattern = "^#!.*\\b(?:ba|z)?sh\\b"
-brackets = [
-    { start = "[", end = "]", close = true, newline = false },
-    { start = "(", end = ")", close = true, newline = false },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
-]

crates/zed2/src/languages/bash/highlights.scm 🔗

@@ -1,59 +0,0 @@
-[
-  (string)
-  (raw_string)
-  (heredoc_body)
-  (heredoc_start)
-  (ansi_c_string)
-] @string
-
-(command_name) @function
-
-(variable_name) @property
-
-[
-  "case"
-  "do"
-  "done"
-  "elif"
-  "else"
-  "esac"
-  "export"
-  "fi"
-  "for"
-  "function"
-  "if"
-  "in"
-  "select"
-  "then"
-  "unset"
-  "until"
-  "while"
-  "local"
-  "declare"
-] @keyword
-
-(comment) @comment
-
-(function_definition name: (word) @function)
-
-(file_descriptor) @number
-
-[
-  (command_substitution)
-  (process_substitution)
-  (expansion)
-]@embedded
-
-[
-  "$"
-  "&&"
-  ">"
-  ">>"
-  "<"
-  "|"
-] @operator
-
-(
-  (command (_) @constant)
-  (#match? @constant "^-")
-)

crates/zed2/src/languages/c.rs 🔗

@@ -1,321 +0,0 @@
-use anyhow::{anyhow, Context, Result};
-use async_trait::async_trait;
-use futures::StreamExt;
-pub use language::*;
-use lsp::LanguageServerBinary;
-use smol::fs::{self, File};
-use std::{any::Any, path::PathBuf, sync::Arc};
-use util::{
-    fs::remove_matching,
-    github::{latest_github_release, GitHubLspBinaryVersion},
-    ResultExt,
-};
-
-pub struct CLspAdapter;
-
-#[async_trait]
-impl super::LspAdapter for CLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("clangd".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "clangd"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        let release = latest_github_release("clangd/clangd", false, delegate.http_client()).await?;
-        let asset_name = format!("clangd-mac-{}.zip", release.name);
-        let asset = release
-            .assets
-            .iter()
-            .find(|asset| asset.name == asset_name)
-            .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
-        let version = GitHubLspBinaryVersion {
-            name: release.name,
-            url: asset.browser_download_url.clone(),
-        };
-        Ok(Box::new(version) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
-        let zip_path = container_dir.join(format!("clangd_{}.zip", version.name));
-        let version_dir = container_dir.join(format!("clangd_{}", version.name));
-        let binary_path = version_dir.join("bin/clangd");
-
-        if fs::metadata(&binary_path).await.is_err() {
-            let mut response = delegate
-                .http_client()
-                .get(&version.url, Default::default(), true)
-                .await
-                .context("error downloading release")?;
-            let mut file = File::create(&zip_path).await?;
-            if !response.status().is_success() {
-                Err(anyhow!(
-                    "download failed with status {}",
-                    response.status().to_string()
-                ))?;
-            }
-            futures::io::copy(response.body_mut(), &mut file).await?;
-
-            let unzip_status = smol::process::Command::new("unzip")
-                .current_dir(&container_dir)
-                .arg(&zip_path)
-                .output()
-                .await?
-                .status;
-            if !unzip_status.success() {
-                Err(anyhow!("failed to unzip clangd archive"))?;
-            }
-
-            remove_matching(&container_dir, |entry| entry != version_dir).await;
-        }
-
-        Ok(LanguageServerBinary {
-            path: binary_path,
-            arguments: vec![],
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir)
-            .await
-            .map(|mut binary| {
-                binary.arguments = vec!["--help".into()];
-                binary
-            })
-    }
-
-    async fn label_for_completion(
-        &self,
-        completion: &lsp::CompletionItem,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        let label = completion
-            .label
-            .strip_prefix('•')
-            .unwrap_or(&completion.label)
-            .trim();
-
-        match completion.kind {
-            Some(lsp::CompletionItemKind::FIELD) if completion.detail.is_some() => {
-                let detail = completion.detail.as_ref().unwrap();
-                let text = format!("{} {}", detail, label);
-                let source = Rope::from(format!("struct S {{ {} }}", text).as_str());
-                let runs = language.highlight_text(&source, 11..11 + text.len());
-                return Some(CodeLabel {
-                    filter_range: detail.len() + 1..text.len(),
-                    text,
-                    runs,
-                });
-            }
-            Some(lsp::CompletionItemKind::CONSTANT | lsp::CompletionItemKind::VARIABLE)
-                if completion.detail.is_some() =>
-            {
-                let detail = completion.detail.as_ref().unwrap();
-                let text = format!("{} {}", detail, label);
-                let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
-                return Some(CodeLabel {
-                    filter_range: detail.len() + 1..text.len(),
-                    text,
-                    runs,
-                });
-            }
-            Some(lsp::CompletionItemKind::FUNCTION | lsp::CompletionItemKind::METHOD)
-                if completion.detail.is_some() =>
-            {
-                let detail = completion.detail.as_ref().unwrap();
-                let text = format!("{} {}", detail, label);
-                let runs = language.highlight_text(&Rope::from(text.as_str()), 0..text.len());
-                return Some(CodeLabel {
-                    filter_range: detail.len() + 1..text.rfind('(').unwrap_or(text.len()),
-                    text,
-                    runs,
-                });
-            }
-            Some(kind) => {
-                let highlight_name = match kind {
-                    lsp::CompletionItemKind::STRUCT
-                    | lsp::CompletionItemKind::INTERFACE
-                    | lsp::CompletionItemKind::CLASS
-                    | lsp::CompletionItemKind::ENUM => Some("type"),
-                    lsp::CompletionItemKind::ENUM_MEMBER => Some("variant"),
-                    lsp::CompletionItemKind::KEYWORD => Some("keyword"),
-                    lsp::CompletionItemKind::VALUE | lsp::CompletionItemKind::CONSTANT => {
-                        Some("constant")
-                    }
-                    _ => None,
-                };
-                if let Some(highlight_id) = language
-                    .grammar()
-                    .and_then(|g| g.highlight_id_for_name(highlight_name?))
-                {
-                    let mut label = CodeLabel::plain(label.to_string(), None);
-                    label.runs.push((
-                        0..label.text.rfind('(').unwrap_or(label.text.len()),
-                        highlight_id,
-                    ));
-                    return Some(label);
-                }
-            }
-            _ => {}
-        }
-        Some(CodeLabel::plain(label.to_string(), None))
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        kind: lsp::SymbolKind,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        let (text, filter_range, display_range) = match kind {
-            lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => {
-                let text = format!("void {} () {{}}", name);
-                let filter_range = 0..name.len();
-                let display_range = 5..5 + name.len();
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::STRUCT => {
-                let text = format!("struct {} {{}}", name);
-                let filter_range = 7..7 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::ENUM => {
-                let text = format!("enum {} {{}}", name);
-                let filter_range = 5..5 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::INTERFACE | lsp::SymbolKind::CLASS => {
-                let text = format!("class {} {{}}", name);
-                let filter_range = 6..6 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::CONSTANT => {
-                let text = format!("const int {} = 0;", name);
-                let filter_range = 10..10 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::MODULE => {
-                let text = format!("namespace {} {{}}", name);
-                let filter_range = 10..10 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::TYPE_PARAMETER => {
-                let text = format!("typename {} {{}};", name);
-                let filter_range = 9..9 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            _ => return None,
-        };
-
-        Some(CodeLabel {
-            runs: language.highlight_text(&text.as_str().into(), display_range.clone()),
-            text: text[display_range].to_string(),
-            filter_range,
-        })
-    }
-}
-
-async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_clangd_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_clangd_dir = Some(entry.path());
-            }
-        }
-        let clangd_dir = last_clangd_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let clangd_bin = clangd_dir.join("bin/clangd");
-        if clangd_bin.exists() {
-            Ok(LanguageServerBinary {
-                path: clangd_bin,
-                arguments: vec![],
-            })
-        } else {
-            Err(anyhow!(
-                "missing clangd binary in directory {:?}",
-                clangd_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}
-
-#[cfg(test)]
-mod tests {
-    use gpui::{Context, TestAppContext};
-    use language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer};
-    use settings::SettingsStore;
-    use std::num::NonZeroU32;
-
-    #[gpui::test]
-    async fn test_c_autoindent(cx: &mut TestAppContext) {
-        // cx.executor().set_block_on_ticks(usize::MAX..=usize::MAX);
-        cx.update(|cx| {
-            let test_settings = SettingsStore::test(cx);
-            cx.set_global(test_settings);
-            language::init(cx);
-            cx.update_global::<SettingsStore, _>(|store, cx| {
-                store.update_user_settings::<AllLanguageSettings>(cx, |s| {
-                    s.defaults.tab_size = NonZeroU32::new(2);
-                });
-            });
-        });
-        let language = crate::languages::language("c", tree_sitter_c::language(), None).await;
-
-        cx.new_model(|cx| {
-            let mut buffer =
-                Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
-
-            // empty function
-            buffer.edit([(0..0, "int main() {}")], None, cx);
-
-            // indent inside braces
-            let ix = buffer.len() - 1;
-            buffer.edit([(ix..ix, "\n\n")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "int main() {\n  \n}");
-
-            // indent body of single-statement if statement
-            let ix = buffer.len() - 2;
-            buffer.edit([(ix..ix, "if (a)\nb;")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "int main() {\n  if (a)\n    b;\n}");
-
-            // indent inside field expression
-            let ix = buffer.len() - 3;
-            buffer.edit([(ix..ix, "\n.c")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "int main() {\n  if (a)\n    b\n      .c;\n}");
-
-            buffer
-        });
-    }
-}

crates/zed2/src/languages/c/config.toml 🔗

@@ -1,12 +0,0 @@
-name = "C"
-path_suffixes = ["c"]
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-]

crates/zed2/src/languages/c/embedding.scm 🔗

@@ -1,43 +0,0 @@
-(
-    (comment)* @context
-    .
-    (declaration
-        declarator: [
-            (function_declarator
-                declarator: (_) @name)
-            (pointer_declarator
-                "*" @name
-                declarator: (function_declarator
-                    declarator: (_) @name))
-            (pointer_declarator
-                "*" @name
-                declarator: (pointer_declarator
-                    "*" @name
-                    declarator: (function_declarator
-                        declarator: (_) @name)))
-            ]
-        ) @item
-    )
-
-(
-    (comment)* @context
-    .
-    (function_definition
-        declarator: [
-            (function_declarator
-                declarator: (_) @name
-                )
-            (pointer_declarator
-                "*" @name
-                declarator: (function_declarator
-                    declarator: (_) @name
-                    ))
-            (pointer_declarator
-                "*" @name
-                declarator: (pointer_declarator
-                    "*" @name
-                    declarator: (function_declarator
-                        declarator: (_) @name)))
-            ]
-        ) @item
-    )

crates/zed2/src/languages/c/highlights.scm 🔗

@@ -1,109 +0,0 @@
-[
-  "break"
-  "case"
-  "const"
-  "continue"
-  "default"
-  "do"
-  "else"
-  "enum"
-  "extern"
-  "for"
-  "if"
-  "inline"
-  "return"
-  "sizeof"
-  "static"
-  "struct"
-  "switch"
-  "typedef"
-  "union"
-  "volatile"
-  "while"
-] @keyword
-
-[
-  "#define"
-  "#elif"
-  "#else"
-  "#endif"
-  "#if"
-  "#ifdef"
-  "#ifndef"
-  "#include"
-  (preproc_directive)
-] @keyword
-
-[
-  "--"
-  "-"
-  "-="
-  "->"
-  "="
-  "!="
-  "*"
-  "&"
-  "&&"
-  "+"
-  "++"
-  "+="
-  "<"
-  "=="
-  ">"
-  "||"
-] @operator
-
-[
-  "."
-  ";"
-] @punctuation.delimiter
-
-[
-  "{"
-  "}"
-  "("
-  ")"
-  "["
-  "]"
-] @punctuation.bracket
-
-[
-  (string_literal)
-  (system_lib_string)
-  (char_literal)
-] @string
-
-(comment) @comment
-
-(number_literal) @number
-
-[
-  (true)
-  (false)
-  (null)
-] @constant
-
-(identifier) @variable
-
-((identifier) @constant
- (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
-
-(call_expression
-  function: (identifier) @function)
-(call_expression
-  function: (field_expression
-    field: (field_identifier) @function))
-(function_declarator
-  declarator: (identifier) @function)
-(preproc_function_def
-  name: (identifier) @function.special)
-
-(field_identifier) @property
-(statement_identifier) @label
-
-[
-  (type_identifier)
-  (primitive_type)
-  (sized_type_specifier)
-] @type
-

crates/zed2/src/languages/c/outline.scm 🔗

@@ -1,70 +0,0 @@
-(preproc_def
-    "#define" @context
-    name: (_) @name) @item
-
-(preproc_function_def
-    "#define" @context
-    name: (_) @name
-    parameters: (preproc_params
-        "(" @context
-        ")" @context)) @item
-
-(type_definition
-    "typedef" @context
-    declarator: (_) @name) @item
-
-(declaration
-    (type_qualifier)? @context
-    type: (_)? @context
-    declarator: [
-        (function_declarator
-            declarator: (_) @name
-            parameters: (parameter_list
-                "(" @context
-                ")" @context))
-        (pointer_declarator
-            "*" @context
-            declarator: (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-        (pointer_declarator
-            "*" @context
-            declarator: (pointer_declarator
-                "*" @context
-                declarator: (function_declarator
-                    declarator: (_) @name
-                    parameters: (parameter_list
-                        "(" @context
-                        ")" @context))))
-    ]
-) @item
-
-(function_definition
-    (type_qualifier)? @context
-    type: (_)? @context
-    declarator: [
-        (function_declarator
-            declarator: (_) @name
-            parameters: (parameter_list
-                "(" @context
-                ")" @context))
-        (pointer_declarator
-            "*" @context
-            declarator: (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-        (pointer_declarator
-            "*" @context
-            declarator: (pointer_declarator
-                "*" @context
-                declarator: (function_declarator
-                    declarator: (_) @name
-                    parameters: (parameter_list
-                        "(" @context
-                        ")" @context))))
-    ]
-) @item

crates/zed2/src/languages/cpp/config.toml 🔗

@@ -1,12 +0,0 @@
-name = "C++"
-path_suffixes = ["cc", "cpp", "h", "hpp", "cxx", "hxx", "inl"]
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-]

crates/zed2/src/languages/cpp/embedding.scm 🔗

@@ -1,61 +0,0 @@
-(
-    (comment)* @context
-    .
-    (function_definition
-        (type_qualifier)? @name
-        type: (_)? @name
-        declarator: [
-            (function_declarator
-                declarator: (_) @name)
-            (pointer_declarator
-                "*" @name
-                declarator: (function_declarator
-                declarator: (_) @name))
-            (pointer_declarator
-                "*" @name
-                declarator: (pointer_declarator
-                    "*" @name
-                declarator: (function_declarator
-                    declarator: (_) @name)))
-            (reference_declarator
-                ["&" "&&"] @name
-                (function_declarator
-                declarator: (_) @name))
-        ]
-        (type_qualifier)? @name) @item
-    )
-
-(
-    (comment)* @context
-    .
-    (template_declaration
-        (class_specifier
-            "class" @name
-            name: (_) @name)
-            ) @item
-)
-
-(
-    (comment)* @context
-    .
-    (class_specifier
-        "class" @name
-        name: (_) @name) @item
-    )
-
-(
-    (comment)* @context
-    .
-    (enum_specifier
-        "enum" @name
-        name: (_) @name) @item
-    )
-
-(
-    (comment)* @context
-    .
-    (declaration
-        type: (struct_specifier
-        "struct" @name)
-        declarator: (_) @name) @item
-)

crates/zed2/src/languages/cpp/highlights.scm 🔗

@@ -1,158 +0,0 @@
-(identifier) @variable
-
-(call_expression
-  function: (qualified_identifier
-    name: (identifier) @function))
-
-(call_expression
-  function: (identifier) @function)
-
-(call_expression
-  function: (field_expression
-    field: (field_identifier) @function))
-
-(preproc_function_def
-  name: (identifier) @function.special)
-
-(template_function
-  name: (identifier) @function)
-
-(template_method
-  name: (field_identifier) @function)
-
-(function_declarator
-  declarator: (identifier) @function)
-
-(function_declarator
-  declarator: (qualified_identifier
-    name: (identifier) @function))
-
-(function_declarator
-  declarator: (field_identifier) @function)
-
-((namespace_identifier) @type
- (#match? @type "^[A-Z]"))
-
-(auto) @type
-(type_identifier) @type
-
-((identifier) @constant
- (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
-
-(field_identifier) @property
-(statement_identifier) @label
-(this) @variable.special
-
-[
-  "break"
-  "case"
-  "catch"
-  "class"
-  "co_await"
-  "co_return"
-  "co_yield"
-  "const"
-  "constexpr"
-  "continue"
-  "default"
-  "delete"
-  "do"
-  "else"
-  "enum"
-  "explicit"
-  "extern"
-  "final"
-  "for"
-  "friend"
-  "if"
-  "if"
-  "inline"
-  "mutable"
-  "namespace"
-  "new"
-  "noexcept"
-  "override"
-  "private"
-  "protected"
-  "public"
-  "return"
-  "sizeof"
-  "static"
-  "struct"
-  "switch"
-  "template"
-  "throw"
-  "try"
-  "typedef"
-  "typename"
-  "union"
-  "using"
-  "virtual"
-  "volatile"
-  "while"
-  (primitive_type)
-  (type_qualifier)
-] @keyword
-
-[
-  "#define"
-  "#elif"
-  "#else"
-  "#endif"
-  "#if"
-  "#ifdef"
-  "#ifndef"
-  "#include"
-  (preproc_directive)
-] @keyword
-
-(comment) @comment
-
-[
-  (true)
-  (false)
-  (null)
-  (nullptr)
-] @constant
-
-(number_literal) @number
-
-[
-  (string_literal)
-  (system_lib_string)
-  (char_literal)
-  (raw_string_literal)
-] @string
-
-[
-  "."
-  ";"
-] @punctuation.delimiter
-
-[
-  "{"
-  "}"
-  "("
-  ")"
-  "["
-  "]"
-] @punctuation.bracket
-
-[
-  "--"
-  "-"
-  "-="
-  "->"
-  "="
-  "!="
-  "*"
-  "&"
-  "&&"
-  "+"
-  "++"
-  "+="
-  "<"
-  "=="
-  ">"
-  "||"
-] @operator

crates/zed2/src/languages/cpp/outline.scm 🔗

@@ -1,149 +0,0 @@
-(preproc_def
-    "#define" @context
-    name: (_) @name) @item
-
-(preproc_function_def
-    "#define" @context
-    name: (_) @name
-    parameters: (preproc_params
-        "(" @context
-        ")" @context)) @item
-
-(type_definition
-    "typedef" @context
-    declarator: (_) @name) @item
-
-(struct_specifier
-    "struct" @context
-    name: (_) @name) @item
-
-(class_specifier
-    "class" @context
-    name: (_) @name) @item
-
-(enum_specifier
-    "enum" @context
-    name: (_) @name) @item
-
-(enumerator
-    name: (_) @name) @item
-
-(declaration
-    (storage_class_specifier) @context
-    (type_qualifier)? @context
-    type: (_) @context
-    declarator: (init_declarator
-      declarator: (_) @name)) @item
-
-(function_definition
-    (type_qualifier)? @context
-    type: (_)? @context
-    declarator: [
-        (function_declarator
-            declarator: (_) @name
-            parameters: (parameter_list
-                "(" @context
-                ")" @context))
-        (pointer_declarator
-            "*" @context
-            declarator: (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-        (pointer_declarator
-            "*" @context
-            declarator: (pointer_declarator
-                "*" @context
-                declarator: (function_declarator
-                    declarator: (_) @name
-                    parameters: (parameter_list
-                        "(" @context
-                        ")" @context))))
-        (reference_declarator
-            ["&" "&&"] @context
-            (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-    ]
-    (type_qualifier)? @context) @item
-
-(declaration
-    (type_qualifier)? @context
-    type: (_)? @context
-    declarator: [
-        (field_identifier) @name
-        (pointer_declarator
-            "*" @context
-            declarator: (field_identifier) @name)
-        (function_declarator
-            declarator: (_) @name
-            parameters: (parameter_list
-                "(" @context
-                ")" @context))
-        (pointer_declarator
-            "*" @context
-            declarator: (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-        (pointer_declarator
-            "*" @context
-            declarator: (pointer_declarator
-                "*" @context
-                declarator: (function_declarator
-                    declarator: (_) @name
-                    parameters: (parameter_list
-                        "(" @context
-                        ")" @context))))
-        (reference_declarator
-            ["&" "&&"] @context
-            (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-    ]
-    (type_qualifier)? @context) @item
-
-(field_declaration
-    (type_qualifier)? @context
-    type: (_) @context
-    declarator: [
-        (field_identifier) @name
-        (pointer_declarator
-            "*" @context
-            declarator: (field_identifier) @name)
-        (function_declarator
-            declarator: (_) @name
-            parameters: (parameter_list
-                "(" @context
-                ")" @context))
-        (pointer_declarator
-            "*" @context
-            declarator: (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-        (pointer_declarator
-            "*" @context
-            declarator: (pointer_declarator
-                "*" @context
-                declarator: (function_declarator
-                    declarator: (_) @name
-                    parameters: (parameter_list
-                        "(" @context
-                        ")" @context))))
-        (reference_declarator
-            ["&" "&&"] @context
-            (function_declarator
-                declarator: (_) @name
-                parameters: (parameter_list
-                    "(" @context
-                    ")" @context)))
-    ]
-    (type_qualifier)? @context) @item

crates/zed2/src/languages/css.rs 🔗

@@ -1,130 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use futures::StreamExt;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-use serde_json::json;
-use smol::fs;
-use std::{
-    any::Any,
-    ffi::OsString,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-const SERVER_PATH: &'static str =
-    "node_modules/vscode-langservers-extracted/bin/vscode-css-language-server";
-
-fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct CssLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl CssLspAdapter {
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        CssLspAdapter { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for CssLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("vscode-css-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "css"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(
-            self.node
-                .npm_package_latest_version("vscode-langservers-extracted")
-                .await?,
-        ) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<String>().unwrap();
-        let server_path = container_dir.join(SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("vscode-langservers-extracted", version.as_str())],
-                )
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        Some(json!({
-            "provideFormatter": true
-        }))
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(SERVER_PATH);
-        if server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: server_binary_arguments(&server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}

crates/zed2/src/languages/css/config.toml 🔗

@@ -1,13 +0,0 @@
-name = "CSS"
-path_suffixes = ["css"]
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-]
-word_characters = ["-"]
-block_comment = ["/* ", " */"]
-prettier_parser_name = "css"

crates/zed2/src/languages/css/highlights.scm 🔗

@@ -1,78 +0,0 @@
-(comment) @comment
-
-[
-  (tag_name)
-  (nesting_selector)
-  (universal_selector)
-] @tag
-
-[
-  "~"
-  ">"
-  "+"
-  "-"
-  "*"
-  "/"
-  "="
-  "^="
-  "|="
-  "~="
-  "$="
-  "*="
-  "and"
-  "or"
-  "not"
-  "only"
-] @operator
-
-(attribute_selector (plain_value) @string)
-
-(attribute_name) @attribute
-(pseudo_element_selector (tag_name) @attribute)
-(pseudo_class_selector (class_name) @attribute)
-
-[
-  (class_name)
-  (id_name)
-  (namespace_name)
-  (property_name)
-  (feature_name)
-] @property
-
-(function_name) @function
-
-(
-  [
-    (property_name)
-    (plain_value)
-  ] @variable.special
-  (#match? @variable.special "^--")
-)
-
-[
-  "@media"
-  "@import"
-  "@charset"
-  "@namespace"
-  "@supports"
-  "@keyframes"
-  (at_keyword)
-  (to)
-  (from)
-  (important)
-]  @keyword
-
-(string_value) @string
-(color_value) @string.special
-
-[
-  (integer_value)
-  (float_value)
-] @number
-
-(unit) @type
-
-[
-  ","
-  ":"
-] @punctuation.delimiter

crates/zed2/src/languages/elixir.rs 🔗

@@ -1,542 +0,0 @@
-use anyhow::{anyhow, bail, Context, Result};
-use async_trait::async_trait;
-use futures::StreamExt;
-use gpui::{AsyncAppContext, Task};
-pub use language::*;
-use lsp::{CompletionItemKind, LanguageServerBinary, SymbolKind};
-use schemars::JsonSchema;
-use serde_derive::{Deserialize, Serialize};
-use settings::Settings;
-use smol::fs::{self, File};
-use std::{
-    any::Any,
-    env::consts,
-    ops::Deref,
-    path::PathBuf,
-    sync::{
-        atomic::{AtomicBool, Ordering::SeqCst},
-        Arc,
-    },
-};
-use util::{
-    async_maybe,
-    fs::remove_matching,
-    github::{latest_github_release, GitHubLspBinaryVersion},
-    ResultExt,
-};
-
-#[derive(Clone, Serialize, Deserialize, JsonSchema)]
-pub struct ElixirSettings {
-    pub lsp: ElixirLspSetting,
-}
-
-#[derive(Clone, Serialize, Deserialize, JsonSchema)]
-#[serde(rename_all = "snake_case")]
-pub enum ElixirLspSetting {
-    ElixirLs,
-    NextLs,
-    Local {
-        path: String,
-        arguments: Vec<String>,
-    },
-}
-
-#[derive(Clone, Serialize, Default, Deserialize, JsonSchema)]
-pub struct ElixirSettingsContent {
-    lsp: Option<ElixirLspSetting>,
-}
-
-impl Settings for ElixirSettings {
-    const KEY: Option<&'static str> = Some("elixir");
-
-    type FileContent = ElixirSettingsContent;
-
-    fn load(
-        default_value: &Self::FileContent,
-        user_values: &[&Self::FileContent],
-        _: &mut gpui::AppContext,
-    ) -> Result<Self>
-    where
-        Self: Sized,
-    {
-        Self::load_via_json_merge(default_value, user_values)
-    }
-}
-
-pub struct ElixirLspAdapter;
-
-#[async_trait]
-impl LspAdapter for ElixirLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("elixir-ls".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "elixir-ls"
-    }
-
-    fn will_start_server(
-        &self,
-        delegate: &Arc<dyn LspAdapterDelegate>,
-        cx: &mut AsyncAppContext,
-    ) -> Option<Task<Result<()>>> {
-        static DID_SHOW_NOTIFICATION: AtomicBool = AtomicBool::new(false);
-
-        const NOTIFICATION_MESSAGE: &str = "Could not run the elixir language server, `elixir-ls`, because `elixir` was not found.";
-
-        let delegate = delegate.clone();
-        Some(cx.spawn(|cx| async move {
-            let elixir_output = smol::process::Command::new("elixir")
-                .args(["--version"])
-                .output()
-                .await;
-            if elixir_output.is_err() {
-                if DID_SHOW_NOTIFICATION
-                    .compare_exchange(false, true, SeqCst, SeqCst)
-                    .is_ok()
-                {
-                    cx.update(|cx| {
-                        delegate.show_notification(NOTIFICATION_MESSAGE, cx);
-                    })?
-                }
-                return Err(anyhow!("cannot run elixir-ls"));
-            }
-
-            Ok(())
-        }))
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        let http = delegate.http_client();
-        let release = latest_github_release("elixir-lsp/elixir-ls", false, http).await?;
-        let version_name = release
-            .name
-            .strip_prefix("Release ")
-            .context("Elixir-ls release name does not start with prefix")?
-            .to_owned();
-
-        let asset_name = format!("elixir-ls-{}.zip", &version_name);
-        let asset = release
-            .assets
-            .iter()
-            .find(|asset| asset.name == asset_name)
-            .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
-
-        let version = GitHubLspBinaryVersion {
-            name: version_name,
-            url: asset.browser_download_url.clone(),
-        };
-        Ok(Box::new(version) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
-        let zip_path = container_dir.join(format!("elixir-ls_{}.zip", version.name));
-        let folder_path = container_dir.join("elixir-ls");
-        let binary_path = folder_path.join("language_server.sh");
-
-        if fs::metadata(&binary_path).await.is_err() {
-            let mut response = delegate
-                .http_client()
-                .get(&version.url, Default::default(), true)
-                .await
-                .context("error downloading release")?;
-            let mut file = File::create(&zip_path)
-                .await
-                .with_context(|| format!("failed to create file {}", zip_path.display()))?;
-            if !response.status().is_success() {
-                Err(anyhow!(
-                    "download failed with status {}",
-                    response.status().to_string()
-                ))?;
-            }
-            futures::io::copy(response.body_mut(), &mut file).await?;
-
-            fs::create_dir_all(&folder_path)
-                .await
-                .with_context(|| format!("failed to create directory {}", folder_path.display()))?;
-            let unzip_status = smol::process::Command::new("unzip")
-                .arg(&zip_path)
-                .arg("-d")
-                .arg(&folder_path)
-                .output()
-                .await?
-                .status;
-            if !unzip_status.success() {
-                Err(anyhow!("failed to unzip elixir-ls archive"))?;
-            }
-
-            remove_matching(&container_dir, |entry| entry != folder_path).await;
-        }
-
-        Ok(LanguageServerBinary {
-            path: binary_path,
-            arguments: vec![],
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary_elixir_ls(container_dir).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary_elixir_ls(container_dir).await
-    }
-
-    async fn label_for_completion(
-        &self,
-        completion: &lsp::CompletionItem,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        match completion.kind.zip(completion.detail.as_ref()) {
-            Some((_, detail)) if detail.starts_with("(function)") => {
-                let text = detail.strip_prefix("(function) ")?;
-                let filter_range = 0..text.find('(').unwrap_or(text.len());
-                let source = Rope::from(format!("def {text}").as_str());
-                let runs = language.highlight_text(&source, 4..4 + text.len());
-                return Some(CodeLabel {
-                    text: text.to_string(),
-                    runs,
-                    filter_range,
-                });
-            }
-            Some((_, detail)) if detail.starts_with("(macro)") => {
-                let text = detail.strip_prefix("(macro) ")?;
-                let filter_range = 0..text.find('(').unwrap_or(text.len());
-                let source = Rope::from(format!("defmacro {text}").as_str());
-                let runs = language.highlight_text(&source, 9..9 + text.len());
-                return Some(CodeLabel {
-                    text: text.to_string(),
-                    runs,
-                    filter_range,
-                });
-            }
-            Some((
-                CompletionItemKind::CLASS
-                | CompletionItemKind::MODULE
-                | CompletionItemKind::INTERFACE
-                | CompletionItemKind::STRUCT,
-                _,
-            )) => {
-                let filter_range = 0..completion
-                    .label
-                    .find(" (")
-                    .unwrap_or(completion.label.len());
-                let text = &completion.label[filter_range.clone()];
-                let source = Rope::from(format!("defmodule {text}").as_str());
-                let runs = language.highlight_text(&source, 10..10 + text.len());
-                return Some(CodeLabel {
-                    text: completion.label.clone(),
-                    runs,
-                    filter_range,
-                });
-            }
-            _ => {}
-        }
-
-        None
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        kind: SymbolKind,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        let (text, filter_range, display_range) = match kind {
-            SymbolKind::METHOD | SymbolKind::FUNCTION => {
-                let text = format!("def {}", name);
-                let filter_range = 4..4 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            SymbolKind::CLASS | SymbolKind::MODULE | SymbolKind::INTERFACE | SymbolKind::STRUCT => {
-                let text = format!("defmodule {}", name);
-                let filter_range = 10..10 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            _ => return None,
-        };
-
-        Some(CodeLabel {
-            runs: language.highlight_text(&text.as_str().into(), display_range.clone()),
-            text: text[display_range].to_string(),
-            filter_range,
-        })
-    }
-}
-
-async fn get_cached_server_binary_elixir_ls(
-    container_dir: PathBuf,
-) -> Option<LanguageServerBinary> {
-    let server_path = container_dir.join("elixir-ls/language_server.sh");
-    if server_path.exists() {
-        Some(LanguageServerBinary {
-            path: server_path,
-            arguments: vec![],
-        })
-    } else {
-        log::error!("missing executable in directory {:?}", server_path);
-        None
-    }
-}
-
-pub struct NextLspAdapter;
-
-#[async_trait]
-impl LspAdapter for NextLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("next-ls".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "next-ls"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        let release =
-            latest_github_release("elixir-tools/next-ls", false, delegate.http_client()).await?;
-        let version = release.name.clone();
-        let platform = match consts::ARCH {
-            "x86_64" => "darwin_amd64",
-            "aarch64" => "darwin_arm64",
-            other => bail!("Running on unsupported platform: {other}"),
-        };
-        let asset_name = format!("next_ls_{}", platform);
-        let asset = release
-            .assets
-            .iter()
-            .find(|asset| asset.name == asset_name)
-            .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
-        let version = GitHubLspBinaryVersion {
-            name: version,
-            url: asset.browser_download_url.clone(),
-        };
-        Ok(Box::new(version) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
-
-        let binary_path = container_dir.join("next-ls");
-
-        if fs::metadata(&binary_path).await.is_err() {
-            let mut response = delegate
-                .http_client()
-                .get(&version.url, Default::default(), true)
-                .await
-                .map_err(|err| anyhow!("error downloading release: {}", err))?;
-
-            let mut file = smol::fs::File::create(&binary_path).await?;
-            if !response.status().is_success() {
-                Err(anyhow!(
-                    "download failed with status {}",
-                    response.status().to_string()
-                ))?;
-            }
-            futures::io::copy(response.body_mut(), &mut file).await?;
-
-            fs::set_permissions(
-                &binary_path,
-                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-            )
-            .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: binary_path,
-            arguments: vec!["--stdio".into()],
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary_next(container_dir)
-            .await
-            .map(|mut binary| {
-                binary.arguments = vec!["--stdio".into()];
-                binary
-            })
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary_next(container_dir)
-            .await
-            .map(|mut binary| {
-                binary.arguments = vec!["--help".into()];
-                binary
-            })
-    }
-
-    async fn label_for_completion(
-        &self,
-        completion: &lsp::CompletionItem,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        label_for_completion_elixir(completion, language)
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        symbol_kind: SymbolKind,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        label_for_symbol_elixir(name, symbol_kind, language)
-    }
-}
-
-async fn get_cached_server_binary_next(container_dir: PathBuf) -> Option<LanguageServerBinary> {
-    async_maybe!({
-        let mut last_binary_path = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_file()
-                && entry
-                    .file_name()
-                    .to_str()
-                    .map_or(false, |name| name == "next-ls")
-            {
-                last_binary_path = Some(entry.path());
-            }
-        }
-
-        if let Some(path) = last_binary_path {
-            Ok(LanguageServerBinary {
-                path,
-                arguments: Vec::new(),
-            })
-        } else {
-            Err(anyhow!("no cached binary"))
-        }
-    })
-    .await
-    .log_err()
-}
-
-pub struct LocalLspAdapter {
-    pub path: String,
-    pub arguments: Vec<String>,
-}
-
-#[async_trait]
-impl LspAdapter for LocalLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("local-ls".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "local-ls"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        Ok(Box::new(()) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        _: Box<dyn 'static + Send + Any>,
-        _: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let path = shellexpand::full(&self.path)?;
-        Ok(LanguageServerBinary {
-            path: PathBuf::from(path.deref()),
-            arguments: self.arguments.iter().map(|arg| arg.into()).collect(),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        _: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        let path = shellexpand::full(&self.path).ok()?;
-        Some(LanguageServerBinary {
-            path: PathBuf::from(path.deref()),
-            arguments: self.arguments.iter().map(|arg| arg.into()).collect(),
-        })
-    }
-
-    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
-        let path = shellexpand::full(&self.path).ok()?;
-        Some(LanguageServerBinary {
-            path: PathBuf::from(path.deref()),
-            arguments: self.arguments.iter().map(|arg| arg.into()).collect(),
-        })
-    }
-
-    async fn label_for_completion(
-        &self,
-        completion: &lsp::CompletionItem,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        label_for_completion_elixir(completion, language)
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        symbol: SymbolKind,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        label_for_symbol_elixir(name, symbol, language)
-    }
-}
-
-fn label_for_completion_elixir(
-    completion: &lsp::CompletionItem,
-    language: &Arc<Language>,
-) -> Option<CodeLabel> {
-    return Some(CodeLabel {
-        runs: language.highlight_text(&completion.label.clone().into(), 0..completion.label.len()),
-        text: completion.label.clone(),
-        filter_range: 0..completion.label.len(),
-    });
-}
-
-fn label_for_symbol_elixir(
-    name: &str,
-    _: SymbolKind,
-    language: &Arc<Language>,
-) -> Option<CodeLabel> {
-    Some(CodeLabel {
-        runs: language.highlight_text(&name.into(), 0..name.len()),
-        text: name.to_string(),
-        filter_range: 0..name.len(),
-    })
-}

crates/zed2/src/languages/elixir/config.toml 🔗

@@ -1,16 +0,0 @@
-name = "Elixir"
-path_suffixes = ["ex", "exs"]
-line_comment = "# "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]
-
-[overrides.string]
-word_characters = ["-"]
-opt_into_language_servers = ["tailwindcss-language-server"]

crates/zed2/src/languages/elixir/embedding.scm 🔗

@@ -1,27 +0,0 @@
-(
-    (unary_operator
-        operator: "@"
-        operand: (call
-            target: (identifier) @unary
-            (#match? @unary "^(doc)$"))
-        ) @context
-    .
-    (call
-        target: (identifier) @name
-        (arguments
-            [
-            (identifier) @name
-            (call
-                target: (identifier) @name)
-                (binary_operator
-                    left: (call
-                    target: (identifier) @name)
-                    operator: "when")
-            ])
-        (#match? @name "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item
-        )
-
-    (call
-        target: (identifier) @name
-        (arguments (alias) @name)
-        (#match? @name "^(defmodule|defprotocol)$")) @item

crates/zed2/src/languages/elixir/highlights.scm 🔗

@@ -1,153 +0,0 @@
-["when" "and" "or" "not" "in" "not in" "fn" "do" "end" "catch" "rescue" "after" "else"] @keyword
-
-(unary_operator
-  operator: "&"
-  operand: (integer) @operator)
-
-(operator_identifier) @operator
-
-(unary_operator
-  operator: _ @operator)
-
-(binary_operator
-  operator: _ @operator)
-
-(dot
-  operator: _ @operator)
-
-(stab_clause
-  operator: _ @operator)
-
-[
-  (boolean)
-  (nil)
-] @constant
-
-[
-  (integer)
-  (float)
-] @number
-
-(alias) @type
-
-(call
-  target: (dot
-    left: (atom) @type))
-
-(char) @constant
-
-(escape_sequence) @string.escape
-
-[
-  (atom)
-  (quoted_atom)
-  (keyword)
-  (quoted_keyword)
-] @string.special.symbol
-
-[
-  (string)
-  (charlist)
-] @string
-
-(sigil
-  (sigil_name) @__name__
-  quoted_start: _ @string
-  quoted_end: _ @string
-  (#match? @__name__ "^[sS]$")) @string
-
-(sigil
-  (sigil_name) @__name__
-  quoted_start: _ @string.regex
-  quoted_end: _ @string.regex
-  (#match? @__name__ "^[rR]$")) @string.regex
-
-(sigil
-  (sigil_name) @__name__
-  quoted_start: _ @string.special
-  quoted_end: _ @string.special) @string.special
-
-(
-  (identifier) @comment.unused
-  (#match? @comment.unused "^_")
-)
-
-(call
-  target: [
-    (identifier) @function
-    (dot
-      right: (identifier) @function)
-  ])
-
-(call
-  target: (identifier) @keyword
-  (arguments
-    [
-      (identifier) @function
-      (binary_operator
-        left: (identifier) @function
-        operator: "when")
-      (binary_operator
-        operator: "|>"
-        right: (identifier))
-    ])
-  (#match? @keyword "^(def|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp|defp)$"))
-
-(binary_operator
-  operator: "|>"
-  right: (identifier) @function)
-
-(call
-  target: (identifier) @keyword
-  (#match? @keyword "^(def|defdelegate|defexception|defguard|defguardp|defimpl|defmacro|defmacrop|defmodule|defn|defnp|defoverridable|defp|defprotocol|defstruct)$"))
-
-(call
-  target: (identifier) @keyword
-  (#match? @keyword "^(alias|case|cond|else|for|if|import|quote|raise|receive|require|reraise|super|throw|try|unless|unquote|unquote_splicing|use|with)$"))
-
-(
-  (identifier) @constant.builtin
-  (#match? @constant.builtin "^(__MODULE__|__DIR__|__ENV__|__CALLER__|__STACKTRACE__)$")
-)
-
-(unary_operator
-  operator: "@" @comment.doc
-  operand: (call
-    target: (identifier) @__attribute__ @comment.doc
-    (arguments
-      [
-        (string)
-        (charlist)
-        (sigil)
-        (boolean)
-      ] @comment.doc))
-  (#match? @__attribute__ "^(moduledoc|typedoc|doc)$"))
-
-(comment) @comment
-
-[
- "%"
-] @punctuation
-
-[
- ","
- ";"
-] @punctuation.delimiter
-
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-  "<<"
-  ">>"
-] @punctuation.bracket
-
-(interpolation "#{" @punctuation.special "}" @punctuation.special) @embedded
-
-((sigil
-  (sigil_name) @_sigil_name
-  (quoted_content) @embedded)
- (#eq? @_sigil_name "H"))

crates/zed2/src/languages/elixir/outline.scm 🔗

@@ -1,26 +0,0 @@
-(call
-  target: (identifier) @context
-  (arguments (alias) @name)
-  (#match? @context "^(defmodule|defprotocol)$")) @item
-
-(call
-  target: (identifier) @context
-  (arguments
-    [
-      (identifier) @name
-      (call
-          target: (identifier) @name
-          (arguments
-              "(" @context.extra
-              _* @context.extra
-              ")" @context.extra))
-      (binary_operator
-        left: (call
-            target: (identifier) @name
-            (arguments
-                "(" @context.extra
-                _* @context.extra
-                ")" @context.extra))
-        operator: "when")
-    ])
-  (#match? @context "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @item

crates/zed2/src/languages/elm/config.toml 🔗

@@ -1,11 +0,0 @@
-name = "Elm"
-path_suffixes = ["elm"]
-line_comment = "-- "
-block_comment = ["{- ", " -}"]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-]

crates/zed2/src/languages/elm/highlights.scm 🔗

@@ -1,72 +0,0 @@
-[
-    "if"
-    "then"
-    "else"
-    "let"
-    "in"
-    (case)
-    (of)
-    (backslash)
-    (as)
-    (port)
-    (exposing)
-    (alias)
-    (import)
-    (module)
-    (type)
-    (arrow)
- ] @keyword
-
-[
-    (eq)
-    (operator_identifier)
-    (colon)
-] @operator
-
-(type_annotation(lower_case_identifier) @function)
-(port_annotation(lower_case_identifier) @function)
-(function_declaration_left(lower_case_identifier) @function.definition)
-
-(function_call_expr
-    target: (value_expr
-        name: (value_qid (lower_case_identifier) @function)))
-
-(exposed_value(lower_case_identifier) @function)
-(exposed_type(upper_case_identifier) @type)
-
-(field_access_expr(value_expr(value_qid)) @identifier)
-(lower_pattern) @variable
-(record_base_identifier) @identifier
-
-[
-    "("
-    ")"
-] @punctuation.bracket
-
-[
-    "|"
-    ","
-] @punctuation.delimiter
-
-(number_constant_expr) @constant
-
-(type_declaration(upper_case_identifier) @type)
-(type_ref) @type
-(type_alias_declaration name: (upper_case_identifier) @type)
-
-(value_expr(upper_case_qid(upper_case_identifier)) @type)
-
-[
-    (line_comment)
-    (block_comment)
-] @comment
-
-(string_escape) @string.escape
-
-[
-    (open_quote)
-    (close_quote)
-    (regular_string_part)
-    (open_char)
-    (close_char)
-] @string

crates/zed2/src/languages/elm/outline.scm 🔗

@@ -1,22 +0,0 @@
-(type_declaration
-    (type) @context
-    (upper_case_identifier) @name) @item
-
-(type_alias_declaration
-    (type) @context
-    (alias) @context
-    name: (upper_case_identifier) @name) @item
-
-(type_alias_declaration
-    typeExpression:
-        (type_expression
-            part: (record_type
-                (field_type
-                    name: (lower_case_identifier) @name) @item)))
-
-(union_variant
-    name: (upper_case_identifier) @name) @item
-
-(value_declaration
-    functionDeclarationLeft:
-        (function_declaration_left(lower_case_identifier) @name)) @item

crates/zed2/src/languages/erb/config.toml 🔗

@@ -1,8 +0,0 @@
-name = "ERB"
-path_suffixes = ["erb"]
-autoclose_before = ">})"
-brackets = [
-    { start = "<", end = ">", close = true, newline = true },
-]
-block_comment = ["<%#", "%>"]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]

crates/zed2/src/languages/glsl/config.toml 🔗

@@ -1,9 +0,0 @@
-name = "GLSL"
-path_suffixes = ["vert", "frag", "tesc", "tese", "geom", "comp"]
-line_comment = "// "
-block_comment = ["/* ", " */"]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]

crates/zed2/src/languages/glsl/highlights.scm 🔗

@@ -1,118 +0,0 @@
-"break" @keyword
-"case" @keyword
-"const" @keyword
-"continue" @keyword
-"default" @keyword
-"do" @keyword
-"else" @keyword
-"enum" @keyword
-"extern" @keyword
-"for" @keyword
-"if" @keyword
-"inline" @keyword
-"return" @keyword
-"sizeof" @keyword
-"static" @keyword
-"struct" @keyword
-"switch" @keyword
-"typedef" @keyword
-"union" @keyword
-"volatile" @keyword
-"while" @keyword
-
-"#define" @keyword
-"#elif" @keyword
-"#else" @keyword
-"#endif" @keyword
-"#if" @keyword
-"#ifdef" @keyword
-"#ifndef" @keyword
-"#include" @keyword
-(preproc_directive) @keyword
-
-"--" @operator
-"-" @operator
-"-=" @operator
-"->" @operator
-"=" @operator
-"!=" @operator
-"*" @operator
-"&" @operator
-"&&" @operator
-"+" @operator
-"++" @operator
-"+=" @operator
-"<" @operator
-"==" @operator
-">" @operator
-"||" @operator
-
-"." @delimiter
-";" @delimiter
-
-(string_literal) @string
-(system_lib_string) @string
-
-(null) @constant
-(number_literal) @number
-(char_literal) @number
-
-(call_expression
-  function: (identifier) @function)
-(call_expression
-  function: (field_expression
-    field: (field_identifier) @function))
-(function_declarator
-  declarator: (identifier) @function)
-(preproc_function_def
-  name: (identifier) @function.special)
-
-(field_identifier) @property
-(statement_identifier) @label
-(type_identifier) @type
-(primitive_type) @type
-(sized_type_specifier) @type
-
-((identifier) @constant
- (#match? @constant "^[A-Z][A-Z\\d_]*$"))
-
-(identifier) @variable
-
-(comment) @comment
-; inherits: c
-
-[
-  "in"
-  "out"
-  "inout"
-  "uniform"
-  "shared"
-  "layout"
-  "attribute"
-  "varying"
-  "buffer"
-  "coherent"
-  "readonly"
-  "writeonly"
-  "precision"
-  "highp"
-  "mediump"
-  "lowp"
-  "centroid"
-  "sample"
-  "patch"
-  "smooth"
-  "flat"
-  "noperspective"
-  "invariant"
-  "precise"
-] @type.qualifier
-
-"subroutine" @keyword.function
-
-(extension_storage_class) @storageclass
-
-(
-  (identifier) @variable.builtin
-  (#match? @variable.builtin "^gl_")
-)

crates/zed2/src/languages/go.rs 🔗

@@ -1,461 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use futures::StreamExt;
-use gpui::{AsyncAppContext, Task};
-pub use language::*;
-use lazy_static::lazy_static;
-use lsp::LanguageServerBinary;
-use regex::Regex;
-use smol::{fs, process};
-use std::{
-    any::Any,
-    ffi::{OsStr, OsString},
-    ops::Range,
-    path::PathBuf,
-    str,
-    sync::{
-        atomic::{AtomicBool, Ordering::SeqCst},
-        Arc,
-    },
-};
-use util::{fs::remove_matching, github::latest_github_release, ResultExt};
-
-fn server_binary_arguments() -> Vec<OsString> {
-    vec!["-mode=stdio".into()]
-}
-
-#[derive(Copy, Clone)]
-pub struct GoLspAdapter;
-
-lazy_static! {
-    static ref GOPLS_VERSION_REGEX: Regex = Regex::new(r"\d+\.\d+\.\d+").unwrap();
-}
-
-#[async_trait]
-impl super::LspAdapter for GoLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("gopls".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "gopls"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        let release = latest_github_release("golang/tools", false, delegate.http_client()).await?;
-        let version: Option<String> = release.name.strip_prefix("gopls/v").map(str::to_string);
-        if version.is_none() {
-            log::warn!(
-                "couldn't infer gopls version from github release name '{}'",
-                release.name
-            );
-        }
-        Ok(Box::new(version) as Box<_>)
-    }
-
-    fn will_fetch_server(
-        &self,
-        delegate: &Arc<dyn LspAdapterDelegate>,
-        cx: &mut AsyncAppContext,
-    ) -> Option<Task<Result<()>>> {
-        static DID_SHOW_NOTIFICATION: AtomicBool = AtomicBool::new(false);
-
-        const NOTIFICATION_MESSAGE: &str =
-            "Could not install the Go language server `gopls`, because `go` was not found.";
-
-        let delegate = delegate.clone();
-        Some(cx.spawn(|cx| async move {
-            let install_output = process::Command::new("go").args(["version"]).output().await;
-            if install_output.is_err() {
-                if DID_SHOW_NOTIFICATION
-                    .compare_exchange(false, true, SeqCst, SeqCst)
-                    .is_ok()
-                {
-                    cx.update(|cx| {
-                        delegate.show_notification(NOTIFICATION_MESSAGE, cx);
-                    })?
-                }
-                return Err(anyhow!("cannot install gopls"));
-            }
-            Ok(())
-        }))
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<Option<String>>().unwrap();
-        let this = *self;
-
-        if let Some(version) = *version {
-            let binary_path = container_dir.join(&format!("gopls_{version}"));
-            if let Ok(metadata) = fs::metadata(&binary_path).await {
-                if metadata.is_file() {
-                    remove_matching(&container_dir, |entry| {
-                        entry != binary_path && entry.file_name() != Some(OsStr::new("gobin"))
-                    })
-                    .await;
-
-                    return Ok(LanguageServerBinary {
-                        path: binary_path.to_path_buf(),
-                        arguments: server_binary_arguments(),
-                    });
-                }
-            }
-        } else if let Some(path) = this
-            .cached_server_binary(container_dir.clone(), delegate)
-            .await
-        {
-            return Ok(path);
-        }
-
-        let gobin_dir = container_dir.join("gobin");
-        fs::create_dir_all(&gobin_dir).await?;
-        let install_output = process::Command::new("go")
-            .env("GO111MODULE", "on")
-            .env("GOBIN", &gobin_dir)
-            .args(["install", "golang.org/x/tools/gopls@latest"])
-            .output()
-            .await?;
-        if !install_output.status.success() {
-            Err(anyhow!("failed to install gopls. Is go installed?"))?;
-        }
-
-        let installed_binary_path = gobin_dir.join("gopls");
-        let version_output = process::Command::new(&installed_binary_path)
-            .arg("version")
-            .output()
-            .await
-            .map_err(|e| anyhow!("failed to run installed gopls binary {:?}", e))?;
-        let version_stdout = str::from_utf8(&version_output.stdout)
-            .map_err(|_| anyhow!("gopls version produced invalid utf8"))?;
-        let version = GOPLS_VERSION_REGEX
-            .find(version_stdout)
-            .ok_or_else(|| anyhow!("failed to parse gopls version output"))?
-            .as_str();
-        let binary_path = container_dir.join(&format!("gopls_{version}"));
-        fs::rename(&installed_binary_path, &binary_path).await?;
-
-        Ok(LanguageServerBinary {
-            path: binary_path.to_path_buf(),
-            arguments: server_binary_arguments(),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir)
-            .await
-            .map(|mut binary| {
-                binary.arguments = vec!["--help".into()];
-                binary
-            })
-    }
-
-    async fn label_for_completion(
-        &self,
-        completion: &lsp::CompletionItem,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        let label = &completion.label;
-
-        // Gopls returns nested fields and methods as completions.
-        // To syntax highlight these, combine their final component
-        // with their detail.
-        let name_offset = label.rfind('.').unwrap_or(0);
-
-        match completion.kind.zip(completion.detail.as_ref()) {
-            Some((lsp::CompletionItemKind::MODULE, detail)) => {
-                let text = format!("{label} {detail}");
-                let source = Rope::from(format!("import {text}").as_str());
-                let runs = language.highlight_text(&source, 7..7 + text.len());
-                return Some(CodeLabel {
-                    text,
-                    runs,
-                    filter_range: 0..label.len(),
-                });
-            }
-            Some((
-                lsp::CompletionItemKind::CONSTANT | lsp::CompletionItemKind::VARIABLE,
-                detail,
-            )) => {
-                let text = format!("{label} {detail}");
-                let source =
-                    Rope::from(format!("var {} {}", &text[name_offset..], detail).as_str());
-                let runs = adjust_runs(
-                    name_offset,
-                    language.highlight_text(&source, 4..4 + text.len()),
-                );
-                return Some(CodeLabel {
-                    text,
-                    runs,
-                    filter_range: 0..label.len(),
-                });
-            }
-            Some((lsp::CompletionItemKind::STRUCT, _)) => {
-                let text = format!("{label} struct {{}}");
-                let source = Rope::from(format!("type {}", &text[name_offset..]).as_str());
-                let runs = adjust_runs(
-                    name_offset,
-                    language.highlight_text(&source, 5..5 + text.len()),
-                );
-                return Some(CodeLabel {
-                    text,
-                    runs,
-                    filter_range: 0..label.len(),
-                });
-            }
-            Some((lsp::CompletionItemKind::INTERFACE, _)) => {
-                let text = format!("{label} interface {{}}");
-                let source = Rope::from(format!("type {}", &text[name_offset..]).as_str());
-                let runs = adjust_runs(
-                    name_offset,
-                    language.highlight_text(&source, 5..5 + text.len()),
-                );
-                return Some(CodeLabel {
-                    text,
-                    runs,
-                    filter_range: 0..label.len(),
-                });
-            }
-            Some((lsp::CompletionItemKind::FIELD, detail)) => {
-                let text = format!("{label} {detail}");
-                let source =
-                    Rope::from(format!("type T struct {{ {} }}", &text[name_offset..]).as_str());
-                let runs = adjust_runs(
-                    name_offset,
-                    language.highlight_text(&source, 16..16 + text.len()),
-                );
-                return Some(CodeLabel {
-                    text,
-                    runs,
-                    filter_range: 0..label.len(),
-                });
-            }
-            Some((lsp::CompletionItemKind::FUNCTION | lsp::CompletionItemKind::METHOD, detail)) => {
-                if let Some(signature) = detail.strip_prefix("func") {
-                    let text = format!("{label}{signature}");
-                    let source = Rope::from(format!("func {} {{}}", &text[name_offset..]).as_str());
-                    let runs = adjust_runs(
-                        name_offset,
-                        language.highlight_text(&source, 5..5 + text.len()),
-                    );
-                    return Some(CodeLabel {
-                        filter_range: 0..label.len(),
-                        text,
-                        runs,
-                    });
-                }
-            }
-            _ => {}
-        }
-        None
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        kind: lsp::SymbolKind,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        let (text, filter_range, display_range) = match kind {
-            lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => {
-                let text = format!("func {} () {{}}", name);
-                let filter_range = 5..5 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::STRUCT => {
-                let text = format!("type {} struct {{}}", name);
-                let filter_range = 5..5 + name.len();
-                let display_range = 0..text.len();
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::INTERFACE => {
-                let text = format!("type {} interface {{}}", name);
-                let filter_range = 5..5 + name.len();
-                let display_range = 0..text.len();
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::CLASS => {
-                let text = format!("type {} T", name);
-                let filter_range = 5..5 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::CONSTANT => {
-                let text = format!("const {} = nil", name);
-                let filter_range = 6..6 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::VARIABLE => {
-                let text = format!("var {} = nil", name);
-                let filter_range = 4..4 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::MODULE => {
-                let text = format!("package {}", name);
-                let filter_range = 8..8 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            _ => return None,
-        };
-
-        Some(CodeLabel {
-            runs: language.highlight_text(&text.as_str().into(), display_range.clone()),
-            text: text[display_range].to_string(),
-            filter_range,
-        })
-    }
-}
-
-async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_binary_path = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_file()
-                && entry
-                    .file_name()
-                    .to_str()
-                    .map_or(false, |name| name.starts_with("gopls_"))
-            {
-                last_binary_path = Some(entry.path());
-            }
-        }
-
-        if let Some(path) = last_binary_path {
-            Ok(LanguageServerBinary {
-                path,
-                arguments: server_binary_arguments(),
-            })
-        } else {
-            Err(anyhow!("no cached binary"))
-        }
-    })()
-    .await
-    .log_err()
-}
-
-fn adjust_runs(
-    delta: usize,
-    mut runs: Vec<(Range<usize>, HighlightId)>,
-) -> Vec<(Range<usize>, HighlightId)> {
-    for (range, _) in &mut runs {
-        range.start += delta;
-        range.end += delta;
-    }
-    runs
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::languages::language;
-    use gpui::Hsla;
-    use theme::SyntaxTheme;
-
-    #[gpui::test]
-    async fn test_go_label_for_completion() {
-        let language = language(
-            "go",
-            tree_sitter_go::language(),
-            Some(Arc::new(GoLspAdapter)),
-        )
-        .await;
-
-        let theme = SyntaxTheme::new_test([
-            ("type", Hsla::default()),
-            ("keyword", Hsla::default()),
-            ("function", Hsla::default()),
-            ("number", Hsla::default()),
-            ("property", Hsla::default()),
-        ]);
-        language.set_theme(&theme);
-
-        let grammar = language.grammar().unwrap();
-        let highlight_function = grammar.highlight_id_for_name("function").unwrap();
-        let highlight_type = grammar.highlight_id_for_name("type").unwrap();
-        let highlight_keyword = grammar.highlight_id_for_name("keyword").unwrap();
-        let highlight_number = grammar.highlight_id_for_name("number").unwrap();
-        let highlight_field = grammar.highlight_id_for_name("property").unwrap();
-
-        assert_eq!(
-            language
-                .label_for_completion(&lsp::CompletionItem {
-                    kind: Some(lsp::CompletionItemKind::FUNCTION),
-                    label: "Hello".to_string(),
-                    detail: Some("func(a B) c.D".to_string()),
-                    ..Default::default()
-                })
-                .await,
-            Some(CodeLabel {
-                text: "Hello(a B) c.D".to_string(),
-                filter_range: 0..5,
-                runs: vec![
-                    (0..5, highlight_function),
-                    (8..9, highlight_type),
-                    (13..14, highlight_type),
-                ],
-            })
-        );
-
-        // Nested methods
-        assert_eq!(
-            language
-                .label_for_completion(&lsp::CompletionItem {
-                    kind: Some(lsp::CompletionItemKind::METHOD),
-                    label: "one.two.Three".to_string(),
-                    detail: Some("func() [3]interface{}".to_string()),
-                    ..Default::default()
-                })
-                .await,
-            Some(CodeLabel {
-                text: "one.two.Three() [3]interface{}".to_string(),
-                filter_range: 0..13,
-                runs: vec![
-                    (8..13, highlight_function),
-                    (17..18, highlight_number),
-                    (19..28, highlight_keyword),
-                ],
-            })
-        );
-
-        // Nested fields
-        assert_eq!(
-            language
-                .label_for_completion(&lsp::CompletionItem {
-                    kind: Some(lsp::CompletionItemKind::FIELD),
-                    label: "two.Three".to_string(),
-                    detail: Some("a.Bcd".to_string()),
-                    ..Default::default()
-                })
-                .await,
-            Some(CodeLabel {
-                text: "two.Three a.Bcd".to_string(),
-                filter_range: 0..9,
-                runs: vec![(4..9, highlight_field), (12..15, highlight_type)],
-            })
-        );
-    }
-}

crates/zed2/src/languages/go/config.toml 🔗

@@ -1,12 +0,0 @@
-name = "Go"
-path_suffixes = ["go"]
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["comment", "string"] },
-]

crates/zed2/src/languages/go/embedding.scm 🔗

@@ -1,24 +0,0 @@
-(
-    (comment)* @context
-    .
-    (type_declaration
-        (type_spec
-            name: (_) @name)
-    ) @item
-)
-
-(
-    (comment)* @context
-    .
-    (function_declaration
-        name: (_) @name
-    ) @item
-)
-
-(
-    (comment)* @context
-    .
-    (method_declaration
-        name: (_) @name
-    ) @item
-)

crates/zed2/src/languages/go/highlights.scm 🔗

@@ -1,107 +0,0 @@
-(identifier) @variable
-(type_identifier) @type
-(field_identifier) @property
-
-(call_expression
-  function: (identifier) @function)
-
-(call_expression
-  function: (selector_expression
-    field: (field_identifier) @function.method))
-
-(function_declaration
-  name: (identifier) @function)
-
-(method_declaration
-  name: (field_identifier) @function.method)
-
-[
-  "--"
-  "-"
-  "-="
-  ":="
-  "!"
-  "!="
-  "..."
-  "*"
-  "*"
-  "*="
-  "/"
-  "/="
-  "&"
-  "&&"
-  "&="
-  "%"
-  "%="
-  "^"
-  "^="
-  "+"
-  "++"
-  "+="
-  "<-"
-  "<"
-  "<<"
-  "<<="
-  "<="
-  "="
-  "=="
-  ">"
-  ">="
-  ">>"
-  ">>="
-  "|"
-  "|="
-  "||"
-  "~"
-] @operator
-
-[
-  "break"
-  "case"
-  "chan"
-  "const"
-  "continue"
-  "default"
-  "defer"
-  "else"
-  "fallthrough"
-  "for"
-  "func"
-  "go"
-  "goto"
-  "if"
-  "import"
-  "interface"
-  "map"
-  "package"
-  "range"
-  "return"
-  "select"
-  "struct"
-  "switch"
-  "type"
-  "var"
-] @keyword
-
-[
-  (interpreted_string_literal)
-  (raw_string_literal)
-  (rune_literal)
-] @string
-
-(escape_sequence) @escape
-
-[
-  (int_literal)
-  (float_literal)
-  (imaginary_literal)
-] @number
-
-[
-  (true)
-  (false)
-  (nil)
-  (iota)
-] @constant.builtin
-
-(comment) @comment

crates/zed2/src/languages/go/indents.scm 🔗

@@ -1,9 +0,0 @@
-[
-    (assignment_statement)
-    (call_expression)
-    (selector_expression)
-] @indent
-
-(_ "[" "]" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent

crates/zed2/src/languages/go/outline.scm 🔗

@@ -1,43 +0,0 @@
-(type_declaration
-    "type" @context
-    (type_spec
-        name: (_) @name)) @item
-
-(function_declaration
-    "func" @context
-    name: (identifier) @name
-    parameters: (parameter_list
-      "(" @context
-      ")" @context)) @item
-
-(method_declaration
-    "func" @context
-    receiver: (parameter_list
-        "(" @context
-        (parameter_declaration
-            type: (_) @context)
-        ")" @context)
-    name: (field_identifier) @name
-    parameters: (parameter_list
-      "(" @context
-      ")" @context)) @item
-
-(const_declaration
-    "const" @context
-    (const_spec
-        name: (identifier) @name) @item)
-
-(source_file
-    (var_declaration
-        "var" @context
-        (var_spec
-            name: (identifier) @name) @item))
-
-(method_spec
-    name: (_) @name
-    parameters: (parameter_list
-      "(" @context
-      ")" @context)) @item
-
-(field_declaration
-    name: (_) @name) @item

crates/zed2/src/languages/heex/config.toml 🔗

@@ -1,12 +0,0 @@
-name = "HEEX"
-path_suffixes = ["heex"]
-autoclose_before = ">})"
-brackets = [
-    { start = "<", end = ">", close = true, newline = true },
-]
-block_comment = ["<%!-- ", " --%>"]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]
-
-[overrides.string]
-word_characters = ["-"]
-opt_into_language_servers = ["tailwindcss-language-server"]

crates/zed2/src/languages/heex/highlights.scm 🔗

@@ -1,57 +0,0 @@
-; HEEx delimiters
-[
-  "/>"
-  "<!"
-  "<"
-  "</"
-  "</:"
-  "<:"
-  ">"
-  "{"
-  "}"
-] @punctuation.bracket
-
-[
-  "<%!--"
-  "<%"
-  "<%#"
-  "<%%="
-  "<%="
-  "%>"
-  "--%>"
-  "-->"
-  "<!--"
-] @keyword
-
-; HEEx operators are highlighted as such
-"=" @operator
-
-; HEEx inherits the DOCTYPE tag from HTML
-(doctype) @constant
-
-(comment) @comment
-
-; HEEx tags and slots are highlighted as HTML
-[
- (tag_name)
- (slot_name)
-] @tag
-
-; HEEx attributes are highlighted as HTML attributes
-(attribute_name) @attribute
-
-; HEEx special attributes are highlighted as keywords
-(special_attribute_name) @keyword
-
-[
-  (attribute_value)
-  (quoted_attribute_value)
-] @string
-
-; HEEx components are highlighted as Elixir modules and functions
-(component_name
-  [
-    (module) @module
-    (function) @function
-    "." @punctuation.delimiter
-  ])

crates/zed2/src/languages/heex/injections.scm 🔗

@@ -1,13 +0,0 @@
-(
-  (directive
-    [
-      (partial_expression_value)
-      (expression_value)
-      (ending_expression_value)
-    ] @content)
-  (#set! language "elixir")
-  (#set! combined)
-)
-
-((expression (expression_value) @content)
- (#set! language "elixir"))

crates/zed2/src/languages/html.rs 🔗

@@ -1,130 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use futures::StreamExt;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-use serde_json::json;
-use smol::fs;
-use std::{
-    any::Any,
-    ffi::OsString,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-const SERVER_PATH: &'static str =
-    "node_modules/vscode-langservers-extracted/bin/vscode-html-language-server";
-
-fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct HtmlLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl HtmlLspAdapter {
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        HtmlLspAdapter { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for HtmlLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("vscode-html-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "html"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(
-            self.node
-                .npm_package_latest_version("vscode-langservers-extracted")
-                .await?,
-        ) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<String>().unwrap();
-        let server_path = container_dir.join(SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("vscode-langservers-extracted", version.as_str())],
-                )
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        Some(json!({
-            "provideFormatter": true
-        }))
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(SERVER_PATH);
-        if server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: server_binary_arguments(&server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}

crates/zed2/src/languages/html/config.toml 🔗

@@ -1,14 +0,0 @@
-name = "HTML"
-path_suffixes = ["html"]
-autoclose_before = ">})"
-block_comment = ["<!-- ", " -->"]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
-    { start = "<", end = ">", close = true, newline = true, not_in = ["comment", "string"] },
-    { start = "!--", end = " --", close = true, newline = false, not_in = ["comment", "string"] },
-]
-word_characters = ["-"]
-prettier_parser_name = "html"

crates/zed2/src/languages/html/highlights.scm 🔗

@@ -1,15 +0,0 @@
-(tag_name) @keyword
-(erroneous_end_tag_name) @keyword
-(doctype) @constant
-(attribute_name) @property
-(attribute_value) @string
-(comment) @comment
-
-"=" @operator
-
-[
-  "<"
-  ">"
-  "</"
-  "/>"
-] @punctuation.bracket

crates/zed2/src/languages/javascript/config.toml 🔗

@@ -1,26 +0,0 @@
-name = "JavaScript"
-path_suffixes = ["js", "jsx", "mjs", "cjs"]
-first_line_pattern = '^#!.*\bnode\b'
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true, not_in = ["comment", "string"] },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
-    { start = "`", end = "`", close = true, newline = false, not_in = ["comment", "string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["comment", "string"] },
-]
-word_characters = ["$", "#"]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]
-prettier_parser_name = "babel"
-
-[overrides.element]
-line_comment = { remove = true }
-block_comment = ["{/* ", " */}"]
-
-[overrides.string]
-word_characters = ["-"]
-opt_into_language_servers = ["tailwindcss-language-server"]

crates/zed2/src/languages/javascript/embedding.scm 🔗

@@ -1,71 +0,0 @@
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (function_declaration
-                "async"? @name
-                "function" @name
-                name: (_) @name))
-        (function_declaration
-            "async"? @name
-            "function" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (class_declaration
-                "class" @name
-                name: (_) @name))
-        (class_declaration
-            "class" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (interface_declaration
-                "interface" @name
-                name: (_) @name))
-        (interface_declaration
-            "interface" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (enum_declaration
-                "enum" @name
-                name: (_) @name))
-        (enum_declaration
-            "enum" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    (method_definition
-        [
-            "get"
-            "set"
-            "async"
-            "*"
-            "static"
-            ]* @name
-        name: (_) @name) @item
-)

crates/zed2/src/languages/javascript/highlights.scm 🔗

@@ -1,217 +0,0 @@
-; Variables
-
-(identifier) @variable
-
-; Properties
-
-(property_identifier) @property
-
-; Function and method calls
-
-(call_expression
-  function: (identifier) @function)
-
-(call_expression
-  function: (member_expression
-    property: (property_identifier) @function.method))
-
-; Function and method definitions
-
-(function
-  name: (identifier) @function)
-(function_declaration
-  name: (identifier) @function)
-(method_definition
-  name: (property_identifier) @function.method)
-
-(pair
-  key: (property_identifier) @function.method
-  value: [(function) (arrow_function)])
-
-(assignment_expression
-  left: (member_expression
-    property: (property_identifier) @function.method)
-  right: [(function) (arrow_function)])
-
-(variable_declarator
-  name: (identifier) @function
-  value: [(function) (arrow_function)])
-
-(assignment_expression
-  left: (identifier) @function
-  right: [(function) (arrow_function)])
-
-; Special identifiers
-
-((identifier) @type
- (#match? @type "^[A-Z]"))
-(type_identifier) @type
-(predefined_type) @type.builtin
-
-([
-  (identifier)
-  (shorthand_property_identifier)
-  (shorthand_property_identifier_pattern)
- ] @constant
- (#match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
-
-; Literals
-
-(this) @variable.special
-(super) @variable.special
-
-[
-  (null)
-  (undefined)
-] @constant.builtin
-
-[
-  (true)
-  (false)
-] @boolean
-
-(comment) @comment
-
-[
-  (string)
-  (template_string)
-] @string
-
-(regex) @string.regex
-(number) @number
-
-; Tokens
-
-[
-  ";"
-  "?."
-  "."
-  ","
-  ":"
-] @punctuation.delimiter
-
-[
-  "-"
-  "--"
-  "-="
-  "+"
-  "++"
-  "+="
-  "*"
-  "*="
-  "**"
-  "**="
-  "/"
-  "/="
-  "%"
-  "%="
-  "<"
-  "<="
-  "<<"
-  "<<="
-  "="
-  "=="
-  "==="
-  "!"
-  "!="
-  "!=="
-  "=>"
-  ">"
-  ">="
-  ">>"
-  ">>="
-  ">>>"
-  ">>>="
-  "~"
-  "^"
-  "&"
-  "|"
-  "^="
-  "&="
-  "|="
-  "&&"
-  "||"
-  "??"
-  "&&="
-  "||="
-  "??="
-] @operator
-
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-]  @punctuation.bracket
-
-[
-  "as"
-  "async"
-  "await"
-  "break"
-  "case"
-  "catch"
-  "class"
-  "const"
-  "continue"
-  "debugger"
-  "default"
-  "delete"
-  "do"
-  "else"
-  "export"
-  "extends"
-  "finally"
-  "for"
-  "from"
-  "function"
-  "get"
-  "if"
-  "import"
-  "in"
-  "instanceof"
-  "let"
-  "new"
-  "of"
-  "return"
-  "set"
-  "static"
-  "switch"
-  "target"
-  "throw"
-  "try"
-  "typeof"
-  "var"
-  "void"
-  "while"
-  "with"
-  "yield"
-] @keyword
-
-(template_substitution
-  "${" @punctuation.special
-  "}" @punctuation.special) @embedded
-
-(type_arguments
-  "<" @punctuation.bracket
-  ">" @punctuation.bracket)
-
-; Keywords
-
-[ "abstract"
-  "declare"
-  "enum"
-  "export"
-  "implements"
-  "interface"
-  "keyof"
-  "namespace"
-  "private"
-  "protected"
-  "public"
-  "type"
-  "readonly"
-  "override"
-] @keyword

crates/zed2/src/languages/javascript/indents.scm 🔗

@@ -1,15 +0,0 @@
-[
-    (call_expression)
-    (assignment_expression)
-    (member_expression)
-    (lexical_declaration)
-    (variable_declaration)
-    (assignment_expression)
-    (if_statement)
-    (for_statement)
-] @indent
-
-(_ "[" "]" @end) @indent
-(_ "<" ">" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent

crates/zed2/src/languages/javascript/outline.scm 🔗

@@ -1,62 +0,0 @@
-(internal_module
-    "namespace" @context
-    name: (_) @name) @item
-
-(enum_declaration
-    "enum" @context
-    name: (_) @name) @item
-
-(function_declaration
-    "async"? @context
-    "function" @context
-    name: (_) @name
-    parameters: (formal_parameters
-      "(" @context
-      ")" @context)) @item
-
-(interface_declaration
-    "interface" @context
-    name: (_) @name) @item
-
-(program
-    (export_statement
-        (lexical_declaration
-            ["let" "const"] @context
-            (variable_declarator
-                name: (_) @name) @item)))
-
-(program
-    (lexical_declaration
-        ["let" "const"] @context
-        (variable_declarator
-            name: (_) @name) @item))
-
-(class_declaration
-    "class" @context
-    name: (_) @name) @item
-
-(method_definition
-    [
-        "get"
-        "set"
-        "async"
-        "*"
-        "readonly"
-        "static"
-        (override_modifier)
-        (accessibility_modifier)
-    ]* @context
-    name: (_) @name
-    parameters: (formal_parameters
-      "(" @context
-      ")" @context)) @item
-
-(public_field_definition
-    [
-        "declare"
-        "readonly"
-        "abstract"
-        "static"
-        (accessibility_modifier)
-    ]* @context
-    name: (_) @name) @item

crates/zed2/src/languages/javascript/overrides.scm 🔗

@@ -1,18 +0,0 @@
-(comment) @comment
-
-[
-  (string)
-  (template_string)
-] @string
-
-[
-  (jsx_element)
-  (jsx_fragment)
-] @element
-
-[
-  (jsx_opening_element)
-  (jsx_closing_element)
-  (jsx_self_closing_element)
-  (jsx_expression)
-] @default

crates/zed2/src/languages/json.rs 🔗

@@ -1,185 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use collections::HashMap;
-use feature_flags::FeatureFlagAppExt;
-use futures::{future::BoxFuture, FutureExt, StreamExt};
-use gpui::AppContext;
-use language::{LanguageRegistry, LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-use serde_json::json;
-use settings::{KeymapFile, SettingsJsonSchemaParams, SettingsStore};
-use smol::fs;
-use std::{
-    any::Any,
-    ffi::OsString,
-    future,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::{paths, ResultExt};
-
-const SERVER_PATH: &'static str =
-    "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver";
-
-fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct JsonLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-    languages: Arc<LanguageRegistry>,
-}
-
-impl JsonLspAdapter {
-    pub fn new(node: Arc<dyn NodeRuntime>, languages: Arc<LanguageRegistry>) -> Self {
-        JsonLspAdapter { node, languages }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for JsonLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("json-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "json"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        Ok(Box::new(
-            self.node
-                .npm_package_latest_version("vscode-json-languageserver")
-                .await?,
-        ) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<String>().unwrap();
-        let server_path = container_dir.join(SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("vscode-json-languageserver", version.as_str())],
-                )
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        Some(json!({
-            "provideFormatter": true
-        }))
-    }
-
-    fn workspace_configuration(
-        &self,
-        _workspace_root: &Path,
-        cx: &mut AppContext,
-    ) -> BoxFuture<'static, serde_json::Value> {
-        let action_names = cx.all_action_names();
-        let staff_mode = cx.is_staff();
-        let language_names = &self.languages.language_names();
-        let settings_schema = cx.global::<SettingsStore>().json_schema(
-            &SettingsJsonSchemaParams {
-                language_names,
-                staff_mode,
-            },
-            cx,
-        );
-
-        future::ready(serde_json::json!({
-            "json": {
-                "format": {
-                    "enable": true,
-                },
-                "schemas": [
-                    {
-                        "fileMatch": [
-                            schema_file_match(&paths::SETTINGS),
-                            &*paths::LOCAL_SETTINGS_RELATIVE_PATH,
-                        ],
-                        "schema": settings_schema,
-                    },
-                    {
-                        "fileMatch": [schema_file_match(&paths::KEYMAP)],
-                        "schema": KeymapFile::generate_json_schema(&action_names),
-                    }
-                ]
-            }
-        }))
-        .boxed()
-    }
-
-    async fn language_ids(&self) -> HashMap<String, String> {
-        [("JSON".into(), "jsonc".into())].into_iter().collect()
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(SERVER_PATH);
-        if server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: server_binary_arguments(&server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}
-
-fn schema_file_match(path: &Path) -> &Path {
-    path.strip_prefix(path.parent().unwrap().parent().unwrap())
-        .unwrap()
-}

crates/zed2/src/languages/json/config.toml 🔗

@@ -1,10 +0,0 @@
-name = "JSON"
-path_suffixes = ["json"]
-line_comment = "// "
-autoclose_before = ",]}"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-]
-prettier_parser_name = "json"

crates/zed2/src/languages/json/embedding.scm 🔗

@@ -1,14 +0,0 @@
-; Only produce one embedding for the entire file.
-(document) @item
-
-; Collapse arrays, except for the first object.
-(array
-  "[" @keep
-  .
-  (object)? @keep
-  "]" @keep) @collapse
-
-; Collapse string values (but not keys).
-(pair value: (string
-  "\"" @keep
-  "\"" @keep) @collapse)

crates/zed2/src/languages/json/highlights.scm 🔗

@@ -1,21 +0,0 @@
-(comment) @comment
-
-(string) @string
-
-(pair
-  key: (string) @property)
-
-(number) @number
-
-[
-  (true)
-  (false)
-  (null)
-] @constant
-
-[
-  "{"
-  "}"
-  "["
-  "]"
-] @punctuation.bracket

crates/zed2/src/languages/language_plugin.rs 🔗

@@ -1,168 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use collections::HashMap;
-use futures::lock::Mutex;
-use gpui::executor::Background;
-use language2::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp2::LanguageServerBinary;
-use plugin_runtime::{Plugin, PluginBinary, PluginBuilder, WasiFn};
-use std::{any::Any, path::PathBuf, sync::Arc};
-use util::ResultExt;
-
-#[allow(dead_code)]
-pub async fn new_json(executor: Arc<Background>) -> Result<PluginLspAdapter> {
-    let plugin = PluginBuilder::new_default()?
-        .host_function_async("command", |command: String| async move {
-            let mut args = command.split(' ');
-            let command = args.next().unwrap();
-            smol::process::Command::new(command)
-                .args(args)
-                .output()
-                .await
-                .log_err()
-                .map(|output| output.stdout)
-        })?
-        .init(PluginBinary::Precompiled(include_bytes!(
-            "../../../../plugins/bin/json_language.wasm.pre",
-        )))
-        .await?;
-
-    PluginLspAdapter::new(plugin, executor).await
-}
-
-pub struct PluginLspAdapter {
-    name: WasiFn<(), String>,
-    fetch_latest_server_version: WasiFn<(), Option<String>>,
-    fetch_server_binary: WasiFn<(PathBuf, String), Result<LanguageServerBinary, String>>,
-    cached_server_binary: WasiFn<PathBuf, Option<LanguageServerBinary>>,
-    initialization_options: WasiFn<(), String>,
-    language_ids: WasiFn<(), Vec<(String, String)>>,
-    executor: Arc<Background>,
-    runtime: Arc<Mutex<Plugin>>,
-}
-
-impl PluginLspAdapter {
-    #[allow(unused)]
-    pub async fn new(mut plugin: Plugin, executor: Arc<Background>) -> Result<Self> {
-        Ok(Self {
-            name: plugin.function("name")?,
-            fetch_latest_server_version: plugin.function("fetch_latest_server_version")?,
-            fetch_server_binary: plugin.function("fetch_server_binary")?,
-            cached_server_binary: plugin.function("cached_server_binary")?,
-            initialization_options: plugin.function("initialization_options")?,
-            language_ids: plugin.function("language_ids")?,
-            executor,
-            runtime: Arc::new(Mutex::new(plugin)),
-        })
-    }
-}
-
-#[async_trait]
-impl LspAdapter for PluginLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        let name: String = self
-            .runtime
-            .lock()
-            .await
-            .call(&self.name, ())
-            .await
-            .unwrap();
-        LanguageServerName(name.into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "PluginLspAdapter"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        let runtime = self.runtime.clone();
-        let function = self.fetch_latest_server_version;
-        self.executor
-            .spawn(async move {
-                let mut runtime = runtime.lock().await;
-                let versions: Result<Option<String>> =
-                    runtime.call::<_, Option<String>>(&function, ()).await;
-                versions
-                    .map_err(|e| anyhow!("{}", e))?
-                    .ok_or_else(|| anyhow!("Could not fetch latest server version"))
-                    .map(|v| Box::new(v) as Box<_>)
-            })
-            .await
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = *version.downcast::<String>().unwrap();
-        let runtime = self.runtime.clone();
-        let function = self.fetch_server_binary;
-        self.executor
-            .spawn(async move {
-                let mut runtime = runtime.lock().await;
-                let handle = runtime.attach_path(&container_dir)?;
-                let result: Result<LanguageServerBinary, String> =
-                    runtime.call(&function, (container_dir, version)).await?;
-                runtime.remove_resource(handle)?;
-                result.map_err(|e| anyhow!("{}", e))
-            })
-            .await
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        let runtime = self.runtime.clone();
-        let function = self.cached_server_binary;
-
-        self.executor
-            .spawn(async move {
-                let mut runtime = runtime.lock().await;
-                let handle = runtime.attach_path(&container_dir).ok()?;
-                let result: Option<LanguageServerBinary> =
-                    runtime.call(&function, container_dir).await.ok()?;
-                runtime.remove_resource(handle).ok()?;
-                result
-            })
-            .await
-    }
-
-    fn can_be_reinstalled(&self) -> bool {
-        false
-    }
-
-    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
-        None
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        let string: String = self
-            .runtime
-            .lock()
-            .await
-            .call(&self.initialization_options, ())
-            .await
-            .log_err()?;
-
-        serde_json::from_str(&string).ok()
-    }
-
-    async fn language_ids(&self) -> HashMap<String, String> {
-        self.runtime
-            .lock()
-            .await
-            .call(&self.language_ids, ())
-            .await
-            .log_err()
-            .unwrap_or_default()
-            .into_iter()
-            .collect()
-    }
-}

crates/zed2/src/languages/lua.rs 🔗

@@ -1,135 +0,0 @@
-use anyhow::{anyhow, bail, Result};
-use async_compression::futures::bufread::GzipDecoder;
-use async_tar::Archive;
-use async_trait::async_trait;
-use futures::{io::BufReader, StreamExt};
-use language::{LanguageServerName, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use smol::fs;
-use std::{any::Any, env::consts, path::PathBuf};
-use util::{
-    async_maybe,
-    github::{latest_github_release, GitHubLspBinaryVersion},
-    ResultExt,
-};
-
-#[derive(Copy, Clone)]
-pub struct LuaLspAdapter;
-
-#[async_trait]
-impl super::LspAdapter for LuaLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("lua-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "lua"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        let release =
-            latest_github_release("LuaLS/lua-language-server", false, delegate.http_client())
-                .await?;
-        let version = release.name.clone();
-        let platform = match consts::ARCH {
-            "x86_64" => "x64",
-            "aarch64" => "arm64",
-            other => bail!("Running on unsupported platform: {other}"),
-        };
-        let asset_name = format!("lua-language-server-{version}-darwin-{platform}.tar.gz");
-        let asset = release
-            .assets
-            .iter()
-            .find(|asset| asset.name == asset_name)
-            .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
-        let version = GitHubLspBinaryVersion {
-            name: release.name.clone(),
-            url: asset.browser_download_url.clone(),
-        };
-        Ok(Box::new(version) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
-
-        let binary_path = container_dir.join("bin/lua-language-server");
-
-        if fs::metadata(&binary_path).await.is_err() {
-            let mut response = delegate
-                .http_client()
-                .get(&version.url, Default::default(), true)
-                .await
-                .map_err(|err| anyhow!("error downloading release: {}", err))?;
-            let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
-            let archive = Archive::new(decompressed_bytes);
-            archive.unpack(container_dir).await?;
-        }
-
-        fs::set_permissions(
-            &binary_path,
-            <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-        )
-        .await?;
-        Ok(LanguageServerBinary {
-            path: binary_path,
-            arguments: Vec::new(),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir)
-            .await
-            .map(|mut binary| {
-                binary.arguments = vec!["--version".into()];
-                binary
-            })
-    }
-}
-
-async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
-    async_maybe!({
-        let mut last_binary_path = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_file()
-                && entry
-                    .file_name()
-                    .to_str()
-                    .map_or(false, |name| name == "lua-language-server")
-            {
-                last_binary_path = Some(entry.path());
-            }
-        }
-
-        if let Some(path) = last_binary_path {
-            Ok(LanguageServerBinary {
-                path,
-                arguments: Vec::new(),
-            })
-        } else {
-            Err(anyhow!("no cached binary"))
-        }
-    })
-    .await
-    .log_err()
-}

crates/zed2/src/languages/lua/config.toml 🔗

@@ -1,10 +0,0 @@
-name = "Lua"
-path_suffixes = ["lua"]
-line_comment = "-- "
-autoclose_before = ",]}"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-]
-collapsed_placeholder = "--[ ... ]--"

crates/zed2/src/languages/lua/highlights.scm 🔗

@@ -1,198 +0,0 @@
-;; Keywords
-
-"return" @keyword
-
-[
- "goto"
- "in"
- "local"
-] @keyword
-
-(break_statement) @keyword
-
-(do_statement
-[
-  "do"
-  "end"
-] @keyword)
-
-(while_statement
-[
-  "while"
-  "do"
-  "end"
-] @keyword)
-
-(repeat_statement
-[
-  "repeat"
-  "until"
-] @keyword)
-
-(if_statement
-[
-  "if"
-  "elseif"
-  "else"
-  "then"
-  "end"
-] @keyword)
-
-(elseif_statement
-[
-  "elseif"
-  "then"
-  "end"
-] @keyword)
-
-(else_statement
-[
-  "else"
-  "end"
-] @keyword)
-
-(for_statement
-[
-  "for"
-  "do"
-  "end"
-] @keyword)
-
-(function_declaration
-[
-  "function"
-  "end"
-] @keyword)
-
-(function_definition
-[
-  "function"
-  "end"
-] @keyword)
-
-;; Operators
-
-[
- "and"
- "not"
- "or"
-] @operator
-
-[
-  "+"
-  "-"
-  "*"
-  "/"
-  "%"
-  "^"
-  "#"
-  "=="
-  "~="
-  "<="
-  ">="
-  "<"
-  ">"
-  "="
-  "&"
-  "~"
-  "|"
-  "<<"
-  ">>"
-  "//"
-  ".."
-] @operator
-
-;; Punctuations
-
-[
-  ";"
-  ":"
-  ","
-  "."
-] @punctuation.delimiter
-
-;; Brackets
-
-[
- "("
- ")"
- "["
- "]"
- "{"
- "}"
-] @punctuation.bracket
-
-;; Variables
-
-(identifier) @variable
-
-((identifier) @variable.special
- (#eq? @variable.special "self"))
-
-(variable_list
-   attribute: (attribute
-     (["<" ">"] @punctuation.bracket
-      (identifier) @attribute)))
-
-;; Constants
-
-((identifier) @constant
- (#match? @constant "^[A-Z][A-Z_0-9]*$"))
-
-(vararg_expression) @constant
-
-(nil) @constant.builtin
-
-[
-  (false)
-  (true)
-] @boolean
-
-;; Tables
-
-(field name: (identifier) @field)
-
-(dot_index_expression field: (identifier) @field)
-
-(table_constructor
-[
-  "{"
-  "}"
-] @constructor)
-
-;; Functions
-
-(parameters (identifier) @parameter)
-
-(function_call
-  name: [
-    (identifier) @function
-    (dot_index_expression field: (identifier) @function)
-  ])
-
-(function_declaration
-  name: [
-    (identifier) @function.definition
-    (dot_index_expression field: (identifier) @function.definition)
-  ])
-
-(method_index_expression method: (identifier) @method)
-
-(function_call
-  (identifier) @function.builtin
-  (#any-of? @function.builtin
-    ;; built-in functions in Lua 5.1
-    "assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs"
-    "load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print"
-    "rawequal" "rawget" "rawset" "require" "select" "setfenv" "setmetatable"
-    "tonumber" "tostring" "type" "unpack" "xpcall"))
-
-;; Others
-
-(comment) @comment
-
-(hash_bang_line) @preproc
-
-(number) @number
-
-(string) @string

crates/zed2/src/languages/lua/indents.scm 🔗

@@ -1,10 +0,0 @@
-(if_statement "end" @end) @indent
-(do_statement "end" @end) @indent
-(while_statement "end" @end) @indent
-(for_statement "end" @end) @indent
-(repeat_statement "until" @end) @indent
-(function_declaration "end" @end) @indent
-
-(_ "[" "]" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent

crates/zed2/src/languages/markdown/config.toml 🔗

@@ -1,11 +0,0 @@
-name = "Markdown"
-path_suffixes = ["md", "mdx"]
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = true, newline = true },
-    { start = "\"", end = "\"", close = false, newline = false },
-    { start = "'", end = "'", close = false, newline = false },
-    { start = "`", end = "`", close = false, newline = false },
-]

crates/zed2/src/languages/markdown/highlights.scm 🔗

@@ -1,24 +0,0 @@
-(emphasis) @emphasis
-(strong_emphasis) @emphasis.strong
-
-[
-  (atx_heading)
-  (setext_heading)
-] @title
-
-[
-  (list_marker_plus)
-  (list_marker_minus)
-  (list_marker_star)
-  (list_marker_dot)
-  (list_marker_parenthesis)
-] @punctuation.list_marker
-
-(code_span) @text.literal
-
-(fenced_code_block
-  (info_string
-    (language) @text.literal))
-
-(link_destination) @link_uri
-(link_text) @link_text

crates/zed2/src/languages/nix/config.toml 🔗

@@ -1,11 +0,0 @@
-name = "Nix"
-path_suffixes = ["nix"]
-line_comment = "# "
-block_comment = ["/* ", " */"]
-autoclose_before = ";:.,=}])>` \n\t\""
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = true, newline = true },
-]

crates/zed2/src/languages/nix/highlights.scm 🔗

@@ -1,95 +0,0 @@
-(comment) @comment
-
-[
-  "if"
-  "then"
-  "else"
-  "let"
-  "inherit"
-  "in"
-  "rec"
-  "with"
-  "assert"
-  "or"
-] @keyword
-
-[
- (string_expression)
- (indented_string_expression)
-] @string
-
-[
-  (path_expression)
-  (hpath_expression)
-  (spath_expression)
-] @string.special.path
-
-(uri_expression) @link_uri
-
-[
-  (integer_expression)
-  (float_expression)
-] @number
-
-(interpolation
-  "${" @punctuation.special
-  "}" @punctuation.special) @embedded
-
-(escape_sequence) @escape
-(dollar_escape) @escape
-
-(function_expression
-  universal: (identifier) @parameter
-)
-
-(formal
-  name: (identifier) @parameter
-  "?"? @punctuation.delimiter)
-
-(select_expression
-  attrpath: (attrpath (identifier)) @property)
-
-(apply_expression
-  function: [
-    (variable_expression (identifier)) @function
-    (select_expression
-      attrpath: (attrpath
-        attr: (identifier) @function .))])
-
-(unary_expression
-  operator: _ @operator)
-
-(binary_expression
-  operator: _ @operator)
-
-(variable_expression (identifier) @variable)
-
-(binding
-  attrpath: (attrpath (identifier)) @property)
-
-"=" @operator
-
-[
-  ";"
-  "."
-  ","
-] @punctuation.delimiter
-
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-] @punctuation.bracket
-
-(identifier) @variable
-
-((identifier) @function.builtin

crates/zed2/src/languages/nu.rs 🔗

@@ -1,55 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use std::{any::Any, path::PathBuf};
-
-pub struct NuLanguageServer;
-
-#[async_trait]
-impl LspAdapter for NuLanguageServer {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("nu".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "nu"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(()))
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        _version: Box<dyn 'static + Send + Any>,
-        _container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        Err(anyhow!(
-            "nu v0.87.0 or greater must be installed and available in your $PATH"
-        ))
-    }
-
-    async fn cached_server_binary(
-        &self,
-        _: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        Some(LanguageServerBinary {
-            path: "nu".into(),
-            arguments: vec!["--lsp".into()],
-        })
-    }
-
-    fn can_be_reinstalled(&self) -> bool {
-        false
-    }
-
-    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
-        None
-    }
-}

crates/zed2/src/languages/nu/config.toml 🔗

@@ -1,9 +0,0 @@
-name = "Nu"
-path_suffixes = ["nu"]
-line_comment = "# "
-autoclose_before = ";:.,=}])>` \n\t\""
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-]

crates/zed2/src/languages/nu/highlights.scm 🔗

@@ -1,302 +0,0 @@
-;;; ---
-;;; keywords
-[
-    "def"
-    "def-env"
-    "alias"
-    "export-env"
-    "export"
-    "extern"
-    "module"
-
-    "let"
-    "let-env"
-    "mut"
-    "const"
-
-    "hide-env"
-
-    "source"
-    "source-env"
-
-    "overlay"
-    "register"
-
-    "loop"
-    "while"
-    "error"
-
-    "do"
-    "if"
-    "else"
-    "try"
-    "catch"
-    "match"
-
-    "break"
-    "continue"
-    "return"
-
-] @keyword
-
-(hide_mod "hide" @keyword)
-(decl_use "use" @keyword)
-
-(ctrl_for
-    "for" @keyword
-    "in" @keyword
-)
-(overlay_list "list" @keyword)
-(overlay_hide "hide" @keyword)
-(overlay_new "new" @keyword)
-(overlay_use
-    "use" @keyword
-    "as" @keyword
-)
-(ctrl_error "make" @keyword)
-
-;;; ---
-;;; literals
-(val_number) @constant
-(val_duration
-    unit: [
-        "ns" "µs" "us" "ms" "sec" "min" "hr" "day" "wk"
-    ] @variable
-)
-(val_filesize
-    unit: [
-        "b" "B"
-
-        "kb" "kB" "Kb" "KB"
-        "mb" "mB" "Mb" "MB"
-        "gb" "gB" "Gb" "GB"
-        "tb" "tB" "Tb" "TB"
-        "pb" "pB" "Pb" "PB"
-        "eb" "eB" "Eb" "EB"
-        "zb" "zB" "Zb" "ZB"
-
-        "kib" "kiB" "kIB" "kIb" "Kib" "KIb" "KIB"
-        "mib" "miB" "mIB" "mIb" "Mib" "MIb" "MIB"
-        "gib" "giB" "gIB" "gIb" "Gib" "GIb" "GIB"
-        "tib" "tiB" "tIB" "tIb" "Tib" "TIb" "TIB"
-        "pib" "piB" "pIB" "pIb" "Pib" "PIb" "PIB"
-        "eib" "eiB" "eIB" "eIb" "Eib" "EIb" "EIB"
-        "zib" "ziB" "zIB" "zIb" "Zib" "ZIb" "ZIB"
-    ] @variable
-)
-(val_binary
-    [
-       "0b"
-       "0o"
-       "0x"
-    ] @constant
-    "[" @punctuation.bracket
-    digit: [
-        "," @punctuation.delimiter
-        (hex_digit) @constant
-    ]
-    "]" @punctuation.bracket
-) @constant
-(val_bool) @constant.builtin
-(val_nothing) @constant.builtin
-(val_string) @string
-(val_date) @constant
-(inter_escape_sequence) @constant
-(escape_sequence) @constant
-(val_interpolated [
-    "$\""
-    "$\'"
-    "\""
-    "\'"
-] @string)
-(unescaped_interpolated_content) @string
-(escaped_interpolated_content) @string
-(expr_interpolated ["(" ")"] @variable)
-
-;;; ---
-;;; operators
-(expr_binary [
-    "+"
-    "-"
-    "*"
-    "/"
-    "mod"
-    "//"
-    "++"
-    "**"
-    "=="
-    "!="
-    "<"
-    "<="
-    ">"
-    ">="
-    "=~"
-    "!~"
-    "and"
-    "or"
-    "xor"
-    "bit-or"
-    "bit-xor"
-    "bit-and"
-    "bit-shl"
-    "bit-shr"
-    "in"
-    "not-in"
-    "starts-with"
-    "ends-with"
-] @operator)
-
-(expr_binary opr: ([
-    "and"
-    "or"
-    "xor"
-    "bit-or"
-    "bit-xor"
-    "bit-and"
-    "bit-shl"
-    "bit-shr"
-    "in"
-    "not-in"
-    "starts-with"
-    "ends-with"
-]) @keyword)
-
-(where_command [
-    "+"
-    "-"
-    "*"
-    "/"
-    "mod"
-    "//"
-    "++"
-    "**"
-    "=="
-    "!="
-    "<"
-    "<="
-    ">"
-    ">="
-    "=~"
-    "!~"
-    "and"
-    "or"
-    "xor"
-    "bit-or"
-    "bit-xor"
-    "bit-and"
-    "bit-shl"
-    "bit-shr"
-    "in"
-    "not-in"
-    "starts-with"
-    "ends-with"
-] @operator)
-
-(assignment [
-    "="
-    "+="
-    "-="
-    "*="
-    "/="
-    "++="
-] @operator)
-
-(expr_unary ["not" "-"] @operator)
-
-(val_range [
-    ".."
-    "..="
-    "..<"
-] @operator)
-
-["=>" "=" "|"] @operator
-
-[
-    "o>"   "out>"
-    "e>"   "err>"
-    "e+o>" "err+out>"
-    "o+e>" "out+err>"
-] @special
-
-;;; ---
-;;; punctuation
-[
-    ","
-    ";"
-] @punctuation.delimiter
-
-(param_short_flag "-" @punctuation.delimiter)
-(param_long_flag ["--"] @punctuation.delimiter)
-(long_flag ["--"] @punctuation.delimiter)
-(param_rest "..." @punctuation.delimiter)
-(param_type [":"] @punctuation.special)
-(param_value ["="] @punctuation.special)
-(param_cmd ["@"] @punctuation.special)
-(param_opt ["?"] @punctuation.special)
-
-[
-    "(" ")"
-    "{" "}"
-    "[" "]"
-] @punctuation.bracket
-
-(val_record
-  (record_entry ":" @punctuation.delimiter))
-;;; ---
-;;; identifiers
-(param_rest
-    name: (_) @variable)
-(param_opt
-    name: (_) @variable)
-(parameter
-    param_name: (_) @variable)
-(param_cmd
-    (cmd_identifier) @string)
-(param_long_flag) @variable
-(param_short_flag) @variable
-
-(short_flag) @variable
-(long_flag) @variable
-
-(scope_pattern [(wild_card) @function])
-
-(cmd_identifier) @function
-
-(command
-    "^" @punctuation.delimiter
-    head: (_) @function
-)
-
-"where" @function
-
-(path
-  ["." "?"] @punctuation.delimiter
-) @variable
-
-(val_variable
-  "$" @operator
-  [
-   (identifier) @variable
-   "in" @type.builtin
-   "nu" @type.builtin
-   "env" @type.builtin
-   "nothing" @type.builtin
-   ]  ; If we have a special styling, use it here
-)
-;;; ---
-;;; types
-(flat_type) @type.builtin
-(list_type
-    "list" @type
-    ["<" ">"] @punctuation.bracket
-)
-(collection_type
-    ["record" "table"] @type
-    "<" @punctuation.bracket
-    key: (_) @variable
-    ["," ":"] @punctuation.delimiter
-    ">" @punctuation.bracket
-)
-
-(shebang) @comment
-(comment) @comment

crates/zed2/src/languages/php.rs 🔗

@@ -1,136 +0,0 @@
-use anyhow::{anyhow, Result};
-
-use async_trait::async_trait;
-use collections::HashMap;
-
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-
-use smol::{fs, stream::StreamExt};
-use std::{
-    any::Any,
-    ffi::OsString,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-fn intelephense_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct IntelephenseVersion(String);
-
-pub struct IntelephenseLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl IntelephenseLspAdapter {
-    const SERVER_PATH: &'static str = "node_modules/intelephense/lib/intelephense.js";
-
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        Self { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for IntelephenseLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("intelephense".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "php"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        Ok(Box::new(IntelephenseVersion(
-            self.node.npm_package_latest_version("intelephense").await?,
-        )) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<IntelephenseVersion>().unwrap();
-        let server_path = container_dir.join(Self::SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(&container_dir, &[("intelephense", version.0.as_str())])
-                .await?;
-        }
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: intelephense_server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn label_for_completion(
-        &self,
-        _item: &lsp::CompletionItem,
-        _language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        None
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        None
-    }
-    async fn language_ids(&self) -> HashMap<String, String> {
-        HashMap::from_iter([("PHP".into(), "php".into())])
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(IntelephenseLspAdapter::SERVER_PATH);
-        if server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: intelephense_server_binary_arguments(&server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}

crates/zed2/src/languages/php/config.toml 🔗

@@ -1,14 +0,0 @@
-name = "PHP"
-path_suffixes = ["php"]
-first_line_pattern = '^#!.*php'
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-]
-collapsed_placeholder = "/* ... */"
-word_characters = ["$"]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]

crates/zed2/src/languages/php/embedding.scm 🔗

@@ -1,36 +0,0 @@
-(
-    (comment)* @context
-    .
-    [
-        (function_definition
-            "function" @name
-            name: (_) @name
-            body: (_
-                "{" @keep
-                "}" @keep) @collapse
-            )
-
-        (trait_declaration
-            "trait" @name
-            name: (_) @name)
-
-        (method_declaration
-            "function" @name
-            name: (_) @name
-            body: (_
-                "{" @keep
-                "}" @keep) @collapse
-            )
-
-        (interface_declaration
-            "interface" @name
-            name: (_) @name
-            )
-
-        (enum_declaration
-            "enum" @name
-            name: (_) @name
-            )
-
-        ] @item
-    )

crates/zed2/src/languages/php/highlights.scm 🔗

@@ -1,123 +0,0 @@
-(php_tag) @tag
-"?>" @tag
-
-; Types
-
-(primitive_type) @type.builtin
-(cast_type) @type.builtin
-(named_type (name) @type) @type
-(named_type (qualified_name) @type) @type
-
-; Functions
-
-(array_creation_expression "array" @function.builtin)
-(list_literal "list" @function.builtin)
-
-(method_declaration
-  name: (name) @function.method)
-
-(function_call_expression
-  function: [(qualified_name (name)) (name)] @function)
-
-(scoped_call_expression
-  name: (name) @function)
-
-(member_call_expression
-  name: (name) @function.method)
-
-(function_definition
-  name: (name) @function)
-
-; Member
-
-(property_element
-  (variable_name) @property)
-
-(member_access_expression
-  name: (variable_name (name)) @property)
-(member_access_expression
-  name: (name) @property)
-
-; Variables
-
-(relative_scope) @variable.builtin
-
-((name) @constant
- (#match? @constant "^_?[A-Z][A-Z\\d_]+$"))
-((name) @constant.builtin
- (#match? @constant.builtin "^__[A-Z][A-Z\d_]+__$"))
-
-((name) @constructor
- (#match? @constructor "^[A-Z]"))
-
-((name) @variable.builtin
- (#eq? @variable.builtin "this"))
-
-(variable_name) @variable
-
-; Basic tokens
-[
-  (string)
-  (string_value)
-  (encapsed_string)
-  (heredoc)
-  (heredoc_body)
-  (nowdoc_body)
-] @string
-(boolean) @constant.builtin
-(null) @constant.builtin
-(integer) @number
-(float) @number
-(comment) @comment
-
-"$" @operator
-
-; Keywords
-
-"abstract" @keyword
-"as" @keyword
-"break" @keyword
-"case" @keyword
-"catch" @keyword
-"class" @keyword
-"const" @keyword
-"continue" @keyword
-"declare" @keyword
-"default" @keyword
-"do" @keyword
-"echo" @keyword
-"else" @keyword
-"elseif" @keyword
-"enum" @keyword
-"enddeclare" @keyword
-"endforeach" @keyword
-"endif" @keyword
-"endswitch" @keyword
-"endwhile" @keyword
-"extends" @keyword
-"final" @keyword
-"finally" @keyword
-"foreach" @keyword
-"function" @keyword
-"global" @keyword
-"if" @keyword
-"implements" @keyword
-"include_once" @keyword
-"include" @keyword
-"insteadof" @keyword
-"interface" @keyword
-"namespace" @keyword
-"new" @keyword
-"private" @keyword
-"protected" @keyword
-"public" @keyword
-"require_once" @keyword
-"require" @keyword
-"return" @keyword
-"static" @keyword
-"switch" @keyword
-"throw" @keyword
-"trait" @keyword
-"try" @keyword
-"use" @keyword
-"while" @keyword

crates/zed2/src/languages/php/outline.scm 🔗

@@ -1,29 +0,0 @@
-(class_declaration
-    "class" @context
-    name: (name) @name
-    ) @item
-
-(function_definition
-    "function" @context
-    name: (_) @name
-    ) @item
-
-(method_declaration
-    "function" @context
-    name: (_) @name
-    ) @item
-
-(interface_declaration
-    "interface" @context
-    name: (_) @name
-    ) @item
-
-(enum_declaration
-    "enum" @context
-    name: (_) @name
-    ) @item
-
-(trait_declaration
-    "trait" @context
-    name: (_) @name
-    ) @item

crates/zed2/src/languages/php/tags.scm 🔗

@@ -1,40 +0,0 @@
-(namespace_definition
-  name: (namespace_name) @name) @module
-
-(interface_declaration
-  name: (name) @name) @definition.interface
-
-(trait_declaration
-  name: (name) @name) @definition.interface
-
-(class_declaration
-  name: (name) @name) @definition.class
-
-(class_interface_clause [(name) (qualified_name)] @name) @impl
-
-(property_declaration
-  (property_element (variable_name (name) @name))) @definition.field
-
-(function_definition
-  name: (name) @name) @definition.function
-
-(method_declaration
-  name: (name) @name) @definition.function
-
-(object_creation_expression
-  [
-    (qualified_name (name) @name)
-    (variable_name (name) @name)
-  ]) @reference.class
-
-(function_call_expression
-  function: [
-    (qualified_name (name) @name)
-    (variable_name (name)) @name
-  ]) @reference.call
-
-(scoped_call_expression
-  name: (name) @name) @reference.call
-
-(member_call_expression
-  name: (name) @name) @reference.call

crates/zed2/src/languages/python.rs 🔗

@@ -1,296 +0,0 @@
-use anyhow::Result;
-use async_trait::async_trait;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-use smol::fs;
-use std::{
-    any::Any,
-    ffi::OsString,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-const SERVER_PATH: &'static str = "node_modules/pyright/langserver.index.js";
-
-fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct PythonLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl PythonLspAdapter {
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        PythonLspAdapter { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for PythonLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("pyright".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "pyright"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(self.node.npm_package_latest_version("pyright").await?) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<String>().unwrap();
-        let server_path = container_dir.join(SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(&container_dir, &[("pyright", version.as_str())])
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn process_completion(&self, item: &mut lsp::CompletionItem) {
-        // Pyright assigns each completion item a `sortText` of the form `XX.YYYY.name`.
-        // Where `XX` is the sorting category, `YYYY` is based on most recent usage,
-        // and `name` is the symbol name itself.
-        //
-        // Because the the symbol name is included, there generally are not ties when
-        // sorting by the `sortText`, so the symbol's fuzzy match score is not taken
-        // into account. Here, we remove the symbol name from the sortText in order
-        // to allow our own fuzzy score to be used to break ties.
-        //
-        // see https://github.com/microsoft/pyright/blob/95ef4e103b9b2f129c9320427e51b73ea7cf78bd/packages/pyright-internal/src/languageService/completionProvider.ts#LL2873
-        let Some(sort_text) = &mut item.sort_text else {
-            return;
-        };
-        let mut parts = sort_text.split('.');
-        let Some(first) = parts.next() else { return };
-        let Some(second) = parts.next() else { return };
-        let Some(_) = parts.next() else { return };
-        sort_text.replace_range(first.len() + second.len() + 1.., "");
-    }
-
-    async fn label_for_completion(
-        &self,
-        item: &lsp::CompletionItem,
-        language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        let label = &item.label;
-        let grammar = language.grammar()?;
-        let highlight_id = match item.kind? {
-            lsp::CompletionItemKind::METHOD => grammar.highlight_id_for_name("function.method")?,
-            lsp::CompletionItemKind::FUNCTION => grammar.highlight_id_for_name("function")?,
-            lsp::CompletionItemKind::CLASS => grammar.highlight_id_for_name("type")?,
-            lsp::CompletionItemKind::CONSTANT => grammar.highlight_id_for_name("constant")?,
-            _ => return None,
-        };
-        Some(language::CodeLabel {
-            text: label.clone(),
-            runs: vec![(0..label.len(), highlight_id)],
-            filter_range: 0..label.len(),
-        })
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        kind: lsp::SymbolKind,
-        language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        let (text, filter_range, display_range) = match kind {
-            lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => {
-                let text = format!("def {}():\n", name);
-                let filter_range = 4..4 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::CLASS => {
-                let text = format!("class {}:", name);
-                let filter_range = 6..6 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::CONSTANT => {
-                let text = format!("{} = 0", name);
-                let filter_range = 0..name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            _ => return None,
-        };
-
-        Some(language::CodeLabel {
-            runs: language.highlight_text(&text.as_str().into(), display_range.clone()),
-            text: text[display_range].to_string(),
-            filter_range,
-        })
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    let server_path = container_dir.join(SERVER_PATH);
-    if server_path.exists() {
-        Some(LanguageServerBinary {
-            path: node.binary_path().await.log_err()?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    } else {
-        log::error!("missing executable in directory {:?}", server_path);
-        None
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use gpui::{Context, ModelContext, TestAppContext};
-    use language::{language_settings::AllLanguageSettings, AutoindentMode, Buffer};
-    use settings::SettingsStore;
-    use std::num::NonZeroU32;
-
-    #[gpui::test]
-    async fn test_python_autoindent(cx: &mut TestAppContext) {
-        // cx.executor().set_block_on_ticks(usize::MAX..=usize::MAX);
-        let language =
-            crate::languages::language("python", tree_sitter_python::language(), None).await;
-        cx.update(|cx| {
-            let test_settings = SettingsStore::test(cx);
-            cx.set_global(test_settings);
-            language::init(cx);
-            cx.update_global::<SettingsStore, _>(|store, cx| {
-                store.update_user_settings::<AllLanguageSettings>(cx, |s| {
-                    s.defaults.tab_size = NonZeroU32::new(2);
-                });
-            });
-        });
-
-        cx.new_model(|cx| {
-            let mut buffer =
-                Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
-            let append = |buffer: &mut Buffer, text: &str, cx: &mut ModelContext<Buffer>| {
-                let ix = buffer.len();
-                buffer.edit([(ix..ix, text)], Some(AutoindentMode::EachLine), cx);
-            };
-
-            // indent after "def():"
-            append(&mut buffer, "def a():\n", cx);
-            assert_eq!(buffer.text(), "def a():\n  ");
-
-            // preserve indent after blank line
-            append(&mut buffer, "\n  ", cx);
-            assert_eq!(buffer.text(), "def a():\n  \n  ");
-
-            // indent after "if"
-            append(&mut buffer, "if a:\n  ", cx);
-            assert_eq!(buffer.text(), "def a():\n  \n  if a:\n    ");
-
-            // preserve indent after statement
-            append(&mut buffer, "b()\n", cx);
-            assert_eq!(buffer.text(), "def a():\n  \n  if a:\n    b()\n    ");
-
-            // preserve indent after statement
-            append(&mut buffer, "else", cx);
-            assert_eq!(buffer.text(), "def a():\n  \n  if a:\n    b()\n    else");
-
-            // dedent "else""
-            append(&mut buffer, ":", cx);
-            assert_eq!(buffer.text(), "def a():\n  \n  if a:\n    b()\n  else:");
-
-            // indent lines after else
-            append(&mut buffer, "\n", cx);
-            assert_eq!(
-                buffer.text(),
-                "def a():\n  \n  if a:\n    b()\n  else:\n    "
-            );
-
-            // indent after an open paren. the closing  paren is not indented
-            // because there is another token before it on the same line.
-            append(&mut buffer, "foo(\n1)", cx);
-            assert_eq!(
-                buffer.text(),
-                "def a():\n  \n  if a:\n    b()\n  else:\n    foo(\n      1)"
-            );
-
-            // dedent the closing paren if it is shifted to the beginning of the line
-            let argument_ix = buffer.text().find('1').unwrap();
-            buffer.edit(
-                [(argument_ix..argument_ix + 1, "")],
-                Some(AutoindentMode::EachLine),
-                cx,
-            );
-            assert_eq!(
-                buffer.text(),
-                "def a():\n  \n  if a:\n    b()\n  else:\n    foo(\n    )"
-            );
-
-            // preserve indent after the close paren
-            append(&mut buffer, "\n", cx);
-            assert_eq!(
-                buffer.text(),
-                "def a():\n  \n  if a:\n    b()\n  else:\n    foo(\n    )\n    "
-            );
-
-            // manually outdent the last line
-            let end_whitespace_ix = buffer.len() - 4;
-            buffer.edit(
-                [(end_whitespace_ix..buffer.len(), "")],
-                Some(AutoindentMode::EachLine),
-                cx,
-            );
-            assert_eq!(
-                buffer.text(),
-                "def a():\n  \n  if a:\n    b()\n  else:\n    foo(\n    )\n"
-            );
-
-            // preserve the newly reduced indentation on the next newline
-            append(&mut buffer, "\n", cx);
-            assert_eq!(
-                buffer.text(),
-                "def a():\n  \n  if a:\n    b()\n  else:\n    foo(\n    )\n\n"
-            );
-
-            // reset to a simple if statement
-            buffer.edit([(0..buffer.len(), "if a:\n  b(\n  )")], None, cx);
-
-            // dedent "else" on the line after a closing paren
-            append(&mut buffer, "\n  else:\n", cx);
-            assert_eq!(buffer.text(), "if a:\n  b(\n  )\nelse:\n  ");
-
-            buffer
-        });
-    }
-}

crates/zed2/src/languages/python/config.toml 🔗

@@ -1,16 +0,0 @@
-name = "Python"
-path_suffixes = ["py", "pyi", "mpy"]
-first_line_pattern = '^#!.*\bpython[0-9.]*\b'
-line_comment = "# "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = false, newline = false, not_in = ["string"] },
-]
-
-auto_indent_using_last_non_empty_line = false
-increase_indent_pattern = ":\\s*$"
-decrease_indent_pattern = "^\\s*(else|elif|except|finally)\\b.*:"

crates/zed2/src/languages/python/highlights.scm 🔗

@@ -1,125 +0,0 @@
-(attribute attribute: (identifier) @property)
-(type (identifier) @type)
-
-; Function calls
-
-(decorator) @function
-
-(call
-  function: (attribute attribute: (identifier) @function.method))
-(call
-  function: (identifier) @function)
-
-; Function definitions
-
-(function_definition
-  name: (identifier) @function)
-
-; Identifier naming conventions
-
-((identifier) @type
- (#match? @type "^[A-Z]"))
-
-((identifier) @constant
- (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
-
-; Builtin functions
-
-((call
-  function: (identifier) @function.builtin)
- (#match?
-   @function.builtin
-   "^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$"))
-
-; Literals
-
-[
-  (none)
-  (true)
-  (false)
-] @constant.builtin
-
-[
-  (integer)
-  (float)
-] @number
-
-(comment) @comment
-(string) @string
-(escape_sequence) @escape
-
-(interpolation
-  "{" @punctuation.special
-  "}" @punctuation.special) @embedded
-
-[
-  "-"
-  "-="
-  "!="
-  "*"
-  "**"
-  "**="
-  "*="
-  "/"
-  "//"
-  "//="
-  "/="
-  "&"
-  "%"
-  "%="
-  "^"
-  "+"
-  "->"
-  "+="
-  "<"
-  "<<"
-  "<="
-  "<>"
-  "="
-  ":="
-  "=="
-  ">"
-  ">="
-  ">>"
-  "|"
-  "~"
-  "and"
-  "in"
-  "is"
-  "not"
-  "or"
-] @operator
-
-[
-  "as"
-  "assert"
-  "async"
-  "await"
-  "break"
-  "class"
-  "continue"
-  "def"
-  "del"
-  "elif"
-  "else"
-  "except"
-  "exec"
-  "finally"
-  "for"
-  "from"
-  "global"
-  "if"
-  "import"
-  "lambda"
-  "nonlocal"
-  "pass"
-  "print"
-  "raise"
-  "return"
-  "try"
-  "while"
-  "with"
-  "yield"
-  "match"
-  "case"
-] @keyword

crates/zed2/src/languages/racket/config.toml 🔗

@@ -1,9 +0,0 @@
-name = "Racket"
-path_suffixes = ["rkt"]
-line_comment = "; "
-autoclose_before = "])"
-brackets = [
-    { start = "[", end = "]", close = true, newline = false },
-    { start = "(", end = ")", close = true, newline = false },
-    { start = "\"", end = "\"", close = true, newline = false },
-]

crates/zed2/src/languages/racket/highlights.scm 🔗

@@ -1,39 +0,0 @@
-["(" ")" "[" "]" "{" "}"] @punctuation.bracket
-
-[(string)
- (here_string)
- (byte_string)] @string
-(regex) @string.regex
-(escape_sequence) @escape
-
-[(comment)
- (block_comment)
- (sexp_comment)] @comment
-
-(symbol) @variable
-
-(number) @number
-(character) @constant.builtin
-(boolean) @constant.builtin
-(keyword) @constant
-(quote . (symbol)) @constant
-
-(extension) @keyword
-(lang_name) @variable.special
-
-((symbol) @operator
- (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
-
-(list
-  .
-  (symbol) @function)
-
-(list
-  .
-  (symbol) @keyword
-  (#match? @keyword

crates/zed2/src/languages/ruby.rs 🔗

@@ -1,160 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use std::{any::Any, path::PathBuf, sync::Arc};
-
-pub struct RubyLanguageServer;
-
-#[async_trait]
-impl LspAdapter for RubyLanguageServer {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("solargraph".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "solargraph"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(()))
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        _version: Box<dyn 'static + Send + Any>,
-        _container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        Err(anyhow!("solargraph must be installed manually"))
-    }
-
-    async fn cached_server_binary(
-        &self,
-        _: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        Some(LanguageServerBinary {
-            path: "solargraph".into(),
-            arguments: vec!["stdio".into()],
-        })
-    }
-
-    fn can_be_reinstalled(&self) -> bool {
-        false
-    }
-
-    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
-        None
-    }
-
-    async fn label_for_completion(
-        &self,
-        item: &lsp::CompletionItem,
-        language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        let label = &item.label;
-        let grammar = language.grammar()?;
-        let highlight_id = match item.kind? {
-            lsp::CompletionItemKind::METHOD => grammar.highlight_id_for_name("function.method")?,
-            lsp::CompletionItemKind::CONSTANT => grammar.highlight_id_for_name("constant")?,
-            lsp::CompletionItemKind::CLASS | lsp::CompletionItemKind::MODULE => {
-                grammar.highlight_id_for_name("type")?
-            }
-            lsp::CompletionItemKind::KEYWORD => {
-                if label.starts_with(':') {
-                    grammar.highlight_id_for_name("string.special.symbol")?
-                } else {
-                    grammar.highlight_id_for_name("keyword")?
-                }
-            }
-            lsp::CompletionItemKind::VARIABLE => {
-                if label.starts_with('@') {
-                    grammar.highlight_id_for_name("property")?
-                } else {
-                    return None;
-                }
-            }
-            _ => return None,
-        };
-        Some(language::CodeLabel {
-            text: label.clone(),
-            runs: vec![(0..label.len(), highlight_id)],
-            filter_range: 0..label.len(),
-        })
-    }
-
-    async fn label_for_symbol(
-        &self,
-        label: &str,
-        kind: lsp::SymbolKind,
-        language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        let grammar = language.grammar()?;
-        match kind {
-            lsp::SymbolKind::METHOD => {
-                let mut parts = label.split('#');
-                let classes = parts.next()?;
-                let method = parts.next()?;
-                if parts.next().is_some() {
-                    return None;
-                }
-
-                let class_id = grammar.highlight_id_for_name("type")?;
-                let method_id = grammar.highlight_id_for_name("function.method")?;
-
-                let mut ix = 0;
-                let mut runs = Vec::new();
-                for (i, class) in classes.split("::").enumerate() {
-                    if i > 0 {
-                        ix += 2;
-                    }
-                    let end_ix = ix + class.len();
-                    runs.push((ix..end_ix, class_id));
-                    ix = end_ix;
-                }
-
-                ix += 1;
-                let end_ix = ix + method.len();
-                runs.push((ix..end_ix, method_id));
-                Some(language::CodeLabel {
-                    text: label.to_string(),
-                    runs,
-                    filter_range: 0..label.len(),
-                })
-            }
-            lsp::SymbolKind::CONSTANT => {
-                let constant_id = grammar.highlight_id_for_name("constant")?;
-                Some(language::CodeLabel {
-                    text: label.to_string(),
-                    runs: vec![(0..label.len(), constant_id)],
-                    filter_range: 0..label.len(),
-                })
-            }
-            lsp::SymbolKind::CLASS | lsp::SymbolKind::MODULE => {
-                let class_id = grammar.highlight_id_for_name("type")?;
-
-                let mut ix = 0;
-                let mut runs = Vec::new();
-                for (i, class) in label.split("::").enumerate() {
-                    if i > 0 {
-                        ix += "::".len();
-                    }
-                    let end_ix = ix + class.len();
-                    runs.push((ix..end_ix, class_id));
-                    ix = end_ix;
-                }
-
-                Some(language::CodeLabel {
-                    text: label.to_string(),
-                    runs,
-                    filter_range: 0..label.len(),
-                })
-            }
-            _ => return None,
-        }
-    }
-}

crates/zed2/src/languages/ruby/brackets.scm 🔗

@@ -1,14 +0,0 @@
-("[" @open "]" @close)
-("{" @open "}" @close)
-("\"" @open "\"" @close)
-("do" @open "end" @close)
-
-(block_parameters "|" @open "|" @close)
-(interpolation "#{" @open "}" @close)
-
-(if "if" @open "end" @close)
-(unless "unless" @open "end" @close)
-(begin "begin" @open "end" @close)
-(module "module" @open "end" @close)
-(_ . "def" @open "end" @close)
-(_ . "class" @open "end" @close)

crates/zed2/src/languages/ruby/config.toml 🔗

@@ -1,13 +0,0 @@
-name = "Ruby"
-path_suffixes = ["rb", "Gemfile"]
-first_line_pattern = '^#!.*\bruby\b'
-line_comment = "# "
-autoclose_before = ";:.,=}])>"
-brackets = [
-  { start = "{", end = "}", close = true, newline = true },
-  { start = "[", end = "]", close = true, newline = true },
-  { start = "(", end = ")", close = true, newline = true },
-  { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
-  { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
-]
-collapsed_placeholder = "# ..."

crates/zed2/src/languages/ruby/embedding.scm 🔗

@@ -1,22 +0,0 @@
-(
-    (comment)* @context
-    .
-    [
-        (module
-            "module" @name
-            name: (_) @name)
-        (method
-            "def" @name
-            name: (_) @name
-            body: (body_statement) @collapse)
-        (class
-            "class" @name
-            name: (_) @name)
-        (singleton_method
-            "def" @name
-            object: (_) @name
-            "." @name
-            name: (_) @name
-            body: (body_statement) @collapse)
-        ] @item
-    )

crates/zed2/src/languages/ruby/highlights.scm 🔗

@@ -1,181 +0,0 @@
-; Keywords
-
-[
-  "alias"
-  "and"
-  "begin"
-  "break"
-  "case"
-  "class"
-  "def"
-  "do"
-  "else"
-  "elsif"
-  "end"
-  "ensure"
-  "for"
-  "if"
-  "in"
-  "module"
-  "next"
-  "or"
-  "rescue"
-  "retry"
-  "return"
-  "then"
-  "unless"
-  "until"
-  "when"
-  "while"
-  "yield"
-] @keyword
-
-(identifier) @variable
-
-((identifier) @keyword
- (#match? @keyword "^(private|protected|public)$"))
-
-; Function calls
-
-((identifier) @function.method.builtin
- (#eq? @function.method.builtin "require"))
-
-"defined?" @function.method.builtin
-
-(call
-  method: [(identifier) (constant)] @function.method)
-
-; Function definitions
-
-(alias (identifier) @function.method)
-(setter (identifier) @function.method)
-(method name: [(identifier) (constant)] @function.method)
-(singleton_method name: [(identifier) (constant)] @function.method)
-
-; Identifiers
-
-[
-  (class_variable)
-  (instance_variable)
-] @property
-
-((identifier) @constant.builtin
- (#match? @constant.builtin "^__(FILE|LINE|ENCODING)__$"))
-
-(file) @constant.builtin
-(line) @constant.builtin
-(encoding) @constant.builtin
-
-(hash_splat_nil
-  "**" @operator
-) @constant.builtin
-
-((constant) @constant
- (#match? @constant "^[A-Z\\d_]+$"))
-
-(constant) @type
-
-(self) @variable.special
-(super) @variable.special
-
-; Literals
-
-[
-  (string)
-  (bare_string)
-  (subshell)
-  (heredoc_body)
-  (heredoc_beginning)
-] @string
-
-[
-  (simple_symbol)
-  (delimited_symbol)
-  (hash_key_symbol)
-  (bare_symbol)
-] @string.special.symbol
-
-(regex) @string.regex
-(escape_sequence) @escape
-
-[
-  (integer)
-  (float)
-] @number
-
-[
-  (nil)
-  (true)
-  (false)
-] @constant.builtin
-
-(comment) @comment
-
-; Operators
-
-[
-  "!"
-  "~"
-  "+"
-  "-"
-  "**"
-  "*"
-  "/"
-  "%"
-  "<<"
-  ">>"
-  "&"
-  "|"
-  "^"
-  ">"
-  "<"
-  "<="
-  ">="
-  "=="
-  "!="
-  "=~"
-  "!~"
-  "<=>"
-  "||"
-  "&&"
-  ".."
-  "..."
-  "="
-  "**="
-  "*="
-  "/="
-  "%="
-  "+="
-  "-="
-  "<<="
-  ">>="
-  "&&="
-  "&="
-  "||="
-  "|="
-  "^="
-  "=>"
-  "->"
-  (operator)
-] @operator
-
-[
-  ","
-  ";"
-  "."
-] @punctuation.delimiter
-
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-  "%w("
-  "%i("
-] @punctuation.bracket
-
-(interpolation
-  "#{" @punctuation.special
-  "}" @punctuation.special) @embedded

crates/zed2/src/languages/ruby/indents.scm 🔗

@@ -1,17 +0,0 @@
-(method "end" @end) @indent
-(class "end" @end) @indent
-(module "end" @end) @indent
-(begin "end" @end) @indent
-(do_block "end" @end) @indent
-
-(then) @indent
-(call) @indent
-
-(ensure) @outdent
-(rescue) @outdent
-(else) @outdent
-
-
-(_ "[" "]" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent

crates/zed2/src/languages/ruby/outline.scm 🔗

@@ -1,17 +0,0 @@
-(class
-    "class" @context
-    name: (_) @name) @item
-
-(method
-    "def" @context
-    name: (_) @name) @item
-
-(singleton_method
-    "def" @context
-    object: (_) @context
-    "." @context
-    name: (_) @name) @item
-
-(module
-    "module" @context
-    name: (_) @name) @item

crates/zed2/src/languages/rust.rs 🔗

@@ -1,568 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_compression::futures::bufread::GzipDecoder;
-use async_trait::async_trait;
-use futures::{io::BufReader, StreamExt};
-pub use language::*;
-use lazy_static::lazy_static;
-use lsp::LanguageServerBinary;
-use regex::Regex;
-use smol::fs::{self, File};
-use std::{any::Any, borrow::Cow, env::consts, path::PathBuf, str, sync::Arc};
-use util::{
-    fs::remove_matching,
-    github::{latest_github_release, GitHubLspBinaryVersion},
-    ResultExt,
-};
-
-pub struct RustLspAdapter;
-
-#[async_trait]
-impl LspAdapter for RustLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("rust-analyzer".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "rust"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        let release =
-            latest_github_release("rust-analyzer/rust-analyzer", false, delegate.http_client())
-                .await?;
-        let asset_name = format!("rust-analyzer-{}-apple-darwin.gz", consts::ARCH);
-        let asset = release
-            .assets
-            .iter()
-            .find(|asset| asset.name == asset_name)
-            .ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
-        Ok(Box::new(GitHubLspBinaryVersion {
-            name: release.name,
-            url: asset.browser_download_url.clone(),
-        }))
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
-        let destination_path = container_dir.join(format!("rust-analyzer-{}", version.name));
-
-        if fs::metadata(&destination_path).await.is_err() {
-            let mut response = delegate
-                .http_client()
-                .get(&version.url, Default::default(), true)
-                .await
-                .map_err(|err| anyhow!("error downloading release: {}", err))?;
-            let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
-            let mut file = File::create(&destination_path).await?;
-            futures::io::copy(decompressed_bytes, &mut file).await?;
-            fs::set_permissions(
-                &destination_path,
-                <fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
-            )
-            .await?;
-
-            remove_matching(&container_dir, |entry| entry != destination_path).await;
-        }
-
-        Ok(LanguageServerBinary {
-            path: destination_path,
-            arguments: Default::default(),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir)
-            .await
-            .map(|mut binary| {
-                binary.arguments = vec!["--help".into()];
-                binary
-            })
-    }
-
-    async fn disk_based_diagnostic_sources(&self) -> Vec<String> {
-        vec!["rustc".into()]
-    }
-
-    async fn disk_based_diagnostics_progress_token(&self) -> Option<String> {
-        Some("rust-analyzer/flycheck".into())
-    }
-
-    fn process_diagnostics(&self, params: &mut lsp::PublishDiagnosticsParams) {
-        lazy_static! {
-            static ref REGEX: Regex = Regex::new("(?m)`([^`]+)\n`$").unwrap();
-        }
-
-        for diagnostic in &mut params.diagnostics {
-            for message in diagnostic
-                .related_information
-                .iter_mut()
-                .flatten()
-                .map(|info| &mut info.message)
-                .chain([&mut diagnostic.message])
-            {
-                if let Cow::Owned(sanitized) = REGEX.replace_all(message, "`$1`") {
-                    *message = sanitized;
-                }
-            }
-        }
-    }
-
-    async fn label_for_completion(
-        &self,
-        completion: &lsp::CompletionItem,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        match completion.kind {
-            Some(lsp::CompletionItemKind::FIELD) if completion.detail.is_some() => {
-                let detail = completion.detail.as_ref().unwrap();
-                let name = &completion.label;
-                let text = format!("{}: {}", name, detail);
-                let source = Rope::from(format!("struct S {{ {} }}", text).as_str());
-                let runs = language.highlight_text(&source, 11..11 + text.len());
-                return Some(CodeLabel {
-                    text,
-                    runs,
-                    filter_range: 0..name.len(),
-                });
-            }
-            Some(lsp::CompletionItemKind::CONSTANT | lsp::CompletionItemKind::VARIABLE)
-                if completion.detail.is_some()
-                    && completion.insert_text_format != Some(lsp::InsertTextFormat::SNIPPET) =>
-            {
-                let detail = completion.detail.as_ref().unwrap();
-                let name = &completion.label;
-                let text = format!("{}: {}", name, detail);
-                let source = Rope::from(format!("let {} = ();", text).as_str());
-                let runs = language.highlight_text(&source, 4..4 + text.len());
-                return Some(CodeLabel {
-                    text,
-                    runs,
-                    filter_range: 0..name.len(),
-                });
-            }
-            Some(lsp::CompletionItemKind::FUNCTION | lsp::CompletionItemKind::METHOD)
-                if completion.detail.is_some() =>
-            {
-                lazy_static! {
-                    static ref REGEX: Regex = Regex::new("\\(…?\\)").unwrap();
-                }
-                let detail = completion.detail.as_ref().unwrap();
-                const FUNCTION_PREFIXES: [&'static str; 2] = ["async fn", "fn"];
-                let prefix = FUNCTION_PREFIXES
-                    .iter()
-                    .find_map(|prefix| detail.strip_prefix(*prefix).map(|suffix| (prefix, suffix)));
-                // fn keyword should be followed by opening parenthesis.
-                if let Some((prefix, suffix)) = prefix {
-                    if suffix.starts_with('(') {
-                        let text = REGEX.replace(&completion.label, suffix).to_string();
-                        let source = Rope::from(format!("{prefix} {} {{}}", text).as_str());
-                        let run_start = prefix.len() + 1;
-                        let runs =
-                            language.highlight_text(&source, run_start..run_start + text.len());
-                        return Some(CodeLabel {
-                            filter_range: 0..completion.label.find('(').unwrap_or(text.len()),
-                            text,
-                            runs,
-                        });
-                    }
-                }
-            }
-            Some(kind) => {
-                let highlight_name = match kind {
-                    lsp::CompletionItemKind::STRUCT
-                    | lsp::CompletionItemKind::INTERFACE
-                    | lsp::CompletionItemKind::ENUM => Some("type"),
-                    lsp::CompletionItemKind::ENUM_MEMBER => Some("variant"),
-                    lsp::CompletionItemKind::KEYWORD => Some("keyword"),
-                    lsp::CompletionItemKind::VALUE | lsp::CompletionItemKind::CONSTANT => {
-                        Some("constant")
-                    }
-                    _ => None,
-                };
-                let highlight_id = language.grammar()?.highlight_id_for_name(highlight_name?)?;
-                let mut label = CodeLabel::plain(completion.label.clone(), None);
-                label.runs.push((
-                    0..label.text.rfind('(').unwrap_or(label.text.len()),
-                    highlight_id,
-                ));
-                return Some(label);
-            }
-            _ => {}
-        }
-        None
-    }
-
-    async fn label_for_symbol(
-        &self,
-        name: &str,
-        kind: lsp::SymbolKind,
-        language: &Arc<Language>,
-    ) -> Option<CodeLabel> {
-        let (text, filter_range, display_range) = match kind {
-            lsp::SymbolKind::METHOD | lsp::SymbolKind::FUNCTION => {
-                let text = format!("fn {} () {{}}", name);
-                let filter_range = 3..3 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::STRUCT => {
-                let text = format!("struct {} {{}}", name);
-                let filter_range = 7..7 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::ENUM => {
-                let text = format!("enum {} {{}}", name);
-                let filter_range = 5..5 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::INTERFACE => {
-                let text = format!("trait {} {{}}", name);
-                let filter_range = 6..6 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::CONSTANT => {
-                let text = format!("const {}: () = ();", name);
-                let filter_range = 6..6 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::MODULE => {
-                let text = format!("mod {} {{}}", name);
-                let filter_range = 4..4 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            lsp::SymbolKind::TYPE_PARAMETER => {
-                let text = format!("type {} {{}}", name);
-                let filter_range = 5..5 + name.len();
-                let display_range = 0..filter_range.end;
-                (text, filter_range, display_range)
-            }
-            _ => return None,
-        };
-
-        Some(CodeLabel {
-            runs: language.highlight_text(&text.as_str().into(), display_range.clone()),
-            text: text[display_range].to_string(),
-            filter_range,
-        })
-    }
-}
-
-async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            last = Some(entry?.path());
-        }
-
-        anyhow::Ok(LanguageServerBinary {
-            path: last.ok_or_else(|| anyhow!("no cached binary"))?,
-            arguments: Default::default(),
-        })
-    })()
-    .await
-    .log_err()
-}
-
-#[cfg(test)]
-mod tests {
-    use std::num::NonZeroU32;
-
-    use super::*;
-    use crate::languages::language;
-    use gpui::{Context, Hsla, TestAppContext};
-    use language::language_settings::AllLanguageSettings;
-    use settings::SettingsStore;
-    use theme::SyntaxTheme;
-
-    #[gpui::test]
-    async fn test_process_rust_diagnostics() {
-        let mut params = lsp::PublishDiagnosticsParams {
-            uri: lsp::Url::from_file_path("/a").unwrap(),
-            version: None,
-            diagnostics: vec![
-                // no newlines
-                lsp::Diagnostic {
-                    message: "use of moved value `a`".to_string(),
-                    ..Default::default()
-                },
-                // newline at the end of a code span
-                lsp::Diagnostic {
-                    message: "consider importing this struct: `use b::c;\n`".to_string(),
-                    ..Default::default()
-                },
-                // code span starting right after a newline
-                lsp::Diagnostic {
-                    message: "cannot borrow `self.d` as mutable\n`self` is a `&` reference"
-                        .to_string(),
-                    ..Default::default()
-                },
-            ],
-        };
-        RustLspAdapter.process_diagnostics(&mut params);
-
-        assert_eq!(params.diagnostics[0].message, "use of moved value `a`");
-
-        // remove trailing newline from code span
-        assert_eq!(
-            params.diagnostics[1].message,
-            "consider importing this struct: `use b::c;`"
-        );
-
-        // do not remove newline before the start of code span
-        assert_eq!(
-            params.diagnostics[2].message,
-            "cannot borrow `self.d` as mutable\n`self` is a `&` reference"
-        );
-    }
-
-    #[gpui::test]
-    async fn test_rust_label_for_completion() {
-        let language = language(
-            "rust",
-            tree_sitter_rust::language(),
-            Some(Arc::new(RustLspAdapter)),
-        )
-        .await;
-        let grammar = language.grammar().unwrap();
-        let theme = SyntaxTheme::new_test([
-            ("type", Hsla::default()),
-            ("keyword", Hsla::default()),
-            ("function", Hsla::default()),
-            ("property", Hsla::default()),
-        ]);
-
-        language.set_theme(&theme);
-
-        let highlight_function = grammar.highlight_id_for_name("function").unwrap();
-        let highlight_type = grammar.highlight_id_for_name("type").unwrap();
-        let highlight_keyword = grammar.highlight_id_for_name("keyword").unwrap();
-        let highlight_field = grammar.highlight_id_for_name("property").unwrap();
-
-        assert_eq!(
-            language
-                .label_for_completion(&lsp::CompletionItem {
-                    kind: Some(lsp::CompletionItemKind::FUNCTION),
-                    label: "hello(…)".to_string(),
-                    detail: Some("fn(&mut Option<T>) -> Vec<T>".to_string()),
-                    ..Default::default()
-                })
-                .await,
-            Some(CodeLabel {
-                text: "hello(&mut Option<T>) -> Vec<T>".to_string(),
-                filter_range: 0..5,
-                runs: vec![
-                    (0..5, highlight_function),
-                    (7..10, highlight_keyword),
-                    (11..17, highlight_type),
-                    (18..19, highlight_type),
-                    (25..28, highlight_type),
-                    (29..30, highlight_type),
-                ],
-            })
-        );
-        assert_eq!(
-            language
-                .label_for_completion(&lsp::CompletionItem {
-                    kind: Some(lsp::CompletionItemKind::FUNCTION),
-                    label: "hello(…)".to_string(),
-                    detail: Some("async fn(&mut Option<T>) -> Vec<T>".to_string()),
-                    ..Default::default()
-                })
-                .await,
-            Some(CodeLabel {
-                text: "hello(&mut Option<T>) -> Vec<T>".to_string(),
-                filter_range: 0..5,
-                runs: vec![
-                    (0..5, highlight_function),
-                    (7..10, highlight_keyword),
-                    (11..17, highlight_type),
-                    (18..19, highlight_type),
-                    (25..28, highlight_type),
-                    (29..30, highlight_type),
-                ],
-            })
-        );
-        assert_eq!(
-            language
-                .label_for_completion(&lsp::CompletionItem {
-                    kind: Some(lsp::CompletionItemKind::FIELD),
-                    label: "len".to_string(),
-                    detail: Some("usize".to_string()),
-                    ..Default::default()
-                })
-                .await,
-            Some(CodeLabel {
-                text: "len: usize".to_string(),
-                filter_range: 0..3,
-                runs: vec![(0..3, highlight_field), (5..10, highlight_type),],
-            })
-        );
-
-        assert_eq!(
-            language
-                .label_for_completion(&lsp::CompletionItem {
-                    kind: Some(lsp::CompletionItemKind::FUNCTION),
-                    label: "hello(…)".to_string(),
-                    detail: Some("fn(&mut Option<T>) -> Vec<T>".to_string()),
-                    ..Default::default()
-                })
-                .await,
-            Some(CodeLabel {
-                text: "hello(&mut Option<T>) -> Vec<T>".to_string(),
-                filter_range: 0..5,
-                runs: vec![
-                    (0..5, highlight_function),
-                    (7..10, highlight_keyword),
-                    (11..17, highlight_type),
-                    (18..19, highlight_type),
-                    (25..28, highlight_type),
-                    (29..30, highlight_type),
-                ],
-            })
-        );
-    }
-
-    #[gpui::test]
-    async fn test_rust_label_for_symbol() {
-        let language = language(
-            "rust",
-            tree_sitter_rust::language(),
-            Some(Arc::new(RustLspAdapter)),
-        )
-        .await;
-        let grammar = language.grammar().unwrap();
-        let theme = SyntaxTheme::new_test([
-            ("type", Hsla::default()),
-            ("keyword", Hsla::default()),
-            ("function", Hsla::default()),
-            ("property", Hsla::default()),
-        ]);
-
-        language.set_theme(&theme);
-
-        let highlight_function = grammar.highlight_id_for_name("function").unwrap();
-        let highlight_type = grammar.highlight_id_for_name("type").unwrap();
-        let highlight_keyword = grammar.highlight_id_for_name("keyword").unwrap();
-
-        assert_eq!(
-            language
-                .label_for_symbol("hello", lsp::SymbolKind::FUNCTION)
-                .await,
-            Some(CodeLabel {
-                text: "fn hello".to_string(),
-                filter_range: 3..8,
-                runs: vec![(0..2, highlight_keyword), (3..8, highlight_function)],
-            })
-        );
-
-        assert_eq!(
-            language
-                .label_for_symbol("World", lsp::SymbolKind::TYPE_PARAMETER)
-                .await,
-            Some(CodeLabel {
-                text: "type World".to_string(),
-                filter_range: 5..10,
-                runs: vec![(0..4, highlight_keyword), (5..10, highlight_type)],
-            })
-        );
-    }
-
-    #[gpui::test]
-    async fn test_rust_autoindent(cx: &mut TestAppContext) {
-        // cx.executor().set_block_on_ticks(usize::MAX..=usize::MAX);
-        cx.update(|cx| {
-            let test_settings = SettingsStore::test(cx);
-            cx.set_global(test_settings);
-            language::init(cx);
-            cx.update_global::<SettingsStore, _>(|store, cx| {
-                store.update_user_settings::<AllLanguageSettings>(cx, |s| {
-                    s.defaults.tab_size = NonZeroU32::new(2);
-                });
-            });
-        });
-
-        let language = crate::languages::language("rust", tree_sitter_rust::language(), None).await;
-
-        cx.new_model(|cx| {
-            let mut buffer =
-                Buffer::new(0, cx.entity_id().as_u64(), "").with_language(language, cx);
-
-            // indent between braces
-            buffer.set_text("fn a() {}", cx);
-            let ix = buffer.len() - 1;
-            buffer.edit([(ix..ix, "\n\n")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "fn a() {\n  \n}");
-
-            // indent between braces, even after empty lines
-            buffer.set_text("fn a() {\n\n\n}", cx);
-            let ix = buffer.len() - 2;
-            buffer.edit([(ix..ix, "\n")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "fn a() {\n\n\n  \n}");
-
-            // indent a line that continues a field expression
-            buffer.set_text("fn a() {\n  \n}", cx);
-            let ix = buffer.len() - 2;
-            buffer.edit([(ix..ix, "b\n.c")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "fn a() {\n  b\n    .c\n}");
-
-            // indent further lines that continue the field expression, even after empty lines
-            let ix = buffer.len() - 2;
-            buffer.edit([(ix..ix, "\n\n.d")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "fn a() {\n  b\n    .c\n    \n    .d\n}");
-
-            // dedent the line after the field expression
-            let ix = buffer.len() - 2;
-            buffer.edit([(ix..ix, ";\ne")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(
-                buffer.text(),
-                "fn a() {\n  b\n    .c\n    \n    .d;\n  e\n}"
-            );
-
-            // indent inside a struct within a call
-            buffer.set_text("const a: B = c(D {});", cx);
-            let ix = buffer.len() - 3;
-            buffer.edit([(ix..ix, "\n\n")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "const a: B = c(D {\n  \n});");
-
-            // indent further inside a nested call
-            let ix = buffer.len() - 4;
-            buffer.edit([(ix..ix, "e: f(\n\n)")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(buffer.text(), "const a: B = c(D {\n  e: f(\n    \n  )\n});");
-
-            // keep that indent after an empty line
-            let ix = buffer.len() - 8;
-            buffer.edit([(ix..ix, "\n")], Some(AutoindentMode::EachLine), cx);
-            assert_eq!(
-                buffer.text(),
-                "const a: B = c(D {\n  e: f(\n    \n    \n  )\n});"
-            );
-
-            buffer
-        });
-    }
-}

crates/zed2/src/languages/rust/config.toml 🔗

@@ -1,13 +0,0 @@
-name = "Rust"
-path_suffixes = ["rs"]
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-]
-collapsed_placeholder = " /* ... */ "

crates/zed2/src/languages/rust/embedding.scm 🔗

@@ -1,32 +0,0 @@
-(
-    [(line_comment) (attribute_item)]* @context
-    .
-    [
-
-        (struct_item
-            name: (_) @name)
-
-        (enum_item
-            name: (_) @name)
-
-        (impl_item
-            trait: (_)? @name
-            "for"? @name
-            type: (_) @name)
-
-        (trait_item
-            name: (_) @name)
-
-        (function_item
-            name: (_) @name
-            body: (block
-                "{" @keep
-                "}" @keep) @collapse)
-
-        (macro_definition
-            name: (_) @name)
-        ] @item
-    )
-
-(attribute_item) @collapse
-(use_declaration) @collapse

crates/zed2/src/languages/rust/highlights.scm 🔗

@@ -1,116 +0,0 @@
-(type_identifier) @type
-(primitive_type) @type.builtin
-(self) @variable.special
-(field_identifier) @property
-
-(call_expression
-  function: [
-    (identifier) @function
-    (scoped_identifier
-      name: (identifier) @function)
-    (field_expression
-      field: (field_identifier) @function.method)
-  ])
-
-(generic_function
-  function: [
-    (identifier) @function
-    (scoped_identifier
-      name: (identifier) @function)
-    (field_expression
-      field: (field_identifier) @function.method)
-  ])
-
-(function_item name: (identifier) @function.definition)
-(function_signature_item name: (identifier) @function.definition)
-
-(macro_invocation
-  macro: [
-    (identifier) @function.special
-    (scoped_identifier
-      name: (identifier) @function.special)
-  ])
-
-(macro_definition
-  name: (identifier) @function.special.definition)
-
-; Identifier conventions
-
-; Assume uppercase names are types/enum-constructors
-((identifier) @type
- (#match? @type "^[A-Z]"))
-
-; Assume all-caps names are constants
-((identifier) @constant
- (#match? @constant "^_*[A-Z][A-Z\\d_]*$"))
-
-[
-  "("
-  ")"
-  "{"
-  "}"
-  "["
-  "]"
-] @punctuation.bracket
-
-(_
-  .
-  "<" @punctuation.bracket
-  ">" @punctuation.bracket)
-
-[
-  "as"
-  "async"
-  "await"
-  "break"
-  "const"
-  "continue"
-  "default"
-  "dyn"
-  "else"
-  "enum"
-  "extern"
-  "for"
-  "fn"
-  "if"
-  "in"
-  "impl"
-  "let"
-  "loop"
-  "macro_rules!"
-  "match"
-  "mod"
-  "move"
-  "pub"
-  "ref"
-  "return"
-  "static"
-  "struct"
-  "trait"
-  "type"
-  "use"
-  "where"
-  "while"
-  "union"
-  "unsafe"
-  (mutable_specifier)
-  (super)
-] @keyword
-
-[
-  (string_literal)
-  (raw_string_literal)
-  (char_literal)
-] @string
-
-[
-  (integer_literal)
-  (float_literal)
-] @number
-
-(boolean_literal) @constant
-
-[
-  (line_comment)
-  (block_comment)
-] @comment

crates/zed2/src/languages/rust/indents.scm 🔗

@@ -1,14 +0,0 @@
-[
-    ((where_clause) _ @end)
-    (field_expression)
-    (call_expression)
-    (assignment_expression)
-    (let_declaration)
-    (let_chain)
-    (await_expression)
-] @indent
-
-(_ "[" "]" @end) @indent
-(_ "<" ">" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent

crates/zed2/src/languages/rust/outline.scm 🔗

@@ -1,63 +0,0 @@
-(struct_item
-    (visibility_modifier)? @context
-    "struct" @context
-    name: (_) @name) @item
-
-(enum_item
-    (visibility_modifier)? @context
-    "enum" @context
-    name: (_) @name) @item
-
-(enum_variant
-    (visibility_modifier)? @context
-    name: (_) @name) @item
-
-(impl_item
-    "impl" @context
-    trait: (_)? @name
-    "for"? @context
-    type: (_) @name) @item
-
-(trait_item
-    (visibility_modifier)? @context
-    "trait" @context
-    name: (_) @name) @item
-
-(function_item
-    (visibility_modifier)? @context
-    (function_modifiers)? @context
-    "fn" @context
-    name: (_) @name) @item
-
-(function_signature_item
-    (visibility_modifier)? @context
-    (function_modifiers)? @context
-    "fn" @context
-    name: (_) @name) @item
-
-(macro_definition
-    . "macro_rules!" @context
-    name: (_) @name) @item
-
-(mod_item
-    (visibility_modifier)? @context
-    "mod" @context
-    name: (_) @name) @item
-
-(type_item
-    (visibility_modifier)? @context
-    "type" @context
-    name: (_) @name) @item
-
-(associated_type
-    "type" @context
-    name: (_) @name) @item
-
-(const_item
-    (visibility_modifier)? @context
-    "const" @context
-    name: (_) @name) @item
-
-(field_declaration
-    (visibility_modifier)? @context
-    name: (_) @name) @item

crates/zed2/src/languages/scheme/config.toml 🔗

@@ -1,9 +0,0 @@
-name = "Scheme"
-path_suffixes = ["scm", "ss"]
-line_comment = "; "
-autoclose_before = "])"
-brackets = [
-    { start = "[", end = "]", close = true, newline = false },
-    { start = "(", end = ")", close = true, newline = false },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
-]

crates/zed2/src/languages/scheme/highlights.scm 🔗

@@ -1,28 +0,0 @@
-["(" ")" "[" "]" "{" "}"] @punctuation.bracket
-
-(number) @number
-(character) @constant.builtin
-(boolean) @constant.builtin
-
-(symbol) @variable
-(string) @string
-
-(escape_sequence) @escape
-
-[(comment)
- (block_comment)
- (directive)] @comment
-
-((symbol) @operator
- (#match? @operator "^(\\+|-|\\*|/|=|>|<|>=|<=)$"))
-
-(list
-  .
-  (symbol) @function)
-
-(list
-  .
-  (symbol) @keyword
-  (#match? @keyword
-   "^(define-syntax|let\\*|lambda|λ|case|=>|quote-splicing|unquote-splicing|set!|let|letrec|letrec-syntax|let-values|let\\*-values|do|else|define|cond|syntax-rules|unquote|begin|quote|let-syntax|and|if|quasiquote|letrec|delay|or|when|unless|identifier-syntax|assert|library|export|import|rename|only|except|prefix)$"
-   ))

crates/zed2/src/languages/svelte.rs 🔗

@@ -1,133 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use futures::StreamExt;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-use serde_json::json;
-use smol::fs;
-use std::{
-    any::Any,
-    ffi::OsString,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-const SERVER_PATH: &'static str = "node_modules/svelte-language-server/bin/server.js";
-
-fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct SvelteLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl SvelteLspAdapter {
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        SvelteLspAdapter { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for SvelteLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("svelte-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "svelte"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(
-            self.node
-                .npm_package_latest_version("svelte-language-server")
-                .await?,
-        ) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<String>().unwrap();
-        let server_path = container_dir.join(SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("svelte-language-server", version.as_str())],
-                )
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        Some(json!({
-            "provideFormatter": true
-        }))
-    }
-
-    fn prettier_plugins(&self) -> &[&'static str] {
-        &["prettier-plugin-svelte"]
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(SERVER_PATH);
-        if server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: server_binary_arguments(&server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}

crates/zed2/src/languages/svelte/config.toml 🔗

@@ -1,20 +0,0 @@
-name = "Svelte"
-path_suffixes = ["svelte"]
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]
-prettier_parser_name = "svelte"
-
-[overrides.string]
-word_characters = ["-"]
-opt_into_language_servers = ["tailwindcss-language-server"]

crates/zed2/src/languages/svelte/highlights.scm 🔗

@@ -1,42 +0,0 @@
-; Special identifiers
-;--------------------
-
-; TODO:
-(tag_name) @tag
-(attribute_name) @property
-(erroneous_end_tag_name) @keyword
-(comment) @comment
-
-[
-  (attribute_value)
-  (quoted_attribute_value)
-] @string
-
-[
-  (text)
-  (raw_text_expr)
-] @none
-
-[
-  (special_block_keyword)
-  (then)
-  (as)
-] @keyword
-
-[
-  "{"
-  "}"
-] @punctuation.bracket
-
-"=" @operator
-
-[
-  "<"
-  ">"
-  "</"
-  "/>"
-  "#"
-  ":"
-  "/"
-  "@"
-] @tag.delimiter

crates/zed2/src/languages/svelte/injections.scm 🔗

@@ -1,28 +0,0 @@
-; injections.scm
-; --------------
-(script_element
-  (raw_text) @content
-  (#set! "language" "javascript"))
-
- ((script_element
-     (start_tag
-       (attribute
-         (quoted_attribute_value (attribute_value) @_language)))
-      (raw_text) @content)
-    (#eq? @_language "ts")
-    (#set! "language" "typescript"))
-
-((script_element
-    (start_tag
-        (attribute
-        (quoted_attribute_value (attribute_value) @_language)))
-    (raw_text) @content)
-  (#eq? @_language "typescript")
-  (#set! "language" "typescript"))
-
-(style_element
-  (raw_text) @content
-  (#set! "language" "css"))
-
-((raw_text_expr) @content
-  (#set! "language" "javascript"))

crates/zed2/src/languages/tailwind.rs 🔗

@@ -1,171 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use collections::HashMap;
-use futures::{
-    future::{self, BoxFuture},
-    FutureExt, StreamExt,
-};
-use gpui::AppContext;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-use serde_json::{json, Value};
-use smol::fs;
-use std::{
-    any::Any,
-    ffi::OsString,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-const SERVER_PATH: &'static str = "node_modules/.bin/tailwindcss-language-server";
-
-fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct TailwindLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl TailwindLspAdapter {
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        TailwindLspAdapter { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for TailwindLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("tailwindcss-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "tailwind"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(
-            self.node
-                .npm_package_latest_version("@tailwindcss/language-server")
-                .await?,
-        ) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<String>().unwrap();
-        let server_path = container_dir.join(SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("@tailwindcss/language-server", version.as_str())],
-                )
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        Some(json!({
-            "provideFormatter": true,
-            "userLanguages": {
-                "html": "html",
-                "css": "css",
-                "javascript": "javascript",
-                "typescriptreact": "typescriptreact",
-            },
-        }))
-    }
-
-    fn workspace_configuration(
-        &self,
-        _workspace_root: &Path,
-        _: &mut AppContext,
-    ) -> BoxFuture<'static, Value> {
-        future::ready(json!({
-            "tailwindCSS": {
-                "emmetCompletions": true,
-            }
-        }))
-        .boxed()
-    }
-
-    async fn language_ids(&self) -> HashMap<String, String> {
-        HashMap::from_iter([
-            ("HTML".to_string(), "html".to_string()),
-            ("CSS".to_string(), "css".to_string()),
-            ("JavaScript".to_string(), "javascript".to_string()),
-            ("TSX".to_string(), "typescriptreact".to_string()),
-            ("Svelte".to_string(), "svelte".to_string()),
-            ("Elixir".to_string(), "phoenix-heex".to_string()),
-            ("HEEX".to_string(), "phoenix-heex".to_string()),
-            ("ERB".to_string(), "erb".to_string()),
-            ("PHP".to_string(), "php".to_string()),
-        ])
-    }
-
-    fn prettier_plugins(&self) -> &[&'static str] {
-        &["prettier-plugin-tailwindcss"]
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(SERVER_PATH);
-        if server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: server_binary_arguments(&server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}

crates/zed2/src/languages/toml/config.toml 🔗

@@ -1,10 +0,0 @@
-name = "TOML"
-path_suffixes = ["Cargo.lock", "toml"]
-line_comment = "# "
-autoclose_before = ",]}"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["comment", "string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["comment", "string"] },
-]

crates/zed2/src/languages/toml/highlights.scm 🔗

@@ -1,37 +0,0 @@
-; Properties
-;-----------
-
-(bare_key) @property
-(quoted_key) @property
-
-; Literals
-;---------
-
-(boolean) @constant
-(comment) @comment
-(string) @string
-(integer) @number
-(float) @number
-(offset_date_time) @string.special
-(local_date_time) @string.special
-(local_date) @string.special
-(local_time) @string.special
-
-; Punctuation
-;------------
-
-[
-  "."
-  ","
-] @punctuation.delimiter
-
-"=" @operator
-
-[
-  "["
-  "]"
-  "[["
-  "]]"
-  "{"
-  "}"
-]  @punctuation.bracket

crates/zed2/src/languages/tsx/config.toml 🔗

@@ -1,25 +0,0 @@
-name = "TSX"
-path_suffixes = ["tsx"]
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-]
-word_characters = ["#", "$"]
-scope_opt_in_language_servers = ["tailwindcss-language-server"]
-prettier_parser_name = "typescript"
-
-[overrides.element]
-line_comment = { remove = true }
-block_comment = ["{/* ", " */}"]
-
-[overrides.string]
-word_characters = ["-"]
-opt_into_language_servers = ["tailwindcss-language-server"]

crates/zed2/src/languages/tsx/embedding.scm 🔗

@@ -1,85 +0,0 @@
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (function_declaration
-                "async"? @name
-                "function" @name
-                name: (_) @name))
-        (function_declaration
-            "async"? @name
-            "function" @name
-            name: (_) @name)
-        ] @item
-    )
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (class_declaration
-                "class" @name
-                name: (_) @name))
-        (class_declaration
-            "class" @name
-            name: (_) @name)
-        ] @item
-    )
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (interface_declaration
-                "interface" @name
-                name: (_) @name))
-        (interface_declaration
-            "interface" @name
-            name: (_) @name)
-        ] @item
-    )
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (enum_declaration
-                "enum" @name
-                name: (_) @name))
-        (enum_declaration
-            "enum" @name
-            name: (_) @name)
-        ] @item
-    )
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (type_alias_declaration
-                "type" @name
-                name: (_) @name))
-        (type_alias_declaration
-            "type" @name
-            name: (_) @name)
-        ] @item
-    )
-
-(
-    (comment)* @context
-    .
-    (method_definition
-        [
-            "get"
-            "set"
-            "async"
-            "*"
-            "static"
-            ]* @name
-        name: (_) @name) @item
-    )

crates/zed2/src/languages/tsx/overrides.scm 🔗

@@ -1,18 +0,0 @@
-(comment) @comment
-
-[
-  (string)
-  (template_string)
-] @string
-
-[
-  (jsx_element)
-  (jsx_fragment)
-] @element
-
-[
-  (jsx_opening_element)
-  (jsx_closing_element)
-  (jsx_self_closing_element)
-  (jsx_expression)
-] @default

crates/zed2/src/languages/typescript.rs 🔗

@@ -1,400 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_compression::futures::bufread::GzipDecoder;
-use async_tar::Archive;
-use async_trait::async_trait;
-use collections::HashMap;
-use futures::{future::BoxFuture, FutureExt};
-use gpui::AppContext;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::{CodeActionKind, LanguageServerBinary};
-use node_runtime::NodeRuntime;
-use serde_json::{json, Value};
-use smol::{fs, io::BufReader, stream::StreamExt};
-use std::{
-    any::Any,
-    ffi::OsString,
-    future,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::{fs::remove_matching, github::latest_github_release};
-use util::{github::GitHubLspBinaryVersion, ResultExt};
-
-fn typescript_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-fn eslint_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct TypeScriptLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl TypeScriptLspAdapter {
-    const OLD_SERVER_PATH: &'static str = "node_modules/typescript-language-server/lib/cli.js";
-    const NEW_SERVER_PATH: &'static str = "node_modules/typescript-language-server/lib/cli.mjs";
-
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        TypeScriptLspAdapter { node }
-    }
-}
-
-struct TypeScriptVersions {
-    typescript_version: String,
-    server_version: String,
-}
-
-#[async_trait]
-impl LspAdapter for TypeScriptLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("typescript-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "tsserver"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        Ok(Box::new(TypeScriptVersions {
-            typescript_version: self.node.npm_package_latest_version("typescript").await?,
-            server_version: self
-                .node
-                .npm_package_latest_version("typescript-language-server")
-                .await?,
-        }) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<TypeScriptVersions>().unwrap();
-        let server_path = container_dir.join(Self::NEW_SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[
-                        ("typescript", version.typescript_version.as_str()),
-                        (
-                            "typescript-language-server",
-                            version.server_version.as_str(),
-                        ),
-                    ],
-                )
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: typescript_server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_ts_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_ts_server_binary(container_dir, &*self.node).await
-    }
-
-    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
-        Some(vec![
-            CodeActionKind::QUICKFIX,
-            CodeActionKind::REFACTOR,
-            CodeActionKind::REFACTOR_EXTRACT,
-            CodeActionKind::SOURCE,
-        ])
-    }
-
-    async fn label_for_completion(
-        &self,
-        item: &lsp::CompletionItem,
-        language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        use lsp::CompletionItemKind as Kind;
-        let len = item.label.len();
-        let grammar = language.grammar()?;
-        let highlight_id = match item.kind? {
-            Kind::CLASS | Kind::INTERFACE => grammar.highlight_id_for_name("type"),
-            Kind::CONSTRUCTOR => grammar.highlight_id_for_name("type"),
-            Kind::CONSTANT => grammar.highlight_id_for_name("constant"),
-            Kind::FUNCTION | Kind::METHOD => grammar.highlight_id_for_name("function"),
-            Kind::PROPERTY | Kind::FIELD => grammar.highlight_id_for_name("property"),
-            _ => None,
-        }?;
-
-        let text = match &item.detail {
-            Some(detail) => format!("{} {}", item.label, detail),
-            None => item.label.clone(),
-        };
-
-        Some(language::CodeLabel {
-            text,
-            runs: vec![(0..len, highlight_id)],
-            filter_range: 0..len,
-        })
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        Some(json!({
-            "provideFormatter": true,
-            "tsserver": {
-                "path": "node_modules/typescript/lib",
-            },
-        }))
-    }
-
-    async fn language_ids(&self) -> HashMap<String, String> {
-        HashMap::from_iter([
-            ("TypeScript".into(), "typescript".into()),
-            ("JavaScript".into(), "javascript".into()),
-            ("TSX".into(), "typescriptreact".into()),
-        ])
-    }
-}
-
-async fn get_cached_ts_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let old_server_path = container_dir.join(TypeScriptLspAdapter::OLD_SERVER_PATH);
-        let new_server_path = container_dir.join(TypeScriptLspAdapter::NEW_SERVER_PATH);
-        if new_server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: typescript_server_binary_arguments(&new_server_path),
-            })
-        } else if old_server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: typescript_server_binary_arguments(&old_server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                container_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}
-
-pub struct EsLintLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl EsLintLspAdapter {
-    const SERVER_PATH: &'static str = "vscode-eslint/server/out/eslintServer.js";
-
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        EsLintLspAdapter { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for EsLintLspAdapter {
-    fn workspace_configuration(
-        &self,
-        workspace_root: &Path,
-        _: &mut AppContext,
-    ) -> BoxFuture<'static, Value> {
-        future::ready(json!({
-            "": {
-                "validate": "on",
-                "rulesCustomizations": [],
-                "run": "onType",
-                "nodePath": null,
-                "workingDirectory": {"mode": "auto"},
-                "workspaceFolder": {
-                    "uri": workspace_root,
-                    "name": workspace_root.file_name()
-                        .unwrap_or_else(|| workspace_root.as_os_str()),
-                },
-            }
-        }))
-        .boxed()
-    }
-
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("eslint".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "eslint"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        // At the time of writing the latest vscode-eslint release was released in 2020 and requires
-        // special custom LSP protocol extensions be handled to fully initialize. Download the latest
-        // prerelease instead to sidestep this issue
-        let release =
-            latest_github_release("microsoft/vscode-eslint", true, delegate.http_client()).await?;
-        Ok(Box::new(GitHubLspBinaryVersion {
-            name: release.name,
-            url: release.tarball_url,
-        }))
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        delegate: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
-        let destination_path = container_dir.join(format!("vscode-eslint-{}", version.name));
-        let server_path = destination_path.join(Self::SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            remove_matching(&container_dir, |entry| entry != destination_path).await;
-
-            let mut response = delegate
-                .http_client()
-                .get(&version.url, Default::default(), true)
-                .await
-                .map_err(|err| anyhow!("error downloading release: {}", err))?;
-            let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
-            let archive = Archive::new(decompressed_bytes);
-            archive.unpack(&destination_path).await?;
-
-            let mut dir = fs::read_dir(&destination_path).await?;
-            let first = dir.next().await.ok_or(anyhow!("missing first file"))??;
-            let repo_root = destination_path.join("vscode-eslint");
-            fs::rename(first.path(), &repo_root).await?;
-
-            self.node
-                .run_npm_subcommand(Some(&repo_root), "install", &[])
-                .await?;
-
-            self.node
-                .run_npm_subcommand(Some(&repo_root), "run-script", &["compile"])
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: eslint_server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_eslint_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_eslint_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn label_for_completion(
-        &self,
-        _item: &lsp::CompletionItem,
-        _language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        None
-    }
-
-    async fn initialization_options(&self) -> Option<serde_json::Value> {
-        None
-    }
-}
-
-async fn get_cached_eslint_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        // This is unfortunate but we don't know what the version is to build a path directly
-        let mut dir = fs::read_dir(&container_dir).await?;
-        let first = dir.next().await.ok_or(anyhow!("missing first file"))??;
-        if !first.file_type().await?.is_dir() {
-            return Err(anyhow!("First entry is not a directory"));
-        }
-        let server_path = first.path().join(EsLintLspAdapter::SERVER_PATH);
-
-        Ok(LanguageServerBinary {
-            path: node.binary_path().await?,
-            arguments: eslint_server_binary_arguments(&server_path),
-        })
-    })()
-    .await
-    .log_err()
-}
-
-#[cfg(test)]
-mod tests {
-    use gpui::{Context, TestAppContext};
-    use unindent::Unindent;
-
-    #[gpui::test]
-    async fn test_outline(cx: &mut TestAppContext) {
-        let language = crate::languages::language(
-            "typescript",
-            tree_sitter_typescript::language_typescript(),
-            None,
-        )
-        .await;
-
-        let text = r#"
-            function a() {
-              // local variables are omitted
-              let a1 = 1;
-              // all functions are included
-              async function a2() {}
-            }
-            // top-level variables are included
-            let b: C
-            function getB() {}
-            // exported variables are included
-            export const d = e;
-        "#
-        .unindent();
-
-        let buffer = cx.new_model(|cx| {
-            language::Buffer::new(0, cx.entity_id().as_u64(), text).with_language(language, cx)
-        });
-        let outline = buffer.update(cx, |buffer, _| buffer.snapshot().outline(None).unwrap());
-        assert_eq!(
-            outline
-                .items
-                .iter()
-                .map(|item| (item.text.as_str(), item.depth))
-                .collect::<Vec<_>>(),
-            &[
-                ("function a()", 0),
-                ("async function a2()", 1),
-                ("let b", 0),
-                ("function getB()", 0),
-                ("const d", 0),
-            ]
-        );
-    }
-}

crates/zed2/src/languages/typescript/config.toml 🔗

@@ -1,16 +0,0 @@
-name = "TypeScript"
-path_suffixes = ["ts", "cts", "d.cts", "d.mts", "mts"]
-line_comment = "// "
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
-    { start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
-]
-word_characters = ["#", "$"]
-prettier_parser_name = "typescript"

crates/zed2/src/languages/typescript/embedding.scm 🔗

@@ -1,85 +0,0 @@
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (function_declaration
-                "async"? @name
-                "function" @name
-                name: (_) @name))
-        (function_declaration
-            "async"? @name
-            "function" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (class_declaration
-                "class" @name
-                name: (_) @name))
-        (class_declaration
-            "class" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (interface_declaration
-                "interface" @name
-                name: (_) @name))
-        (interface_declaration
-            "interface" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (enum_declaration
-                "enum" @name
-                name: (_) @name))
-        (enum_declaration
-            "enum" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    [
-        (export_statement
-            (type_alias_declaration
-                "type" @name
-                name: (_) @name))
-        (type_alias_declaration
-            "type" @name
-            name: (_) @name)
-    ] @item
-)
-
-(
-    (comment)* @context
-    .
-    (method_definition
-        [
-            "get"
-            "set"
-            "async"
-            "*"
-            "static"
-            ]* @name
-        name: (_) @name) @item
-)

crates/zed2/src/languages/typescript/highlights.scm 🔗

@@ -1,221 +0,0 @@
-; Variables
-
-(identifier) @variable
-
-; Properties
-
-(property_identifier) @property
-
-; Function and method calls
-
-(call_expression
-  function: (identifier) @function)
-
-(call_expression
-  function: (member_expression
-    property: (property_identifier) @function.method))
-
-; Function and method definitions
-
-(function
-  name: (identifier) @function)
-(function_declaration
-  name: (identifier) @function)
-(method_definition
-  name: (property_identifier) @function.method)
-
-(pair
-  key: (property_identifier) @function.method
-  value: [(function) (arrow_function)])
-
-(assignment_expression
-  left: (member_expression
-    property: (property_identifier) @function.method)
-  right: [(function) (arrow_function)])
-
-(variable_declarator
-  name: (identifier) @function
-  value: [(function) (arrow_function)])
-
-(assignment_expression
-  left: (identifier) @function
-  right: [(function) (arrow_function)])
-
-; Special identifiers
-
-((identifier) @constructor
- (#match? @constructor "^[A-Z]"))
-
-((identifier) @type
- (#match? @type "^[A-Z]"))
-(type_identifier) @type
-(predefined_type) @type.builtin
-
-([
-  (identifier)
-  (shorthand_property_identifier)
-  (shorthand_property_identifier_pattern)
- ] @constant
- (#match? @constant "^_*[A-Z_][A-Z\\d_]*$"))
-
-; Literals
-
-(this) @variable.special
-(super) @variable.special
-
-[
-  (null)
-  (undefined)
-] @constant.builtin
-
-[
-  (true)
-  (false)
-] @boolean
-
-(comment) @comment
-
-[
-  (string)
-  (template_string)
-] @string
-
-(regex) @string.regex
-(number) @number
-
-; Tokens
-
-[
-  ";"
-  "?."
-  "."
-  ","
-  ":"
-] @punctuation.delimiter
-
-[
-  "-"
-  "--"
-  "-="
-  "+"
-  "++"
-  "+="
-  "*"
-  "*="
-  "**"
-  "**="
-  "/"
-  "/="
-  "%"
-  "%="
-  "<"
-  "<="
-  "<<"
-  "<<="
-  "="
-  "=="
-  "==="
-  "!"
-  "!="
-  "!=="
-  "=>"
-  ">"
-  ">="
-  ">>"
-  ">>="
-  ">>>"
-  ">>>="
-  "~"
-  "^"
-  "&"
-  "|"
-  "^="
-  "&="
-  "|="
-  "&&"
-  "||"
-  "??"
-  "&&="
-  "||="
-  "??="
-] @operator
-
-[
-  "("
-  ")"
-  "["
-  "]"
-  "{"
-  "}"
-]  @punctuation.bracket
-
-[
-  "as"
-  "async"
-  "await"
-  "break"
-  "case"
-  "catch"
-  "class"
-  "const"
-  "continue"
-  "debugger"
-  "default"
-  "delete"
-  "do"
-  "else"
-  "export"
-  "extends"
-  "finally"
-  "for"
-  "from"
-  "function"
-  "get"
-  "if"
-  "import"
-  "in"
-  "instanceof"
-  "let"
-  "new"
-  "of"
-  "return"
-  "satisfies"
-  "set"
-  "static"
-  "switch"
-  "target"
-  "throw"
-  "try"
-  "typeof"
-  "var"
-  "void"
-  "while"
-  "with"
-  "yield"
-] @keyword
-
-(template_substitution
-  "${" @punctuation.special
-  "}" @punctuation.special) @embedded
-
-(type_arguments
-  "<" @punctuation.bracket
-  ">" @punctuation.bracket)
-
-; Keywords
-
-[ "abstract"
-  "declare"
-  "enum"
-  "export"
-  "implements"
-  "interface"
-  "keyof"
-  "namespace"
-  "private"
-  "protected"
-  "public"
-  "type"
-  "readonly"
-  "override"
-] @keyword

crates/zed2/src/languages/typescript/indents.scm 🔗

@@ -1,15 +0,0 @@
-[
-    (call_expression)
-    (assignment_expression)
-    (member_expression)
-    (lexical_declaration)
-    (variable_declaration)
-    (assignment_expression)
-    (if_statement)
-    (for_statement)
-] @indent
-
-(_ "[" "]" @end) @indent
-(_ "<" ">" @end) @indent
-(_ "{" "}" @end) @indent
-(_ "(" ")" @end) @indent

crates/zed2/src/languages/typescript/outline.scm 🔗

@@ -1,65 +0,0 @@
-(internal_module
-    "namespace" @context
-    name: (_) @name) @item
-
-(enum_declaration
-    "enum" @context
-    name: (_) @name) @item
-
-(type_alias_declaration
-    "type" @context
-    name: (_) @name) @item
-
-(function_declaration
-    "async"? @context
-    "function" @context
-    name: (_) @name
-    parameters: (formal_parameters
-      "(" @context
-      ")" @context)) @item
-
-(interface_declaration
-    "interface" @context
-    name: (_) @name) @item
-
-(export_statement
-    (lexical_declaration
-        ["let" "const"] @context
-        (variable_declarator
-            name: (_) @name) @item))
-
-(program
-    (lexical_declaration
-        ["let" "const"] @context
-        (variable_declarator
-            name: (_) @name) @item))
-
-(class_declaration
-    "class" @context
-    name: (_) @name) @item
-
-(method_definition
-    [
-        "get"
-        "set"
-        "async"
-        "*"
-        "readonly"
-        "static"
-        (override_modifier)
-        (accessibility_modifier)
-    ]* @context
-    name: (_) @name
-    parameters: (formal_parameters
-      "(" @context
-      ")" @context)) @item
-
-(public_field_definition
-    [
-        "declare"
-        "readonly"
-        "abstract"
-        "static"
-        (accessibility_modifier)
-    ]* @context
-    name: (_) @name) @item

crates/zed2/src/languages/uiua.rs 🔗

@@ -1,55 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
-use lsp::LanguageServerBinary;
-use std::{any::Any, path::PathBuf};
-
-pub struct UiuaLanguageServer;
-
-#[async_trait]
-impl LspAdapter for UiuaLanguageServer {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("uiua".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "uiua"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(()))
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        _version: Box<dyn 'static + Send + Any>,
-        _container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        Err(anyhow!(
-            "uiua must be installed and available in your $PATH"
-        ))
-    }
-
-    async fn cached_server_binary(
-        &self,
-        _: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        Some(LanguageServerBinary {
-            path: "uiua".into(),
-            arguments: vec!["lsp".into()],
-        })
-    }
-
-    fn can_be_reinstalled(&self) -> bool {
-        false
-    }
-
-    async fn installation_test_binary(&self, _: PathBuf) -> Option<LanguageServerBinary> {
-        None
-    }
-}

crates/zed2/src/languages/uiua/config.toml 🔗

@@ -1,10 +0,0 @@
-name = "Uiua"
-path_suffixes = ["ua"]
-line_comment = "# "
-autoclose_before = ")]}\""
-brackets = [
-    { start = "{", end = "}", close = true, newline = false},
-    { start = "[", end = "]", close = true, newline = false },
-    { start = "(", end = ")", close = true, newline = false },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-]

crates/zed2/src/languages/uiua/highlights.scm 🔗

@@ -1,50 +0,0 @@
-[
-  (openParen)
-  (closeParen)
-  (openCurly)
-  (closeCurly)
-  (openBracket)
-  (closeBracket)
-] @punctuation.bracket
-
-[
-  (branchSeparator)
-  (underscore)
-] @constructor
-; ] @punctuation.delimiter
-
-[ (character) ] @constant.character
-[ (comment) ] @comment
-[ (constant) ] @constant.numeric
-[ (identifier) ] @variable
-[ (leftArrow) ] @keyword
-[ (function) ] @function
-[ (modifier1) ] @operator
-[ (modifier2) ] @operator
-[ (number) ] @constant.numeric
-[ (placeHolder) ] @special
-[ (otherConstant) ] @string.special
-[ (signature) ] @type
-[ (system) ] @function.builtin
-[ (tripleMinus) ] @module
-
-; planet
-[
-  "id"
-  "identity"
-  "∘"
-  "dip"
-  "⊙"
-  "gap"
-  "⋅"
-] @tag
-
-[
-  (string)
-  (multiLineString)
-] @string
-
-; [
-;   (deprecated)
-;   (identifierDeprecated)
-; ] @warning

crates/zed2/src/languages/vue.rs 🔗

@@ -1,220 +0,0 @@
-use anyhow::{anyhow, ensure, Result};
-use async_trait::async_trait;
-use futures::StreamExt;
-pub use language::*;
-use lsp::{CodeActionKind, LanguageServerBinary};
-use node_runtime::NodeRuntime;
-use parking_lot::Mutex;
-use serde_json::Value;
-use smol::fs::{self};
-use std::{
-    any::Any,
-    ffi::OsString,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-pub struct VueLspVersion {
-    vue_version: String,
-    ts_version: String,
-}
-
-pub struct VueLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-    typescript_install_path: Mutex<Option<PathBuf>>,
-}
-
-impl VueLspAdapter {
-    const SERVER_PATH: &'static str =
-        "node_modules/@vue/language-server/bin/vue-language-server.js";
-    // TODO: this can't be hardcoded, yet we have to figure out how to pass it in initialization_options.
-    const TYPESCRIPT_PATH: &'static str = "node_modules/typescript/lib";
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        let typescript_install_path = Mutex::new(None);
-        Self {
-            node,
-            typescript_install_path,
-        }
-    }
-}
-#[async_trait]
-impl super::LspAdapter for VueLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("vue-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "vue-language-server"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Send + Any>> {
-        Ok(Box::new(VueLspVersion {
-            vue_version: self
-                .node
-                .npm_package_latest_version("@vue/language-server")
-                .await?,
-            ts_version: self.node.npm_package_latest_version("typescript").await?,
-        }) as Box<_>)
-    }
-    async fn initialization_options(&self) -> Option<Value> {
-        let typescript_sdk_path = self.typescript_install_path.lock();
-        let typescript_sdk_path = typescript_sdk_path
-            .as_ref()
-            .expect("initialization_options called without a container_dir for typescript");
-
-        Some(serde_json::json!({
-            "typescript": {
-                "tsdk": typescript_sdk_path
-            }
-        }))
-    }
-    fn code_action_kinds(&self) -> Option<Vec<CodeActionKind>> {
-        // REFACTOR is explicitly disabled, as vue-lsp does not adhere to LSP protocol for code actions with these - it
-        // sends back a CodeAction with neither `command` nor `edits` fields set, which is against the spec.
-        Some(vec![
-            CodeActionKind::EMPTY,
-            CodeActionKind::QUICKFIX,
-            CodeActionKind::REFACTOR_REWRITE,
-        ])
-    }
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<VueLspVersion>().unwrap();
-        let server_path = container_dir.join(Self::SERVER_PATH);
-        let ts_path = container_dir.join(Self::TYPESCRIPT_PATH);
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("@vue/language-server", version.vue_version.as_str())],
-                )
-                .await?;
-        }
-        ensure!(
-            fs::metadata(&server_path).await.is_ok(),
-            "@vue/language-server package installation failed"
-        );
-        if fs::metadata(&ts_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("typescript", version.ts_version.as_str())],
-                )
-                .await?;
-        }
-
-        ensure!(
-            fs::metadata(&ts_path).await.is_ok(),
-            "typescript for Vue package installation failed"
-        );
-        *self.typescript_install_path.lock() = Some(ts_path);
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: vue_server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        let (server, ts_path) = get_cached_server_binary(container_dir, self.node.clone()).await?;
-        *self.typescript_install_path.lock() = Some(ts_path);
-        Some(server)
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        let (server, ts_path) = get_cached_server_binary(container_dir, self.node.clone())
-            .await
-            .map(|(mut binary, ts_path)| {
-                binary.arguments = vec!["--help".into()];
-                (binary, ts_path)
-            })?;
-        *self.typescript_install_path.lock() = Some(ts_path);
-        Some(server)
-    }
-
-    async fn label_for_completion(
-        &self,
-        item: &lsp::CompletionItem,
-        language: &Arc<language::Language>,
-    ) -> Option<language::CodeLabel> {
-        use lsp::CompletionItemKind as Kind;
-        let len = item.label.len();
-        let grammar = language.grammar()?;
-        let highlight_id = match item.kind? {
-            Kind::CLASS | Kind::INTERFACE => grammar.highlight_id_for_name("type"),
-            Kind::CONSTRUCTOR => grammar.highlight_id_for_name("type"),
-            Kind::CONSTANT => grammar.highlight_id_for_name("constant"),
-            Kind::FUNCTION | Kind::METHOD => grammar.highlight_id_for_name("function"),
-            Kind::PROPERTY | Kind::FIELD => grammar.highlight_id_for_name("tag"),
-            Kind::VARIABLE => grammar.highlight_id_for_name("type"),
-            Kind::KEYWORD => grammar.highlight_id_for_name("keyword"),
-            Kind::VALUE => grammar.highlight_id_for_name("tag"),
-            _ => None,
-        }?;
-
-        let text = match &item.detail {
-            Some(detail) => format!("{} {}", item.label, detail),
-            None => item.label.clone(),
-        };
-
-        Some(language::CodeLabel {
-            text,
-            runs: vec![(0..len, highlight_id)],
-            filter_range: 0..len,
-        })
-    }
-}
-
-fn vue_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-type TypescriptPath = PathBuf;
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: Arc<dyn NodeRuntime>,
-) -> Option<(LanguageServerBinary, TypescriptPath)> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(VueLspAdapter::SERVER_PATH);
-        let typescript_path = last_version_dir.join(VueLspAdapter::TYPESCRIPT_PATH);
-        if server_path.exists() && typescript_path.exists() {
-            Ok((
-                LanguageServerBinary {
-                    path: node.binary_path().await?,
-                    arguments: vue_server_binary_arguments(&server_path),
-                },
-                typescript_path,
-            ))
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}

crates/zed2/src/languages/vue/config.toml 🔗

@@ -1,14 +0,0 @@
-name = "Vue.js"
-path_suffixes = ["vue"]
-block_comment = ["<!-- ", " -->"]
-autoclose_before = ";:.,=}])>"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "(", end = ")", close = true, newline = true },
-    { start = "<", end = ">", close = true, newline = true, not_in = ["string", "comment"] },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-    { start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
-    { start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
-]
-word_characters = ["-"]

crates/zed2/src/languages/vue/highlights.scm 🔗

@@ -1,15 +0,0 @@
-(attribute) @property
-(directive_attribute) @property
-(quoted_attribute_value) @string
-(interpolation) @punctuation.special
-(raw_text) @embedded
-
-((tag_name) @type
- (#match? @type "^[A-Z]"))
-
-((directive_name) @keyword
- (#match? @keyword "^v-"))
-
-(start_tag) @tag
-(end_tag) @tag
-(self_closing_tag) @tag

crates/zed2/src/languages/yaml.rs 🔗

@@ -1,146 +0,0 @@
-use anyhow::{anyhow, Result};
-use async_trait::async_trait;
-use futures::{future::BoxFuture, FutureExt, StreamExt};
-use gpui::AppContext;
-use language::{
-    language_settings::all_language_settings, LanguageServerName, LspAdapter, LspAdapterDelegate,
-};
-use lsp::LanguageServerBinary;
-use node_runtime::NodeRuntime;
-use serde_json::Value;
-use smol::fs;
-use std::{
-    any::Any,
-    ffi::OsString,
-    future,
-    path::{Path, PathBuf},
-    sync::Arc,
-};
-use util::ResultExt;
-
-const SERVER_PATH: &'static str = "node_modules/yaml-language-server/bin/yaml-language-server";
-
-fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
-    vec![server_path.into(), "--stdio".into()]
-}
-
-pub struct YamlLspAdapter {
-    node: Arc<dyn NodeRuntime>,
-}
-
-impl YamlLspAdapter {
-    pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
-        YamlLspAdapter { node }
-    }
-}
-
-#[async_trait]
-impl LspAdapter for YamlLspAdapter {
-    async fn name(&self) -> LanguageServerName {
-        LanguageServerName("yaml-language-server".into())
-    }
-
-    fn short_name(&self) -> &'static str {
-        "yaml"
-    }
-
-    async fn fetch_latest_server_version(
-        &self,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<Box<dyn 'static + Any + Send>> {
-        Ok(Box::new(
-            self.node
-                .npm_package_latest_version("yaml-language-server")
-                .await?,
-        ) as Box<_>)
-    }
-
-    async fn fetch_server_binary(
-        &self,
-        version: Box<dyn 'static + Send + Any>,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Result<LanguageServerBinary> {
-        let version = version.downcast::<String>().unwrap();
-        let server_path = container_dir.join(SERVER_PATH);
-
-        if fs::metadata(&server_path).await.is_err() {
-            self.node
-                .npm_install_packages(
-                    &container_dir,
-                    &[("yaml-language-server", version.as_str())],
-                )
-                .await?;
-        }
-
-        Ok(LanguageServerBinary {
-            path: self.node.binary_path().await?,
-            arguments: server_binary_arguments(&server_path),
-        })
-    }
-
-    async fn cached_server_binary(
-        &self,
-        container_dir: PathBuf,
-        _: &dyn LspAdapterDelegate,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-
-    async fn installation_test_binary(
-        &self,
-        container_dir: PathBuf,
-    ) -> Option<LanguageServerBinary> {
-        get_cached_server_binary(container_dir, &*self.node).await
-    }
-    fn workspace_configuration(
-        &self,
-        _workspace_root: &Path,
-        cx: &mut AppContext,
-    ) -> BoxFuture<'static, Value> {
-        let tab_size = all_language_settings(None, cx)
-            .language(Some("YAML"))
-            .tab_size;
-
-        future::ready(serde_json::json!({
-            "yaml": {
-                "keyOrdering": false
-            },
-            "[yaml]": {
-                "editor.tabSize": tab_size,
-            }
-        }))
-        .boxed()
-    }
-}
-
-async fn get_cached_server_binary(
-    container_dir: PathBuf,
-    node: &dyn NodeRuntime,
-) -> Option<LanguageServerBinary> {
-    (|| async move {
-        let mut last_version_dir = None;
-        let mut entries = fs::read_dir(&container_dir).await?;
-        while let Some(entry) = entries.next().await {
-            let entry = entry?;
-            if entry.file_type().await?.is_dir() {
-                last_version_dir = Some(entry.path());
-            }
-        }
-        let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
-        let server_path = last_version_dir.join(SERVER_PATH);
-        if server_path.exists() {
-            Ok(LanguageServerBinary {
-                path: node.binary_path().await?,
-                arguments: server_binary_arguments(&server_path),
-            })
-        } else {
-            Err(anyhow!(
-                "missing executable in directory {:?}",
-                last_version_dir
-            ))
-        }
-    })()
-    .await
-    .log_err()
-}

crates/zed2/src/languages/yaml/config.toml 🔗

@@ -1,12 +0,0 @@
-name = "YAML"
-path_suffixes = ["yml", "yaml"]
-line_comment = "# "
-autoclose_before = ",]}"
-brackets = [
-    { start = "{", end = "}", close = true, newline = true },
-    { start = "[", end = "]", close = true, newline = true },
-    { start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
-]
-
-increase_indent_pattern = ":\\s*[|>]?\\s*$"
-prettier_parser_name = "yaml"

crates/zed2/src/languages/yaml/highlights.scm 🔗

@@ -1,49 +0,0 @@
-(boolean_scalar) @boolean
-(null_scalar) @constant.builtin
-
-[
-  (double_quote_scalar)
-  (single_quote_scalar)
-  (block_scalar)
-  (string_scalar)
-] @string
-
-(escape_sequence) @string.escape
-
-[
-  (integer_scalar)
-  (float_scalar)
-] @number
-
-(comment) @comment
-
-[
-  (anchor_name)
-  (alias_name)
-  (tag) 
-] @type
-
-key: (flow_node (plain_scalar (string_scalar) @property)) 
-
-[
- ","
- "-"
- ":"
- ">"
- "?"
- "|"
-] @punctuation.delimiter
-
-[
- "["
- "]"
- "{"
- "}"
-] @punctuation.bracket
-
-[
- "*"
- "&"
- "---"
- "..."
-] @punctuation.special

crates/zed2/src/main.rs 🔗

@@ -1,799 +0,0 @@
-// Allow binary to be called Zed for a nice application menu when running executable directly
-#![allow(non_snake_case)]
-
-use anyhow::{anyhow, Context as _, Result};
-use backtrace::Backtrace;
-use chrono::Utc;
-use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
-use client::{Client, UserStore};
-use collab_ui::channel_view::ChannelView;
-use db::kvp::KEY_VALUE_STORE;
-use editor::Editor;
-use fs::RealFs;
-use futures::StreamExt;
-use gpui::{App, AppContext, AsyncAppContext, Context, SemanticVersion, Task};
-use isahc::{prelude::Configurable, Request};
-use language::LanguageRegistry;
-use log::LevelFilter;
-
-use node_runtime::RealNodeRuntime;
-use parking_lot::Mutex;
-use serde::{Deserialize, Serialize};
-use settings::{
-    default_settings, handle_settings_file_changes, watch_config_file, Settings, SettingsStore,
-};
-use simplelog::ConfigBuilder;
-use smol::process::Command;
-use std::{
-    env,
-    ffi::OsStr,
-    fs::OpenOptions,
-    io::{IsTerminal, Write},
-    panic,
-    path::{Path, PathBuf},
-    sync::{
-        atomic::{AtomicU32, Ordering},
-        Arc, Weak,
-    },
-    thread,
-};
-use theme::ActiveTheme;
-use util::{
-    async_maybe,
-    channel::{parse_zed_link, AppCommitSha, ReleaseChannel, RELEASE_CHANNEL},
-    http::{self, HttpClient},
-    paths, ResultExt,
-};
-use uuid::Uuid;
-use welcome::{show_welcome_view, FIRST_OPEN};
-use workspace::{AppState, WorkspaceStore};
-use zed2::{
-    app_menus, build_window_options, ensure_only_instance, handle_cli_connection,
-    handle_keymap_file_changes, initialize_workspace, languages, Assets, IsOnlyInstance,
-    OpenListener, OpenRequest,
-};
-
-fn main() {
-    menu::init();
-    zed_actions::init();
-
-    let http = http::client();
-    init_paths();
-    init_logger();
-
-    if ensure_only_instance() != IsOnlyInstance::Yes {
-        return;
-    }
-
-    log::info!("========== starting zed ==========");
-    let app = App::production(Arc::new(Assets));
-
-    let (installation_id, existing_installation_id_found) = app
-        .background_executor()
-        .block(installation_id())
-        .ok()
-        .unzip();
-    let session_id = Uuid::new_v4().to_string();
-    init_panic_hook(&app, installation_id.clone(), session_id.clone());
-
-    let fs = Arc::new(RealFs);
-    let user_settings_file_rx = watch_config_file(
-        &app.background_executor(),
-        fs.clone(),
-        paths::SETTINGS.clone(),
-    );
-    let user_keymap_file_rx = watch_config_file(
-        &app.background_executor(),
-        fs.clone(),
-        paths::KEYMAP.clone(),
-    );
-
-    let login_shell_env_loaded = if stdout_is_a_pty() {
-        Task::ready(())
-    } else {
-        app.background_executor().spawn(async {
-            load_login_shell_environment().await.log_err();
-        })
-    };
-
-    let (listener, mut open_rx) = OpenListener::new();
-    let listener = Arc::new(listener);
-    let open_listener = listener.clone();
-    app.on_open_urls(move |urls, _| open_listener.open_urls(&urls));
-    app.on_reopen(move |cx| {
-        if cx.has_global::<Weak<AppState>>() {
-            if let Some(app_state) = cx.global::<Weak<AppState>>().upgrade() {
-                workspace::open_new(&app_state, cx, |workspace, cx| {
-                    Editor::new_file(workspace, &Default::default(), cx)
-                })
-                .detach();
-            }
-        }
-    });
-
-    app.run(move |cx| {
-        cx.set_global(*RELEASE_CHANNEL);
-        if let Some(build_sha) = option_env!("ZED_COMMIT_SHA") {
-            cx.set_global(AppCommitSha(build_sha.into()))
-        }
-
-        cx.set_global(listener.clone());
-
-        load_embedded_fonts(cx);
-
-        let mut store = SettingsStore::default();
-        store
-            .set_default_settings(default_settings().as_ref(), cx)
-            .unwrap();
-        cx.set_global(store);
-        handle_settings_file_changes(user_settings_file_rx, cx);
-        handle_keymap_file_changes(user_keymap_file_rx, cx);
-
-        let client = client::Client::new(http.clone(), cx);
-        let mut languages = LanguageRegistry::new(login_shell_env_loaded);
-        let copilot_language_server_id = languages.next_language_server_id();
-        languages.set_executor(cx.background_executor().clone());
-        languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone());
-        let languages = Arc::new(languages);
-        let node_runtime = RealNodeRuntime::new(http.clone());
-
-        language::init(cx);
-        languages::init(languages.clone(), node_runtime.clone(), cx);
-        let user_store = cx.new_model(|cx| UserStore::new(client.clone(), cx));
-        let workspace_store = cx.new_model(|cx| WorkspaceStore::new(client.clone(), cx));
-
-        cx.set_global(client.clone());
-
-        theme::init(theme::LoadThemes::All, cx);
-        project::Project::init(&client, cx);
-        client::init(&client, cx);
-        command_palette::init(cx);
-        language::init(cx);
-        editor::init(cx);
-        diagnostics::init(cx);
-        copilot::init(
-            copilot_language_server_id,
-            http.clone(),
-            node_runtime.clone(),
-            cx,
-        );
-        assistant::init(cx);
-        // component_test::init(cx);
-
-        cx.spawn(|_| watch_languages(fs.clone(), languages.clone()))
-            .detach();
-        watch_file_types(fs.clone(), cx);
-
-        languages.set_theme(cx.theme().clone());
-        cx.observe_global::<SettingsStore>({
-            let languages = languages.clone();
-            move |cx| languages.set_theme(cx.theme().clone())
-        })
-        .detach();
-
-        client.telemetry().start(installation_id, session_id, cx);
-        let telemetry_settings = *client::TelemetrySettings::get_global(cx);
-        client.telemetry().report_setting_event(
-            telemetry_settings,
-            "theme",
-            cx.theme().name.to_string(),
-        );
-        let event_operation = match existing_installation_id_found {
-            Some(false) => "first open",
-            _ => "open",
-        };
-        client
-            .telemetry()
-            .report_app_event(telemetry_settings, event_operation, true);
-
-        let app_state = Arc::new(AppState {
-            languages: languages.clone(),
-            client: client.clone(),
-            user_store: user_store.clone(),
-            fs: fs.clone(),
-            build_window_options,
-            workspace_store,
-            node_runtime,
-        });
-        cx.set_global(Arc::downgrade(&app_state));
-
-        audio::init(Assets, cx);
-        auto_update::init(http.clone(), client::ZED_SERVER_URL.clone(), cx);
-
-        workspace::init(app_state.clone(), cx);
-        recent_projects::init(cx);
-
-        go_to_line::init(cx);
-        file_finder::init(cx);
-        outline::init(cx);
-        project_symbols::init(cx);
-        project_panel::init(Assets, cx);
-        channel::init(&client, user_store.clone(), cx);
-        search::init(cx);
-        semantic_index::init(fs.clone(), http.clone(), languages.clone(), cx);
-        vim::init(cx);
-        terminal_view::init(cx);
-
-        journal::init(app_state.clone(), cx);
-        language_selector::init(cx);
-        theme_selector::init(cx);
-        language_tools::init(cx);
-        call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
-        notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx);
-        collab_ui::init(&app_state, cx);
-        feedback::init(cx);
-        welcome::init(cx);
-
-        cx.set_menus(app_menus());
-        initialize_workspace(app_state.clone(), cx);
-
-        if stdout_is_a_pty() {
-            cx.activate(true);
-            let urls = collect_url_args();
-            if !urls.is_empty() {
-                listener.open_urls(&urls)
-            }
-        } else {
-            upload_previous_panics(http.clone(), cx);
-
-            // TODO Development mode that forces the CLI mode usually runs Zed binary as is instead
-            // of an *app, hence gets no specific callbacks run. Emulate them here, if needed.
-            if std::env::var(FORCE_CLI_MODE_ENV_VAR_NAME).ok().is_some()
-                && !listener.triggered.load(Ordering::Acquire)
-            {
-                listener.open_urls(&collect_url_args())
-            }
-        }
-
-        let mut triggered_authentication = false;
-
-        fn open_paths_and_log_errs(
-            paths: &[PathBuf],
-            app_state: &Arc<AppState>,
-            cx: &mut AppContext,
-        ) {
-            let task = workspace::open_paths(&paths, &app_state, None, cx);
-            cx.spawn(|_| async move {
-                if let Some((_window, results)) = task.await.log_err() {
-                    for result in results {
-                        if let Some(Err(e)) = result {
-                            log::error!("Error opening path: {}", e);
-                        }
-                    }
-                }
-            })
-            .detach();
-        }
-
-        match open_rx.try_next() {
-            Ok(Some(OpenRequest::Paths { paths })) => {
-                open_paths_and_log_errs(&paths, &app_state, cx)
-            }
-            Ok(Some(OpenRequest::CliConnection { connection })) => {
-                let app_state = app_state.clone();
-                cx.spawn(move |cx| handle_cli_connection(connection, app_state, cx))
-                    .detach();
-            }
-            Ok(Some(OpenRequest::JoinChannel { channel_id })) => {
-                triggered_authentication = true;
-                let app_state = app_state.clone();
-                let client = client.clone();
-                cx.spawn(|cx| async move {
-                    // ignore errors here, we'll show a generic "not signed in"
-                    let _ = authenticate(client, &cx).await;
-                    cx.update(|cx| workspace::join_channel(channel_id, app_state, None, cx))?
-                        .await?;
-                    anyhow::Ok(())
-                })
-                .detach_and_log_err(cx);
-            }
-            Ok(Some(OpenRequest::OpenChannelNotes { channel_id })) => {
-                triggered_authentication = true;
-                let app_state = app_state.clone();
-                let client = client.clone();
-                cx.spawn(|mut cx| async move {
-                    // ignore errors here, we'll show a generic "not signed in"
-                    let _ = authenticate(client, &cx).await;
-                    let workspace_window =
-                        workspace::get_any_active_workspace(app_state, cx.clone()).await?;
-                    let _ = workspace_window
-                        .update(&mut cx, |_, cx| {
-                            ChannelView::open(channel_id, cx.view().clone(), cx)
-                        })?
-                        .await?;
-                    anyhow::Ok(())
-                })
-                .detach_and_log_err(cx);
-            }
-            Ok(None) | Err(_) => cx
-                .spawn({
-                    let app_state = app_state.clone();
-                    |cx| async move { restore_or_create_workspace(&app_state, cx).await }
-                })
-                .detach(),
-        }
-
-        let app_state = app_state.clone();
-        cx.spawn(move |cx| async move {
-            while let Some(request) = open_rx.next().await {
-                match request {
-                    OpenRequest::Paths { paths } => {
-                        cx.update(|cx| open_paths_and_log_errs(&paths, &app_state, cx))
-                            .ok();
-                    }
-                    OpenRequest::CliConnection { connection } => {
-                        let app_state = app_state.clone();
-                        cx.spawn(move |cx| {
-                            handle_cli_connection(connection, app_state.clone(), cx)
-                        })
-                        .detach();
-                    }
-                    OpenRequest::JoinChannel { channel_id } => {
-                        let app_state = app_state.clone();
-                        cx.update(|mut cx| {
-                            cx.spawn(|cx| async move {
-                                cx.update(|cx| {
-                                    workspace::join_channel(channel_id, app_state, None, cx)
-                                })?
-                                .await?;
-                                anyhow::Ok(())
-                            })
-                            .detach_and_log_err(&mut cx);
-                        })
-                        .log_err();
-                    }
-                    OpenRequest::OpenChannelNotes { channel_id } => {
-                        let app_state = app_state.clone();
-                        let open_notes_task = cx.spawn(|mut cx| async move {
-                            let workspace_window =
-                                workspace::get_any_active_workspace(app_state, cx.clone()).await?;
-                            let _ = workspace_window
-                                .update(&mut cx, |_, cx| {
-                                    ChannelView::open(channel_id, cx.view().clone(), cx)
-                                })?
-                                .await?;
-                            anyhow::Ok(())
-                        });
-                        cx.update(|cx| open_notes_task.detach_and_log_err(cx))
-                            .log_err();
-                    }
-                }
-            }
-        })
-        .detach();
-
-        if !triggered_authentication {
-            cx.spawn(|cx| async move { authenticate(client, &cx).await })
-                .detach_and_log_err(cx);
-        }
-    });
-}
-
-async fn authenticate(client: Arc<Client>, cx: &AsyncAppContext) -> Result<()> {
-    if stdout_is_a_pty() {
-        if client::IMPERSONATE_LOGIN.is_some() {
-            client.authenticate_and_connect(false, &cx).await?;
-        }
-    } else if client.has_keychain_credentials(&cx) {
-        client.authenticate_and_connect(true, &cx).await?;
-    }
-    Ok::<_, anyhow::Error>(())
-}
-
-async fn installation_id() -> Result<(String, bool)> {
-    let legacy_key_name = "device_id".to_string();
-    let key_name = "installation_id".to_string();
-
-    // Migrate legacy key to new key
-    if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(&legacy_key_name) {
-        KEY_VALUE_STORE
-            .write_kvp(key_name, installation_id.clone())
-            .await?;
-        KEY_VALUE_STORE.delete_kvp(legacy_key_name).await?;
-        return Ok((installation_id, true));
-    }
-
-    if let Ok(Some(installation_id)) = KEY_VALUE_STORE.read_kvp(&key_name) {
-        return Ok((installation_id, true));
-    }
-
-    let installation_id = Uuid::new_v4().to_string();
-
-    KEY_VALUE_STORE
-        .write_kvp(key_name, installation_id.clone())
-        .await?;
-
-    Ok((installation_id, false))
-}
-
-async fn restore_or_create_workspace(app_state: &Arc<AppState>, cx: AsyncAppContext) {
-    async_maybe!({
-        if let Some(location) = workspace::last_opened_workspace_paths().await {
-            cx.update(|cx| workspace::open_paths(location.paths().as_ref(), app_state, None, cx))?
-                .await
-                .log_err();
-        } else if matches!(KEY_VALUE_STORE.read_kvp(FIRST_OPEN), Ok(None)) {
-            cx.update(|cx| show_welcome_view(app_state, cx)).log_err();
-        } else {
-            cx.update(|cx| {
-                workspace::open_new(app_state, cx, |workspace, cx| {
-                    Editor::new_file(workspace, &Default::default(), cx)
-                })
-                .detach();
-            })?;
-        }
-        anyhow::Ok(())
-    })
-    .await
-    .log_err();
-}
-
-fn init_paths() {
-    std::fs::create_dir_all(&*util::paths::CONFIG_DIR).expect("could not create config path");
-    std::fs::create_dir_all(&*util::paths::LANGUAGES_DIR).expect("could not create languages path");
-    std::fs::create_dir_all(&*util::paths::DB_DIR).expect("could not create database path");
-    std::fs::create_dir_all(&*util::paths::LOGS_DIR).expect("could not create logs path");
-}
-
-fn init_logger() {
-    if stdout_is_a_pty() {
-        env_logger::init();
-    } else {
-        let level = LevelFilter::Info;
-
-        // Prevent log file from becoming too large.
-        const KIB: u64 = 1024;
-        const MIB: u64 = 1024 * KIB;
-        const MAX_LOG_BYTES: u64 = MIB;
-        if std::fs::metadata(&*paths::LOG).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES)
-        {
-            let _ = std::fs::rename(&*paths::LOG, &*paths::OLD_LOG);
-        }
-
-        let log_file = OpenOptions::new()
-            .create(true)
-            .append(true)
-            .open(&*paths::LOG)
-            .expect("could not open logfile");
-
-        let config = ConfigBuilder::new()
-            .set_time_format_str("%Y-%m-%dT%T") //All timestamps are UTC
-            .build();
-
-        simplelog::WriteLogger::init(level, config, log_file).expect("could not initialize logger");
-    }
-}
-
-#[derive(Serialize, Deserialize)]
-struct LocationData {
-    file: String,
-    line: u32,
-}
-
-#[derive(Serialize, Deserialize)]
-struct Panic {
-    thread: String,
-    payload: String,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    location_data: Option<LocationData>,
-    backtrace: Vec<String>,
-    app_version: String,
-    release_channel: String,
-    os_name: String,
-    os_version: Option<String>,
-    architecture: String,
-    panicked_on: i64,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    installation_id: Option<String>,
-    session_id: String,
-}
-
-#[derive(Serialize)]
-struct PanicRequest {
-    panic: Panic,
-    token: String,
-}
-
-static PANIC_COUNT: AtomicU32 = AtomicU32::new(0);
-
-fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: String) {
-    let is_pty = stdout_is_a_pty();
-    let app_metadata = app.metadata();
-
-    panic::set_hook(Box::new(move |info| {
-        let prior_panic_count = PANIC_COUNT.fetch_add(1, Ordering::SeqCst);
-        if prior_panic_count > 0 {
-            // Give the panic-ing thread time to write the panic file
-            loop {
-                std::thread::yield_now();
-            }
-        }
-
-        let thread = thread::current();
-        let thread_name = thread.name().unwrap_or("<unnamed>");
-
-        let payload = info
-            .payload()
-            .downcast_ref::<&str>()
-            .map(|s| s.to_string())
-            .or_else(|| info.payload().downcast_ref::<String>().map(|s| s.clone()))
-            .unwrap_or_else(|| "Box<Any>".to_string());
-
-        if *util::channel::RELEASE_CHANNEL == ReleaseChannel::Dev {
-            let location = info.location().unwrap();
-            let backtrace = Backtrace::new();
-            eprintln!(
-                "Thread {:?} panicked with {:?} at {}:{}:{}\n{:?}",
-                thread_name,
-                payload,
-                location.file(),
-                location.line(),
-                location.column(),
-                backtrace,
-            );
-            std::process::exit(-1);
-        }
-
-        let app_version = client::ZED_APP_VERSION
-            .or(app_metadata.app_version)
-            .map_or("dev".to_string(), |v| v.to_string());
-
-        let backtrace = Backtrace::new();
-        let mut backtrace = backtrace
-            .frames()
-            .iter()
-            .filter_map(|frame| Some(format!("{:#}", frame.symbols().first()?.name()?)))
-            .collect::<Vec<_>>();
-
-        // Strip out leading stack frames for rust panic-handling.
-        if let Some(ix) = backtrace
-            .iter()
-            .position(|name| name == "rust_begin_unwind")
-        {
-            backtrace.drain(0..=ix);
-        }
-
-        let panic_data = Panic {
-            thread: thread_name.into(),
-            payload: payload.into(),
-            location_data: info.location().map(|location| LocationData {
-                file: location.file().into(),
-                line: location.line(),
-            }),
-            app_version: app_version.clone(),
-            release_channel: RELEASE_CHANNEL.display_name().into(),
-            os_name: app_metadata.os_name.into(),
-            os_version: app_metadata
-                .os_version
-                .as_ref()
-                .map(SemanticVersion::to_string),
-            architecture: env::consts::ARCH.into(),
-            panicked_on: Utc::now().timestamp_millis(),
-            backtrace,
-            installation_id: installation_id.clone(),
-            session_id: session_id.clone(),
-        };
-
-        if let Some(panic_data_json) = serde_json::to_string_pretty(&panic_data).log_err() {
-            log::error!("{}", panic_data_json);
-        }
-
-        if !is_pty {
-            if let Some(panic_data_json) = serde_json::to_string(&panic_data).log_err() {
-                let timestamp = chrono::Utc::now().format("%Y_%m_%d %H_%M_%S").to_string();
-                let panic_file_path = paths::LOGS_DIR.join(format!("zed-{}.panic", timestamp));
-                let panic_file = std::fs::OpenOptions::new()
-                    .append(true)
-                    .create(true)
-                    .open(&panic_file_path)
-                    .log_err();
-                if let Some(mut panic_file) = panic_file {
-                    writeln!(&mut panic_file, "{}", panic_data_json).log_err();
-                    panic_file.flush().log_err();
-                }
-            }
-        }
-
-        std::process::abort();
-    }));
-}
-
-fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut AppContext) {
-    let telemetry_settings = *client::TelemetrySettings::get_global(cx);
-
-    cx.background_executor()
-        .spawn(async move {
-            let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL);
-            let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
-            while let Some(child) = children.next().await {
-                let child = child?;
-                let child_path = child.path();
-
-                if child_path.extension() != Some(OsStr::new("panic")) {
-                    continue;
-                }
-                let filename = if let Some(filename) = child_path.file_name() {
-                    filename.to_string_lossy()
-                } else {
-                    continue;
-                };
-
-                if !filename.starts_with("zed") {
-                    continue;
-                }
-
-                if telemetry_settings.diagnostics {
-                    let panic_file_content = smol::fs::read_to_string(&child_path)
-                        .await
-                        .context("error reading panic file")?;
-
-                    let panic = serde_json::from_str(&panic_file_content)
-                        .ok()
-                        .or_else(|| {
-                            panic_file_content
-                                .lines()
-                                .next()
-                                .and_then(|line| serde_json::from_str(line).ok())
-                        })
-                        .unwrap_or_else(|| {
-                            log::error!(
-                                "failed to deserialize panic file {:?}",
-                                panic_file_content
-                            );
-                            None
-                        });
-
-                    if let Some(panic) = panic {
-                        let body = serde_json::to_string(&PanicRequest {
-                            panic,
-                            token: client::ZED_SECRET_CLIENT_TOKEN.into(),
-                        })
-                        .unwrap();
-
-                        let request = Request::post(&panic_report_url)
-                            .redirect_policy(isahc::config::RedirectPolicy::Follow)
-                            .header("Content-Type", "application/json")
-                            .body(body.into())?;
-                        let response = http.send(request).await.context("error sending panic")?;
-                        if !response.status().is_success() {
-                            log::error!("Error uploading panic to server: {}", response.status());
-                        }
-                    }
-                }
-
-                // We've done what we can, delete the file
-                std::fs::remove_file(child_path)
-                    .context("error removing panic")
-                    .log_err();
-            }
-            Ok::<_, anyhow::Error>(())
-        })
-        .detach_and_log_err(cx);
-}
-
-async fn load_login_shell_environment() -> Result<()> {
-    let marker = "ZED_LOGIN_SHELL_START";
-    let shell = env::var("SHELL").context(
-        "SHELL environment variable is not assigned so we can't source login environment variables",
-    )?;
-    let output = Command::new(&shell)
-        .args(["-lic", &format!("echo {marker} && /usr/bin/env -0")])
-        .output()
-        .await
-        .context("failed to spawn login shell to source login environment variables")?;
-    if !output.status.success() {
-        Err(anyhow!("login shell exited with error"))?;
-    }
-
-    let stdout = String::from_utf8_lossy(&output.stdout);
-
-    if let Some(env_output_start) = stdout.find(marker) {
-        let env_output = &stdout[env_output_start + marker.len()..];
-        for line in env_output.split_terminator('\0') {
-            if let Some(separator_index) = line.find('=') {
-                let key = &line[..separator_index];
-                let value = &line[separator_index + 1..];
-                env::set_var(key, value);
-            }
-        }
-        log::info!(
-            "set environment variables from shell:{}, path:{}",
-            shell,
-            env::var("PATH").unwrap_or_default(),
-        );
-    }
-
-    Ok(())
-}
-
-fn stdout_is_a_pty() -> bool {
-    std::env::var(FORCE_CLI_MODE_ENV_VAR_NAME).ok().is_none() && std::io::stdout().is_terminal()
-}
-
-fn collect_url_args() -> Vec<String> {
-    env::args()
-        .skip(1)
-        .filter_map(|arg| match std::fs::canonicalize(Path::new(&arg)) {
-            Ok(path) => Some(format!("file://{}", path.to_string_lossy())),
-            Err(error) => {
-                if let Some(_) = parse_zed_link(&arg) {
-                    Some(arg)
-                } else {
-                    log::error!("error parsing path argument: {}", error);
-                    None
-                }
-            }
-        })
-        .collect()
-}
-
-fn load_embedded_fonts(cx: &AppContext) {
-    let asset_source = cx.asset_source();
-    let font_paths = asset_source.list("fonts").unwrap();
-    let embedded_fonts = Mutex::new(Vec::new());
-    let executor = cx.background_executor();
-
-    executor.block(executor.scoped(|scope| {
-        for font_path in &font_paths {
-            if !font_path.ends_with(".ttf") {
-                continue;
-            }
-
-            scope.spawn(async {
-                let font_bytes = asset_source.load(font_path).unwrap().to_vec();
-                embedded_fonts.lock().push(Arc::from(font_bytes));
-            });
-        }
-    }));
-
-    cx.text_system()
-        .add_fonts(&embedded_fonts.into_inner())
-        .unwrap();
-}
-
-#[cfg(debug_assertions)]
-async fn watch_languages(fs: Arc<dyn fs::Fs>, languages: Arc<LanguageRegistry>) -> Option<()> {
-    use std::time::Duration;
-
-    let mut events = fs
-        .watch(
-            "crates/zed2/src/languages".as_ref(),
-            Duration::from_millis(100),
-        )
-        .await;
-    while (events.next().await).is_some() {
-        languages.reload();
-    }
-    Some(())
-}
-
-#[cfg(debug_assertions)]
-fn watch_file_types(fs: Arc<dyn fs::Fs>, cx: &mut AppContext) {
-    use std::time::Duration;
-
-    cx.spawn(|cx| async move {
-        let mut events = fs
-            .watch(
-                "assets/icons/file_icons/file_types.json".as_ref(),
-                Duration::from_millis(100),
-            )
-            .await;
-        while (events.next().await).is_some() {
-            cx.update(|cx| {
-                cx.update_global(|file_types, _| {
-                    *file_types = project_panel::file_associations::FileAssociations::new(Assets);
-                });
-            })
-            .ok();
-        }
-    })
-    .detach()
-}
-
-#[cfg(not(debug_assertions))]
-async fn watch_languages(_: Arc<dyn fs::Fs>, _: Arc<LanguageRegistry>) -> Option<()> {
-    None
-}
-
-#[cfg(not(debug_assertions))]
-fn watch_file_types(_fs: Arc<dyn fs::Fs>, _cx: &mut AppContext) {}

crates/zed2/src/only_instance.rs 🔗

@@ -1,105 +0,0 @@
-use std::{
-    io::{Read, Write},
-    net::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpListener, TcpStream},
-    thread,
-    time::Duration,
-};
-
-use util::channel::ReleaseChannel;
-
-const LOCALHOST: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
-const CONNECT_TIMEOUT: Duration = Duration::from_millis(10);
-const RECEIVE_TIMEOUT: Duration = Duration::from_millis(35);
-const SEND_TIMEOUT: Duration = Duration::from_millis(20);
-
-fn address() -> SocketAddr {
-    let port = match *util::channel::RELEASE_CHANNEL {
-        ReleaseChannel::Dev => 43737,
-        ReleaseChannel::Preview => 43738,
-        ReleaseChannel::Stable => 43739,
-        ReleaseChannel::Nightly => 43740,
-    };
-
-    SocketAddr::V4(SocketAddrV4::new(LOCALHOST, port))
-}
-
-fn instance_handshake() -> &'static str {
-    match *util::channel::RELEASE_CHANNEL {
-        ReleaseChannel::Dev => "Zed Editor Dev Instance Running",
-        ReleaseChannel::Nightly => "Zed Editor Nightly Instance Running",
-        ReleaseChannel::Preview => "Zed Editor Preview Instance Running",
-        ReleaseChannel::Stable => "Zed Editor Stable Instance Running",
-    }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum IsOnlyInstance {
-    Yes,
-    No,
-}
-
-pub fn ensure_only_instance() -> IsOnlyInstance {
-    if *db::ZED_STATELESS || *util::channel::RELEASE_CHANNEL == ReleaseChannel::Dev {
-        return IsOnlyInstance::Yes;
-    }
-
-    if check_got_handshake() {
-        return IsOnlyInstance::No;
-    }
-
-    let listener = match TcpListener::bind(address()) {
-        Ok(listener) => listener,
-
-        Err(err) => {
-            log::warn!("Error binding to single instance port: {err}");
-            if check_got_handshake() {
-                return IsOnlyInstance::No;
-            }
-
-            // Avoid failing to start when some other application by chance already has
-            // a claim on the port. This is sub-par as any other instance that gets launched
-            // will be unable to communicate with this instance and will duplicate
-            log::warn!("Backup handshake request failed, continuing without handshake");
-            return IsOnlyInstance::Yes;
-        }
-    };
-
-    thread::spawn(move || {
-        for stream in listener.incoming() {
-            let mut stream = match stream {
-                Ok(stream) => stream,
-                Err(_) => return,
-            };
-
-            _ = stream.set_nodelay(true);
-            _ = stream.set_read_timeout(Some(SEND_TIMEOUT));
-            _ = stream.write_all(instance_handshake().as_bytes());
-        }
-    });
-
-    IsOnlyInstance::Yes
-}
-
-fn check_got_handshake() -> bool {
-    match TcpStream::connect_timeout(&address(), CONNECT_TIMEOUT) {
-        Ok(mut stream) => {
-            let mut buf = vec![0u8; instance_handshake().len()];
-
-            stream.set_read_timeout(Some(RECEIVE_TIMEOUT)).unwrap();
-            if let Err(err) = stream.read_exact(&mut buf) {
-                log::warn!("Connected to single instance port but failed to read: {err}");
-                return false;
-            }
-
-            if buf == instance_handshake().as_bytes() {
-                log::info!("Got instance handshake");
-                return true;
-            }
-
-            log::warn!("Got wrong instance handshake value");
-            false
-        }
-
-        Err(_) => false,
-    }
-}

crates/zed2/src/open_listener.rs 🔗

@@ -1,303 +0,0 @@
-use anyhow::{anyhow, Context, Result};
-use cli::{ipc, IpcHandshake};
-use cli::{ipc::IpcSender, CliRequest, CliResponse};
-use editor::scroll::autoscroll::Autoscroll;
-use editor::Editor;
-use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
-use futures::channel::{mpsc, oneshot};
-use futures::{FutureExt, SinkExt, StreamExt};
-use gpui::AsyncAppContext;
-use language::{Bias, Point};
-use std::collections::HashMap;
-use std::ffi::OsStr;
-use std::os::unix::prelude::OsStrExt;
-use std::path::Path;
-use std::sync::atomic::Ordering;
-use std::sync::Arc;
-use std::thread;
-use std::time::Duration;
-use std::{path::PathBuf, sync::atomic::AtomicBool};
-use util::channel::parse_zed_link;
-use util::paths::PathLikeWithPosition;
-use util::ResultExt;
-use workspace::AppState;
-
-pub enum OpenRequest {
-    Paths {
-        paths: Vec<PathBuf>,
-    },
-    CliConnection {
-        connection: (mpsc::Receiver<CliRequest>, IpcSender<CliResponse>),
-    },
-    JoinChannel {
-        channel_id: u64,
-    },
-    OpenChannelNotes {
-        channel_id: u64,
-    },
-}
-
-pub struct OpenListener {
-    tx: UnboundedSender<OpenRequest>,
-    pub triggered: AtomicBool,
-}
-
-impl OpenListener {
-    pub fn new() -> (Self, UnboundedReceiver<OpenRequest>) {
-        let (tx, rx) = mpsc::unbounded();
-        (
-            OpenListener {
-                tx,
-                triggered: AtomicBool::new(false),
-            },
-            rx,
-        )
-    }
-
-    pub fn open_urls(&self, urls: &[String]) {
-        self.triggered.store(true, Ordering::Release);
-        let request = if let Some(server_name) =
-            urls.first().and_then(|url| url.strip_prefix("zed-cli://"))
-        {
-            self.handle_cli_connection(server_name)
-        } else if let Some(request_path) = urls.first().and_then(|url| parse_zed_link(url)) {
-            self.handle_zed_url_scheme(request_path)
-        } else {
-            self.handle_file_urls(urls)
-        };
-
-        if let Some(request) = request {
-            self.tx
-                .unbounded_send(request)
-                .map_err(|_| anyhow!("no listener for open requests"))
-                .log_err();
-        }
-    }
-
-    fn handle_cli_connection(&self, server_name: &str) -> Option<OpenRequest> {
-        if let Some(connection) = connect_to_cli(server_name).log_err() {
-            return Some(OpenRequest::CliConnection { connection });
-        }
-
-        None
-    }
-
-    fn handle_zed_url_scheme(&self, request_path: &str) -> Option<OpenRequest> {
-        let mut parts = request_path.split("/");
-        if parts.next() == Some("channel") {
-            if let Some(slug) = parts.next() {
-                if let Some(id_str) = slug.split("-").last() {
-                    if let Ok(channel_id) = id_str.parse::<u64>() {
-                        if Some("notes") == parts.next() {
-                            return Some(OpenRequest::OpenChannelNotes { channel_id });
-                        } else {
-                            return Some(OpenRequest::JoinChannel { channel_id });
-                        }
-                    }
-                }
-            }
-        }
-        log::error!("invalid zed url: {}", request_path);
-        None
-    }
-
-    fn handle_file_urls(&self, urls: &[String]) -> Option<OpenRequest> {
-        let paths: Vec<_> = urls
-            .iter()
-            .flat_map(|url| url.strip_prefix("file://"))
-            .map(|url| {
-                let decoded = urlencoding::decode_binary(url.as_bytes());
-                PathBuf::from(OsStr::from_bytes(decoded.as_ref()))
-            })
-            .collect();
-
-        Some(OpenRequest::Paths { paths })
-    }
-}
-
-fn connect_to_cli(
-    server_name: &str,
-) -> Result<(mpsc::Receiver<CliRequest>, IpcSender<CliResponse>)> {
-    let handshake_tx = cli::ipc::IpcSender::<IpcHandshake>::connect(server_name.to_string())
-        .context("error connecting to cli")?;
-    let (request_tx, request_rx) = ipc::channel::<CliRequest>()?;
-    let (response_tx, response_rx) = ipc::channel::<CliResponse>()?;
-
-    handshake_tx
-        .send(IpcHandshake {
-            requests: request_tx,
-            responses: response_rx,
-        })
-        .context("error sending ipc handshake")?;
-
-    let (mut async_request_tx, async_request_rx) =
-        futures::channel::mpsc::channel::<CliRequest>(16);
-    thread::spawn(move || {
-        while let Ok(cli_request) = request_rx.recv() {
-            if smol::block_on(async_request_tx.send(cli_request)).is_err() {
-                break;
-            }
-        }
-        Ok::<_, anyhow::Error>(())
-    });
-
-    Ok((async_request_rx, response_tx))
-}
-
-pub async fn handle_cli_connection(
-    (mut requests, responses): (mpsc::Receiver<CliRequest>, IpcSender<CliResponse>),
-    app_state: Arc<AppState>,
-    mut cx: AsyncAppContext,
-) {
-    if let Some(request) = requests.next().await {
-        match request {
-            CliRequest::Open { paths, wait } => {
-                let mut caret_positions = HashMap::new();
-
-                let paths = if paths.is_empty() {
-                    workspace::last_opened_workspace_paths()
-                        .await
-                        .map(|location| location.paths().to_vec())
-                        .unwrap_or_default()
-                } else {
-                    paths
-                        .into_iter()
-                        .filter_map(|path_with_position_string| {
-                            let path_with_position = PathLikeWithPosition::parse_str(
-                                &path_with_position_string,
-                                |path_str| {
-                                    Ok::<_, std::convert::Infallible>(
-                                        Path::new(path_str).to_path_buf(),
-                                    )
-                                },
-                            )
-                            .expect("Infallible");
-                            let path = path_with_position.path_like;
-                            if let Some(row) = path_with_position.row {
-                                if path.is_file() {
-                                    let row = row.saturating_sub(1);
-                                    let col =
-                                        path_with_position.column.unwrap_or(0).saturating_sub(1);
-                                    caret_positions.insert(path.clone(), Point::new(row, col));
-                                }
-                            }
-                            Some(path)
-                        })
-                        .collect()
-                };
-
-                let mut errored = false;
-
-                match cx.update(|cx| workspace::open_paths(&paths, &app_state, None, cx)) {
-                    Ok(task) => match task.await {
-                        Ok((workspace, items)) => {
-                            let mut item_release_futures = Vec::new();
-
-                            for (item, path) in items.into_iter().zip(&paths) {
-                                match item {
-                                    Some(Ok(item)) => {
-                                        if let Some(point) = caret_positions.remove(path) {
-                                            if let Some(active_editor) = item.downcast::<Editor>() {
-                                                workspace
-                                                    .update(&mut cx, |_, cx| {
-                                                        active_editor.update(cx, |editor, cx| {
-                                                            let snapshot = editor
-                                                                .snapshot(cx)
-                                                                .display_snapshot;
-                                                            let point = snapshot
-                                                                .buffer_snapshot
-                                                                .clip_point(point, Bias::Left);
-                                                            editor.change_selections(
-                                                                Some(Autoscroll::center()),
-                                                                cx,
-                                                                |s| s.select_ranges([point..point]),
-                                                            );
-                                                        });
-                                                    })
-                                                    .log_err();
-                                            }
-                                        }
-
-                                        cx.update(|cx| {
-                                            let released = oneshot::channel();
-                                            item.on_release(
-                                                cx,
-                                                Box::new(move |_| {
-                                                    let _ = released.0.send(());
-                                                }),
-                                            )
-                                            .detach();
-                                            item_release_futures.push(released.1);
-                                        })
-                                        .log_err();
-                                    }
-                                    Some(Err(err)) => {
-                                        responses
-                                            .send(CliResponse::Stderr {
-                                                message: format!(
-                                                    "error opening {:?}: {}",
-                                                    path, err
-                                                ),
-                                            })
-                                            .log_err();
-                                        errored = true;
-                                    }
-                                    None => {}
-                                }
-                            }
-
-                            if wait {
-                                let background = cx.background_executor().clone();
-                                let wait = async move {
-                                    if paths.is_empty() {
-                                        let (done_tx, done_rx) = oneshot::channel();
-                                        let _subscription = workspace.update(&mut cx, |_, cx| {
-                                            cx.on_release(move |_, _, _| {
-                                                let _ = done_tx.send(());
-                                            })
-                                        });
-                                        let _ = done_rx.await;
-                                    } else {
-                                        let _ = futures::future::try_join_all(item_release_futures)
-                                            .await;
-                                    };
-                                }
-                                .fuse();
-                                futures::pin_mut!(wait);
-
-                                loop {
-                                    // Repeatedly check if CLI is still open to avoid wasting resources
-                                    // waiting for files or workspaces to close.
-                                    let mut timer = background.timer(Duration::from_secs(1)).fuse();
-                                    futures::select_biased! {
-                                        _ = wait => break,
-                                        _ = timer => {
-                                            if responses.send(CliResponse::Ping).is_err() {
-                                                break;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        Err(error) => {
-                            errored = true;
-                            responses
-                                .send(CliResponse::Stderr {
-                                    message: format!("error opening {:?}: {}", paths, error),
-                                })
-                                .log_err();
-                        }
-                    },
-                    Err(_) => errored = true,
-                }
-
-                responses
-                    .send(CliResponse::Exit {
-                        status: i32::from(errored),
-                    })
-                    .log_err();
-            }
-        }
-    }
-}

crates/zed2/src/zed2.rs 🔗

@@ -1,2598 +0,0 @@
-mod app_menus;
-mod assets;
-pub mod languages;
-mod only_instance;
-mod open_listener;
-
-pub use app_menus::*;
-pub use assets::*;
-use assistant::AssistantPanel;
-use breadcrumbs::Breadcrumbs;
-use collections::VecDeque;
-use editor::{Editor, MultiBuffer};
-use gpui::{
-    actions, point, px, AppContext, Context, FocusableView, PromptLevel, TitlebarOptions, View,
-    ViewContext, VisualContext, WindowBounds, WindowKind, WindowOptions,
-};
-pub use only_instance::*;
-pub use open_listener::*;
-
-use anyhow::{anyhow, Context as _};
-use futures::{channel::mpsc, StreamExt};
-use project_panel::ProjectPanel;
-use quick_action_bar::QuickActionBar;
-use search::project_search::ProjectSearchBar;
-use settings::{initial_local_settings_content, load_default_keymap, KeymapFile, Settings};
-use std::{borrow::Cow, ops::Deref, sync::Arc};
-use terminal_view::terminal_panel::TerminalPanel;
-use util::{
-    asset_str,
-    channel::{AppCommitSha, ReleaseChannel},
-    paths::{self, LOCAL_SETTINGS_RELATIVE_PATH},
-    ResultExt,
-};
-use uuid::Uuid;
-use workspace::Pane;
-use workspace::{
-    create_and_open_local_file, notifications::simple_message_notification::MessageNotification,
-    open_new, AppState, NewFile, NewWindow, Workspace, WorkspaceSettings,
-};
-use zed_actions::{OpenBrowser, OpenSettings, OpenZedURL, Quit};
-
-actions!(
-    zed,
-    [
-        About,
-        DebugElements,
-        DecreaseBufferFontSize,
-        Hide,
-        HideOthers,
-        IncreaseBufferFontSize,
-        Minimize,
-        OpenDefaultKeymap,
-        OpenDefaultSettings,
-        OpenKeymap,
-        OpenLicenses,
-        OpenLocalSettings,
-        OpenLog,
-        OpenTelemetryLog,
-        ResetBufferFontSize,
-        ResetDatabase,
-        ShowAll,
-        ToggleFullScreen,
-        Zoom,
-    ]
-);
-
-pub fn build_window_options(
-    bounds: Option<WindowBounds>,
-    display_uuid: Option<Uuid>,
-    cx: &mut AppContext,
-) -> WindowOptions {
-    let bounds = bounds.unwrap_or(WindowBounds::Maximized);
-    let display = display_uuid.and_then(|uuid| {
-        cx.displays()
-            .into_iter()
-            .find(|display| display.uuid().ok() == Some(uuid))
-    });
-
-    WindowOptions {
-        bounds,
-        titlebar: Some(TitlebarOptions {
-            title: None,
-            appears_transparent: true,
-            traffic_light_position: Some(point(px(8.), px(8.))),
-        }),
-        center: false,
-        focus: false,
-        show: false,
-        kind: WindowKind::Normal,
-        is_movable: true,
-        display_id: display.map(|display| display.id()),
-    }
-}
-
-pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
-    cx.observe_new_views(move |workspace: &mut Workspace, cx| {
-        let workspace_handle = cx.view().clone();
-        let center_pane = workspace.active_pane().clone();
-        initialize_pane(workspace, &center_pane, cx);
-        cx.subscribe(&workspace_handle, {
-            move |workspace, _, event, cx| {
-                if let workspace::Event::PaneAdded(pane) = event {
-                    initialize_pane(workspace, pane, cx);
-                }
-            }
-        })
-        .detach();
-
-        //     cx.emit(workspace2::Event::PaneAdded(
-        //         workspace.active_pane().clone(),
-        //     ));
-
-        //     let collab_titlebar_item =
-        //         cx.add_view(|cx| CollabTitlebarItem::new(workspace, &workspace_handle, cx));
-        //     workspace.set_titlebar_item(collab_titlebar_item.into_any(), cx);
-
-        let copilot =
-            cx.new_view(|cx| copilot_button::CopilotButton::new(app_state.fs.clone(), cx));
-        let diagnostic_summary =
-            cx.new_view(|cx| diagnostics::items::DiagnosticIndicator::new(workspace, cx));
-        let activity_indicator =
-            activity_indicator::ActivityIndicator::new(workspace, app_state.languages.clone(), cx);
-        let active_buffer_language =
-            cx.new_view(|_| language_selector::ActiveBufferLanguage::new(workspace));
-        let vim_mode_indicator = cx.new_view(|cx| vim::ModeIndicator::new(cx));
-        let feedback_button =
-            cx.new_view(|_| feedback::deploy_feedback_button::DeployFeedbackButton::new(workspace));
-        let cursor_position = cx.new_view(|_| editor::items::CursorPosition::new());
-        workspace.status_bar().update(cx, |status_bar, cx| {
-            status_bar.add_left_item(diagnostic_summary, cx);
-            status_bar.add_left_item(activity_indicator, cx);
-            status_bar.add_right_item(feedback_button, cx);
-            // status_bar.add_right_item(copilot, cx);
-            status_bar.add_right_item(copilot, cx);
-            status_bar.add_right_item(active_buffer_language, cx);
-            status_bar.add_right_item(vim_mode_indicator, cx);
-            status_bar.add_right_item(cursor_position, cx);
-        });
-
-        auto_update::notify_of_any_new_update(cx);
-
-        vim::observe_keystrokes(cx);
-
-        let handle = cx.view().downgrade();
-        cx.on_window_should_close(move |cx| {
-            handle
-                .update(cx, |workspace, cx| {
-                    workspace.close_window(&Default::default(), cx);
-                    false
-                })
-                .unwrap_or(true)
-        });
-
-        cx.spawn(|workspace_handle, mut cx| async move {
-            let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
-            let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
-            let assistant_panel = AssistantPanel::load(workspace_handle.clone(), cx.clone());
-            let channels_panel =
-                collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
-            let chat_panel =
-                collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
-            let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
-                workspace_handle.clone(),
-                cx.clone(),
-            );
-            let (
-                project_panel,
-                terminal_panel,
-                assistant_panel,
-                channels_panel,
-                chat_panel,
-                notification_panel,
-            ) = futures::try_join!(
-                project_panel,
-                terminal_panel,
-                assistant_panel,
-                channels_panel,
-                chat_panel,
-                notification_panel,
-            )?;
-
-            workspace_handle.update(&mut cx, |workspace, cx| {
-                workspace.add_panel(project_panel, cx);
-                workspace.add_panel(terminal_panel, cx);
-                workspace.add_panel(assistant_panel, cx);
-                workspace.add_panel(channels_panel, cx);
-                workspace.add_panel(chat_panel, cx);
-                workspace.add_panel(notification_panel, cx);
-
-                // if !was_deserialized
-                //     && workspace
-                //         .project()
-                //         .read(cx)
-                //         .visible_worktrees(cx)
-                //         .any(|tree| {
-                //             tree.read(cx)
-                //                 .root_entry()
-                //                 .map_or(false, |entry| entry.is_dir())
-                //         })
-                // {
-                //     workspace.toggle_dock(project_panel_position, cx);
-                // }
-                cx.focus_self();
-            })
-        })
-        .detach();
-
-        workspace
-            .register_action(about)
-            .register_action(|_, _: &Hide, cx| {
-                cx.hide();
-            })
-            .register_action(|_, _: &HideOthers, cx| {
-                cx.hide_other_apps();
-            })
-            .register_action(|_, _: &ShowAll, cx| {
-                cx.unhide_other_apps();
-            })
-            .register_action(|_, _: &Minimize, cx| {
-                cx.minimize_window();
-            })
-            .register_action(|_, _: &Zoom, cx| {
-                cx.zoom_window();
-            })
-            .register_action(|_, _: &ToggleFullScreen, cx| {
-                cx.toggle_full_screen();
-            })
-            .register_action(quit)
-            .register_action(|_, action: &OpenZedURL, cx| {
-                cx.global::<Arc<OpenListener>>()
-                    .open_urls(&[action.url.clone()])
-            })
-            .register_action(|_, action: &OpenBrowser, cx| cx.open_url(&action.url))
-            .register_action(move |_, _: &IncreaseBufferFontSize, cx| {
-                theme::adjust_font_size(cx, |size| *size += px(1.0))
-            })
-            .register_action(move |_, _: &DecreaseBufferFontSize, cx| {
-                theme::adjust_font_size(cx, |size| *size -= px(1.0))
-            })
-            .register_action(move |_, _: &ResetBufferFontSize, cx| theme::reset_font_size(cx))
-            .register_action(|_, _: &install_cli::Install, cx| {
-                cx.spawn(|_, cx| async move {
-                    install_cli::install_cli(cx.deref())
-                        .await
-                        .context("error creating CLI symlink")
-                })
-                .detach_and_log_err(cx);
-            })
-            .register_action(|workspace, _: &OpenLog, cx| {
-                open_log_file(workspace, cx);
-            })
-            .register_action(|workspace, _: &OpenLicenses, cx| {
-                open_bundled_file(
-                    workspace,
-                    asset_str::<Assets>("licenses.md"),
-                    "Open Source License Attribution",
-                    "Markdown",
-                    cx,
-                );
-            })
-            .register_action(
-                move |workspace: &mut Workspace,
-                      _: &OpenTelemetryLog,
-                      cx: &mut ViewContext<Workspace>| {
-                    open_telemetry_log_file(workspace, cx);
-                },
-            )
-            .register_action(
-                move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
-                    create_and_open_local_file(&paths::KEYMAP, cx, Default::default)
-                        .detach_and_log_err(cx);
-                },
-            )
-            .register_action(
-                move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
-                    create_and_open_local_file(&paths::SETTINGS, cx, || {
-                        settings::initial_user_settings_content().as_ref().into()
-                    })
-                    .detach_and_log_err(cx);
-                },
-            )
-            .register_action(open_local_settings_file)
-            .register_action(
-                move |workspace: &mut Workspace,
-                      _: &OpenDefaultKeymap,
-                      cx: &mut ViewContext<Workspace>| {
-                    open_bundled_file(
-                        workspace,
-                        settings::default_keymap(),
-                        "Default Key Bindings",
-                        "JSON",
-                        cx,
-                    );
-                },
-            )
-            .register_action(
-                move |workspace: &mut Workspace,
-                      _: &OpenDefaultSettings,
-                      cx: &mut ViewContext<Workspace>| {
-                    open_bundled_file(
-                        workspace,
-                        settings::default_settings(),
-                        "Default Settings",
-                        "JSON",
-                        cx,
-                    );
-                },
-            )
-            //todo!()
-            // cx.add_action({
-            //     move |workspace: &mut Workspace, _: &DebugElements, cx: &mut ViewContext<Workspace>| {
-            //         let app_state = workspace.app_state().clone();
-            //         let markdown = app_state.languages.language_for_name("JSON");
-            //         let window = cx.window();
-            //         cx.spawn(|workspace, mut cx| async move {
-            //             let markdown = markdown.await.log_err();
-            //             let content = to_string_pretty(&window.debug_elements(&cx).ok_or_else(|| {
-            //                 anyhow!("could not debug elements for window {}", window.id())
-            //             })?)
-            //             .unwrap();
-            //             workspace
-            //                 .update(&mut cx, |workspace, cx| {
-            //                     workspace.with_local_workspace(cx, move |workspace, cx| {
-            //                         let project = workspace.project().clone();
-            //                         let buffer = project
-            //                             .update(cx, |project, cx| {
-            //                                 project.create_buffer(&content, markdown, cx)
-            //                             })
-            //                             .expect("creating buffers on a local workspace always succeeds");
-            //                         let buffer = cx.add_model(|cx| {
-            //                             MultiBuffer::singleton(buffer, cx)
-            //                                 .with_title("Debug Elements".into())
-            //                         });
-            //                         workspace.add_item(
-            //                             Box::new(cx.add_view(|cx| {
-            //                                 Editor::for_multibuffer(buffer, Some(project.clone()), cx)
-            //                             })),
-            //                             cx,
-            //                         );
-            //                     })
-            //                 })?
-            //                 .await
-            //         })
-            //         .detach_and_log_err(cx);
-            //     }
-            // });
-            // .register_action(
-            //     |workspace: &mut Workspace,
-            //      _: &project_panel::ToggleFocus,
-            //      cx: &mut ViewContext<Workspace>| {
-            //         workspace.toggle_panel_focus::<ProjectPanel>(cx);
-            //     },
-            // );
-            // cx.add_action(
-            //     |workspace: &mut Workspace,
-            //      _: &collab_ui::collab_panel::ToggleFocus,
-            //      cx: &mut ViewContext<Workspace>| {
-            //         workspace.toggle_panel_focus::<collab_ui::collab_panel::CollabPanel>(cx);
-            //     },
-            // );
-            // cx.add_action(
-            //     |workspace: &mut Workspace,
-            //      _: &collab_ui::chat_panel::ToggleFocus,
-            //      cx: &mut ViewContext<Workspace>| {
-            //         workspace.toggle_panel_focus::<collab_ui::chat_panel::ChatPanel>(cx);
-            //     },
-            // );
-            // cx.add_action(
-            //     |workspace: &mut Workspace,
-            //      _: &collab_ui::notification_panel::ToggleFocus,
-            //      cx: &mut ViewContext<Workspace>| {
-            //         workspace.toggle_panel_focus::<collab_ui::notification_panel::NotificationPanel>(cx);
-            //     },
-            // );
-            // cx.add_action(
-            //     |workspace: &mut Workspace,
-            //      _: &terminal_panel::ToggleFocus,
-            //      cx: &mut ViewContext<Workspace>| {
-            //         workspace.toggle_panel_focus::<TerminalPanel>(cx);
-            //     },
-            // );
-            .register_action({
-                let app_state = Arc::downgrade(&app_state);
-                move |_, _: &NewWindow, cx| {
-                    if let Some(app_state) = app_state.upgrade() {
-                        open_new(&app_state, cx, |workspace, cx| {
-                            Editor::new_file(workspace, &Default::default(), cx)
-                        })
-                        .detach();
-                    }
-                }
-            })
-            .register_action({
-                let app_state = Arc::downgrade(&app_state);
-                move |_, _: &NewFile, cx| {
-                    if let Some(app_state) = app_state.upgrade() {
-                        open_new(&app_state, cx, |workspace, cx| {
-                            Editor::new_file(workspace, &Default::default(), cx)
-                        })
-                        .detach();
-                    }
-                }
-            });
-
-        workspace.focus_handle(cx).focus(cx);
-        //todo!()
-        // load_default_keymap(cx);
-    })
-    .detach();
-}
-
-fn initialize_pane(workspace: &mut Workspace, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
-    pane.update(cx, |pane, cx| {
-        pane.toolbar().update(cx, |toolbar, cx| {
-            let breadcrumbs = cx.new_view(|_| Breadcrumbs::new());
-            toolbar.add_item(breadcrumbs, cx);
-            let buffer_search_bar = cx.new_view(search::BufferSearchBar::new);
-            toolbar.add_item(buffer_search_bar.clone(), cx);
-
-            let quick_action_bar =
-                cx.new_view(|_| QuickActionBar::new(buffer_search_bar, workspace));
-            toolbar.add_item(quick_action_bar, cx);
-            let diagnostic_editor_controls = cx.new_view(|_| diagnostics::ToolbarControls::new());
-            toolbar.add_item(diagnostic_editor_controls, cx);
-            let project_search_bar = cx.new_view(|_| ProjectSearchBar::new());
-            toolbar.add_item(project_search_bar, cx);
-            let lsp_log_item = cx.new_view(|_| language_tools::LspLogToolbarItemView::new());
-            toolbar.add_item(lsp_log_item, cx);
-            let syntax_tree_item =
-                cx.new_view(|_| language_tools::SyntaxTreeToolbarItemView::new());
-            toolbar.add_item(syntax_tree_item, cx);
-        })
-    });
-}
-
-fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
-    use std::fmt::Write as _;
-
-    let app_name = cx.global::<ReleaseChannel>().display_name();
-    let version = env!("CARGO_PKG_VERSION");
-    let mut message = format!("{app_name} {version}");
-    if let Some(sha) = cx.try_global::<AppCommitSha>() {
-        write!(&mut message, "\n\n{}", sha.0).unwrap();
-    }
-
-    let prompt = cx.prompt(PromptLevel::Info, &message, &["OK"]);
-    cx.foreground_executor()
-        .spawn(async {
-            prompt.await.ok();
-        })
-        .detach();
-}
-
-fn quit(_: &mut Workspace, _: &Quit, cx: &mut gpui::ViewContext<Workspace>) {
-    let should_confirm = WorkspaceSettings::get_global(cx).confirm_quit;
-    cx.spawn(|_, mut cx| async move {
-        let mut workspace_windows = cx.update(|_, cx| {
-            cx.windows()
-                .into_iter()
-                .filter_map(|window| window.downcast::<Workspace>())
-                .collect::<Vec<_>>()
-        })?;
-
-        // If multiple windows have unsaved changes, and need a save prompt,
-        // prompt in the active window before switching to a different window.
-        cx.update(|_, cx| {
-            workspace_windows.sort_by_key(|window| window.is_active(&cx) == Some(false));
-        })
-        .log_err();
-
-        if let (true, Some(_)) = (should_confirm, workspace_windows.first().copied()) {
-            let answer = cx
-                .update(|_, cx| {
-                    cx.prompt(
-                        PromptLevel::Info,
-                        "Are you sure you want to quit?",
-                        &["Quit", "Cancel"],
-                    )
-                })
-                .log_err();
-
-            if let Some(answer) = answer {
-                let answer = answer.await.ok();
-                if answer != Some(0) {
-                    return Ok(());
-                }
-            }
-        }
-
-        // If the user cancels any save prompt, then keep the app open.
-        for window in workspace_windows {
-            if let Some(should_close) = window
-                .update(&mut cx, |workspace, cx| {
-                    workspace.prepare_to_close(true, cx)
-                })
-                .log_err()
-            {
-                if !should_close.await? {
-                    return Ok(());
-                }
-            }
-        }
-        cx.update(|_, cx| {
-            cx.quit();
-        })?;
-        anyhow::Ok(())
-    })
-    .detach_and_log_err(cx);
-}
-
-fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
-    const MAX_LINES: usize = 1000;
-    workspace
-        .with_local_workspace(cx, move |workspace, cx| {
-            let fs = workspace.app_state().fs.clone();
-            cx.spawn(|workspace, mut cx| async move {
-                let (old_log, new_log) =
-                    futures::join!(fs.load(&paths::OLD_LOG), fs.load(&paths::LOG));
-
-                let mut lines = VecDeque::with_capacity(MAX_LINES);
-                for line in old_log
-                    .iter()
-                    .flat_map(|log| log.lines())
-                    .chain(new_log.iter().flat_map(|log| log.lines()))
-                {
-                    if lines.len() == MAX_LINES {
-                        lines.pop_front();
-                    }
-                    lines.push_back(line);
-                }
-                let log = lines
-                    .into_iter()
-                    .flat_map(|line| [line, "\n"])
-                    .collect::<String>();
-
-                workspace
-                    .update(&mut cx, |workspace, cx| {
-                        let project = workspace.project().clone();
-                        let buffer = project
-                            .update(cx, |project, cx| project.create_buffer("", None, cx))
-                            .expect("creating buffers on a local workspace always succeeds");
-                        buffer.update(cx, |buffer, cx| buffer.edit([(0..0, log)], None, cx));
-
-                        let buffer = cx.new_model(|cx| {
-                            MultiBuffer::singleton(buffer, cx).with_title("Log".into())
-                        });
-                        workspace.add_item(
-                            Box::new(
-                                cx.new_view(|cx| {
-                                    Editor::for_multibuffer(buffer, Some(project), cx)
-                                }),
-                            ),
-                            cx,
-                        );
-                    })
-                    .log_err();
-            })
-            .detach();
-        })
-        .detach();
-}
-
-pub fn handle_keymap_file_changes(
-    mut user_keymap_file_rx: mpsc::UnboundedReceiver<String>,
-    cx: &mut AppContext,
-) {
-    cx.spawn(move |cx| async move {
-        //  let mut settings_subscription = None;
-        while let Some(user_keymap_content) = user_keymap_file_rx.next().await {
-            if let Some(keymap_content) = KeymapFile::parse(&user_keymap_content).log_err() {
-                cx.update(|cx| reload_keymaps(cx, &keymap_content)).ok();
-
-                // todo!()
-                // let mut old_base_keymap = cx.read(|cx| *settings::get::<BaseKeymap>(cx));
-                // drop(settings_subscription);
-                // settings_subscription = Some(cx.update(|cx| {
-                //     cx.observe_global::<SettingsStore, _>(move |cx| {
-                //         let new_base_keymap = *settings::get::<BaseKeymap>(cx);
-                //         if new_base_keymap != old_base_keymap {
-                //             old_base_keymap = new_base_keymap.clone();
-                //             reload_keymaps(cx, &keymap_content);
-                //         }
-                //     })
-                // }));
-            }
-        }
-    })
-    .detach();
-}
-
-fn reload_keymaps(cx: &mut AppContext, keymap_content: &KeymapFile) {
-    // todo!()
-    // cx.clear_bindings();
-    load_default_keymap(cx);
-    keymap_content.clone().add_to_cx(cx).log_err();
-    cx.set_menus(app_menus());
-}
-
-fn open_local_settings_file(
-    workspace: &mut Workspace,
-    _: &OpenLocalSettings,
-    cx: &mut ViewContext<Workspace>,
-) {
-    let project = workspace.project().clone();
-    let worktree = project
-        .read(cx)
-        .visible_worktrees(cx)
-        .find_map(|tree| tree.read(cx).root_entry()?.is_dir().then_some(tree));
-    if let Some(worktree) = worktree {
-        let tree_id = worktree.read(cx).id();
-        cx.spawn(|workspace, mut cx| async move {
-            let file_path = &*LOCAL_SETTINGS_RELATIVE_PATH;
-
-            if let Some(dir_path) = file_path.parent() {
-                if worktree.update(&mut cx, |tree, _| tree.entry_for_path(dir_path).is_none())? {
-                    project
-                        .update(&mut cx, |project, cx| {
-                            project.create_entry((tree_id, dir_path), true, cx)
-                        })?
-                        .await
-                        .context("worktree was removed")?;
-                }
-            }
-
-            if worktree.update(&mut cx, |tree, _| tree.entry_for_path(file_path).is_none())? {
-                project
-                    .update(&mut cx, |project, cx| {
-                        project.create_entry((tree_id, file_path), false, cx)
-                    })?
-                    .await
-                    .context("worktree was removed")?;
-            }
-
-            let editor = workspace
-                .update(&mut cx, |workspace, cx| {
-                    workspace.open_path((tree_id, file_path), None, true, cx)
-                })?
-                .await?
-                .downcast::<Editor>()
-                .ok_or_else(|| anyhow!("unexpected item type"))?;
-
-            editor
-                .downgrade()
-                .update(&mut cx, |editor, cx| {
-                    if let Some(buffer) = editor.buffer().read(cx).as_singleton() {
-                        if buffer.read(cx).is_empty() {
-                            buffer.update(cx, |buffer, cx| {
-                                buffer.edit([(0..0, initial_local_settings_content())], None, cx)
-                            });
-                        }
-                    }
-                })
-                .ok();
-
-            anyhow::Ok(())
-        })
-        .detach();
-    } else {
-        workspace.show_notification(0, cx, |cx| {
-            cx.new_view(|_| MessageNotification::new("This project has no folders open."))
-        })
-    }
-}
-
-fn open_telemetry_log_file(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) {
-    workspace.with_local_workspace(cx, move |workspace, cx| {
-        let app_state = workspace.app_state().clone();
-        cx.spawn(|workspace, mut cx| async move {
-            async fn fetch_log_string(app_state: &Arc<AppState>) -> Option<String> {
-                let path = app_state.client.telemetry().log_file_path()?;
-                app_state.fs.load(&path).await.log_err()
-            }
-
-            let log = fetch_log_string(&app_state).await.unwrap_or_else(|| "// No data has been collected yet".to_string());
-
-            const MAX_TELEMETRY_LOG_LEN: usize = 5 * 1024 * 1024;
-            let mut start_offset = log.len().saturating_sub(MAX_TELEMETRY_LOG_LEN);
-            if let Some(newline_offset) = log[start_offset..].find('\n') {
-                start_offset += newline_offset + 1;
-            }
-            let log_suffix = &log[start_offset..];
-            let json = app_state.languages.language_for_name("JSON").await.log_err();
-
-            workspace.update(&mut cx, |workspace, cx| {
-                let project = workspace.project().clone();
-                let buffer = project
-                    .update(cx, |project, cx| project.create_buffer("", None, cx))
-                    .expect("creating buffers on a local workspace always succeeds");
-                buffer.update(cx, |buffer, cx| {
-                    buffer.set_language(json, cx);
-                    buffer.edit(
-                        [(
-                            0..0,
-                            concat!(
-                                "// Zed collects anonymous usage data to help us understand how people are using the app.\n",
-                                "// Telemetry can be disabled via the `settings.json` file.\n",
-                                "// Here is the data that has been reported for the current session:\n",
-                                "\n"
-                            ),
-                        )],
-                        None,
-                        cx,
-                    );
-                    buffer.edit([(buffer.len()..buffer.len(), log_suffix)], None, cx);
-                });
-
-                let buffer = cx.new_model(|cx| {
-                    MultiBuffer::singleton(buffer, cx).with_title("Telemetry Log".into())
-                });
-                workspace.add_item(
-                    Box::new(cx.new_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx))),
-                    cx,
-                );
-            }).log_err()?;
-
-            Some(())
-        })
-        .detach();
-    }).detach();
-}
-
-fn open_bundled_file(
-    workspace: &mut Workspace,
-    text: Cow<'static, str>,
-    title: &'static str,
-    language: &'static str,
-    cx: &mut ViewContext<Workspace>,
-) {
-    let language = workspace.app_state().languages.language_for_name(language);
-    cx.spawn(|workspace, mut cx| async move {
-        let language = language.await.log_err();
-        workspace
-            .update(&mut cx, |workspace, cx| {
-                workspace.with_local_workspace(cx, |workspace, cx| {
-                    let project = workspace.project();
-                    let buffer = project.update(cx, move |project, cx| {
-                        project
-                            .create_buffer(text.as_ref(), language, cx)
-                            .expect("creating buffers on a local workspace always succeeds")
-                    });
-                    let buffer = cx.new_model(|cx| {
-                        MultiBuffer::singleton(buffer, cx).with_title(title.into())
-                    });
-                    workspace.add_item(
-                        Box::new(cx.new_view(|cx| {
-                            Editor::for_multibuffer(buffer, Some(project.clone()), cx)
-                        })),
-                        cx,
-                    );
-                })
-            })?
-            .await
-    })
-    .detach_and_log_err(cx);
-}
-
-// todo!()
-// #[cfg(test)]
-// mod tests {
-//     use super::*;
-//     use assets::Assets;
-//     use editor::{scroll::autoscroll::Autoscroll, DisplayPoint, Editor};
-//     use fs::{FakeFs, Fs};
-//     use gpui::{
-//         actions, elements::Empty, executor::Deterministic, Action, AnyElement, AnyWindowHandle,
-//         AppContext, AssetSource, Element, Entity, TestAppContext, View, ViewHandle,
-//     };
-//     use language::LanguageRegistry;
-//     use project::{project_settings::ProjectSettings, Project, ProjectPath};
-//     use serde_json::json;
-//     use settings::{handle_settings_file_changes, watch_config_file, SettingsStore};
-//     use std::{
-//         collections::HashSet,
-//         path::{Path, PathBuf},
-//     };
-//     use theme::{ThemeRegistry, ThemeSettings};
-//     use workspace::{
-//         item::{Item, ItemHandle},
-//         open_new, open_paths, pane, NewFile, SaveIntent, SplitDirection, WorkspaceHandle,
-//     };
-
-//     #[gpui::test]
-//     async fn test_open_paths_action(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree(
-//                 "/root",
-//                 json!({
-//                     "a": {
-//                         "aa": null,
-//                         "ab": null,
-//                     },
-//                     "b": {
-//                         "ba": null,
-//                         "bb": null,
-//                     },
-//                     "c": {
-//                         "ca": null,
-//                         "cb": null,
-//                     },
-//                     "d": {
-//                         "da": null,
-//                         "db": null,
-//                     },
-//                 }),
-//             )
-//             .await;
-
-//         cx.update(|cx| {
-//             open_paths(
-//                 &[PathBuf::from("/root/a"), PathBuf::from("/root/b")],
-//                 &app_state,
-//                 None,
-//                 cx,
-//             )
-//         })
-//         .await
-//         .unwrap();
-//         assert_eq!(cx.windows().len(), 1);
-
-//         cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(cx.windows().len(), 1);
-//         let workspace_1 = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
-//         workspace_1.update(cx, |workspace, cx| {
-//             assert_eq!(workspace.worktrees(cx).count(), 2);
-//             assert!(workspace.left_dock().read(cx).is_open());
-//             assert!(workspace.active_pane().is_focused(cx));
-//         });
-
-//         cx.update(|cx| {
-//             open_paths(
-//                 &[PathBuf::from("/root/b"), PathBuf::from("/root/c")],
-//                 &app_state,
-//                 None,
-//                 cx,
-//             )
-//         })
-//         .await
-//         .unwrap();
-//         assert_eq!(cx.windows().len(), 2);
-
-//         // Replace existing windows
-//         let window = cx.windows()[0].downcast::<Workspace>().unwrap();
-//         cx.update(|cx| {
-//             open_paths(
-//                 &[PathBuf::from("/root/c"), PathBuf::from("/root/d")],
-//                 &app_state,
-//                 Some(window),
-//                 cx,
-//             )
-//         })
-//         .await
-//         .unwrap();
-//         assert_eq!(cx.windows().len(), 2);
-//         let workspace_1 = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
-//         workspace_1.update(cx, |workspace, cx| {
-//             assert_eq!(
-//                 workspace
-//                     .worktrees(cx)
-//                     .map(|w| w.read(cx).abs_path())
-//                     .collect::<Vec<_>>(),
-//                 &[Path::new("/root/c").into(), Path::new("/root/d").into()]
-//             );
-//             assert!(workspace.left_dock().read(cx).is_open());
-//             assert!(workspace.active_pane().is_focused(cx));
-//         });
-//     }
-
-//     #[gpui::test]
-//     async fn test_window_edit_state(executor: Arc<Deterministic>, cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree("/root", json!({"a": "hey"}))
-//             .await;
-
-//         cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(cx.windows().len(), 1);
-
-//         // When opening the workspace, the window is not in a edited state.
-//         let window = cx.windows()[0].downcast::<Workspace>().unwrap();
-//         let workspace = window.root(cx);
-//         let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
-//         let editor = workspace.read_with(cx, |workspace, cx| {
-//             workspace
-//                 .active_item(cx)
-//                 .unwrap()
-//                 .downcast::<Editor>()
-//                 .unwrap()
-//         });
-//         assert!(!window.is_edited(cx));
-
-//         // Editing a buffer marks the window as edited.
-//         editor.update(cx, |editor, cx| editor.insert("EDIT", cx));
-//         assert!(window.is_edited(cx));
-
-//         // Undoing the edit restores the window's edited state.
-//         editor.update(cx, |editor, cx| editor.undo(&Default::default(), cx));
-//         assert!(!window.is_edited(cx));
-
-//         // Redoing the edit marks the window as edited again.
-//         editor.update(cx, |editor, cx| editor.redo(&Default::default(), cx));
-//         assert!(window.is_edited(cx));
-
-//         // Closing the item restores the window's edited state.
-//         let close = pane.update(cx, |pane, cx| {
-//             drop(editor);
-//             pane.close_active_item(&Default::default(), cx).unwrap()
-//         });
-//         executor.run_until_parked();
-
-//         window.simulate_prompt_answer(1, cx);
-//         close.await.unwrap();
-//         assert!(!window.is_edited(cx));
-
-//         // Opening the buffer again doesn't impact the window's edited state.
-//         cx.update(|cx| open_paths(&[PathBuf::from("/root/a")], &app_state, None, cx))
-//             .await
-//             .unwrap();
-//         let editor = workspace.read_with(cx, |workspace, cx| {
-//             workspace
-//                 .active_item(cx)
-//                 .unwrap()
-//                 .downcast::<Editor>()
-//                 .unwrap()
-//         });
-//         assert!(!window.is_edited(cx));
-
-//         // Editing the buffer marks the window as edited.
-//         editor.update(cx, |editor, cx| editor.insert("EDIT", cx));
-//         assert!(window.is_edited(cx));
-
-//         // Ensure closing the window via the mouse gets preempted due to the
-//         // buffer having unsaved changes.
-//         assert!(!window.simulate_close(cx));
-//         executor.run_until_parked();
-//         assert_eq!(cx.windows().len(), 1);
-
-//         // The window is successfully closed after the user dismisses the prompt.
-//         window.simulate_prompt_answer(1, cx);
-//         executor.run_until_parked();
-//         assert_eq!(cx.windows().len(), 0);
-//     }
-
-//     #[gpui::test]
-//     async fn test_new_empty_workspace(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         cx.update(|cx| {
-//             open_new(&app_state, cx, |workspace, cx| {
-//                 Editor::new_file(workspace, &Default::default(), cx)
-//             })
-//         })
-//         .await;
-
-//         let window = cx
-//             .windows()
-//             .first()
-//             .unwrap()
-//             .downcast::<Workspace>()
-//             .unwrap();
-//         let workspace = window.root(cx);
-
-//         let editor = workspace.update(cx, |workspace, cx| {
-//             workspace
-//                 .active_item(cx)
-//                 .unwrap()
-//                 .downcast::<editor::Editor>()
-//                 .unwrap()
-//         });
-
-//         editor.update(cx, |editor, cx| {
-//             assert!(editor.text(cx).is_empty());
-//             assert!(!editor.is_dirty(cx));
-//         });
-
-//         let save_task = workspace.update(cx, |workspace, cx| {
-//             workspace.save_active_item(SaveIntent::Save, cx)
-//         });
-//         app_state.fs.create_dir(Path::new("/root")).await.unwrap();
-//         cx.foreground().run_until_parked();
-//         cx.simulate_new_path_selection(|_| Some(PathBuf::from("/root/the-new-name")));
-//         save_task.await.unwrap();
-//         editor.read_with(cx, |editor, cx| {
-//             assert!(!editor.is_dirty(cx));
-//             assert_eq!(editor.title(cx), "the-new-name");
-//         });
-//     }
-
-//     #[gpui::test]
-//     async fn test_open_entry(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree(
-//                 "/root",
-//                 json!({
-//                     "a": {
-//                         "file1": "contents 1",
-//                         "file2": "contents 2",
-//                         "file3": "contents 3",
-//                     },
-//                 }),
-//             )
-//             .await;
-
-//         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
-//         let window = cx.add_window(|cx| Workspace::test_new(project, cx));
-//         let workspace = window.root(cx);
-
-//         let entries = cx.read(|cx| workspace.file_project_paths(cx));
-//         let file1 = entries[0].clone();
-//         let file2 = entries[1].clone();
-//         let file3 = entries[2].clone();
-
-//         // Open the first entry
-//         let entry_1 = workspace
-//             .update(cx, |w, cx| w.open_path(file1.clone(), None, true, cx))
-//             .await
-//             .unwrap();
-//         cx.read(|cx| {
-//             let pane = workspace.read(cx).active_pane().read(cx);
-//             assert_eq!(
-//                 pane.active_item().unwrap().project_path(cx),
-//                 Some(file1.clone())
-//             );
-//             assert_eq!(pane.items_len(), 1);
-//         });
-
-//         // Open the second entry
-//         workspace
-//             .update(cx, |w, cx| w.open_path(file2.clone(), None, true, cx))
-//             .await
-//             .unwrap();
-//         cx.read(|cx| {
-//             let pane = workspace.read(cx).active_pane().read(cx);
-//             assert_eq!(
-//                 pane.active_item().unwrap().project_path(cx),
-//                 Some(file2.clone())
-//             );
-//             assert_eq!(pane.items_len(), 2);
-//         });
-
-//         // Open the first entry again. The existing pane item is activated.
-//         let entry_1b = workspace
-//             .update(cx, |w, cx| w.open_path(file1.clone(), None, true, cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(entry_1.id(), entry_1b.id());
-
-//         cx.read(|cx| {
-//             let pane = workspace.read(cx).active_pane().read(cx);
-//             assert_eq!(
-//                 pane.active_item().unwrap().project_path(cx),
-//                 Some(file1.clone())
-//             );
-//             assert_eq!(pane.items_len(), 2);
-//         });
-
-//         // Split the pane with the first entry, then open the second entry again.
-//         workspace
-//             .update(cx, |w, cx| {
-//                 w.split_and_clone(w.active_pane().clone(), SplitDirection::Right, cx);
-//                 w.open_path(file2.clone(), None, true, cx)
-//             })
-//             .await
-//             .unwrap();
-
-//         workspace.read_with(cx, |w, cx| {
-//             assert_eq!(
-//                 w.active_pane()
-//                     .read(cx)
-//                     .active_item()
-//                     .unwrap()
-//                     .project_path(cx),
-//                 Some(file2.clone())
-//             );
-//         });
-
-//         // Open the third entry twice concurrently. Only one pane item is added.
-//         let (t1, t2) = workspace.update(cx, |w, cx| {
-//             (
-//                 w.open_path(file3.clone(), None, true, cx),
-//                 w.open_path(file3.clone(), None, true, cx),
-//             )
-//         });
-//         t1.await.unwrap();
-//         t2.await.unwrap();
-//         cx.read(|cx| {
-//             let pane = workspace.read(cx).active_pane().read(cx);
-//             assert_eq!(
-//                 pane.active_item().unwrap().project_path(cx),
-//                 Some(file3.clone())
-//             );
-//             let pane_entries = pane
-//                 .items()
-//                 .map(|i| i.project_path(cx).unwrap())
-//                 .collect::<Vec<_>>();
-//             assert_eq!(pane_entries, &[file1, file2, file3]);
-//         });
-//     }
-
-//     #[gpui::test]
-//     async fn test_open_paths(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree(
-//                 "/",
-//                 json!({
-//                     "dir1": {
-//                         "a.txt": ""
-//                     },
-//                     "dir2": {
-//                         "b.txt": ""
-//                     },
-//                     "dir3": {
-//                         "c.txt": ""
-//                     },
-//                     "d.txt": ""
-//                 }),
-//             )
-//             .await;
-
-//         cx.update(|cx| open_paths(&[PathBuf::from("/dir1/")], &app_state, None, cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(cx.windows().len(), 1);
-//         let workspace = cx.windows()[0].downcast::<Workspace>().unwrap().root(cx);
-
-//         #[track_caller]
-//         fn assert_project_panel_selection(
-//             workspace: &Workspace,
-//             expected_worktree_path: &Path,
-//             expected_entry_path: &Path,
-//             cx: &AppContext,
-//         ) {
-//             let project_panel = [
-//                 workspace.left_dock().read(cx).panel::<ProjectPanel>(),
-//                 workspace.right_dock().read(cx).panel::<ProjectPanel>(),
-//                 workspace.bottom_dock().read(cx).panel::<ProjectPanel>(),
-//             ]
-//             .into_iter()
-//             .find_map(std::convert::identity)
-//             .expect("found no project panels")
-//             .read(cx);
-//             let (selected_worktree, selected_entry) = project_panel
-//                 .selected_entry(cx)
-//                 .expect("project panel should have a selected entry");
-//             assert_eq!(
-//                 selected_worktree.abs_path().as_ref(),
-//                 expected_worktree_path,
-//                 "Unexpected project panel selected worktree path"
-//             );
-//             assert_eq!(
-//                 selected_entry.path.as_ref(),
-//                 expected_entry_path,
-//                 "Unexpected project panel selected entry path"
-//             );
-//         }
-
-//         // Open a file within an existing worktree.
-//         workspace
-//             .update(cx, |view, cx| {
-//                 view.open_paths(vec!["/dir1/a.txt".into()], true, cx)
-//             })
-//             .await;
-//         cx.read(|cx| {
-//             let workspace = workspace.read(cx);
-//             assert_project_panel_selection(workspace, Path::new("/dir1"), Path::new("a.txt"), cx);
-//             assert_eq!(
-//                 workspace
-//                     .active_pane()
-//                     .read(cx)
-//                     .active_item()
-//                     .unwrap()
-//                     .as_any()
-//                     .downcast_ref::<Editor>()
-//                     .unwrap()
-//                     .read(cx)
-//                     .title(cx),
-//                 "a.txt"
-//             );
-//         });
-
-//         // Open a file outside of any existing worktree.
-//         workspace
-//             .update(cx, |view, cx| {
-//                 view.open_paths(vec!["/dir2/b.txt".into()], true, cx)
-//             })
-//             .await;
-//         cx.read(|cx| {
-//             let workspace = workspace.read(cx);
-//             assert_project_panel_selection(workspace, Path::new("/dir2/b.txt"), Path::new(""), cx);
-//             let worktree_roots = workspace
-//                 .worktrees(cx)
-//                 .map(|w| w.read(cx).as_local().unwrap().abs_path().as_ref())
-//                 .collect::<HashSet<_>>();
-//             assert_eq!(
-//                 worktree_roots,
-//                 vec!["/dir1", "/dir2/b.txt"]
-//                     .into_iter()
-//                     .map(Path::new)
-//                     .collect(),
-//             );
-//             assert_eq!(
-//                 workspace
-//                     .active_pane()
-//                     .read(cx)
-//                     .active_item()
-//                     .unwrap()
-//                     .as_any()
-//                     .downcast_ref::<Editor>()
-//                     .unwrap()
-//                     .read(cx)
-//                     .title(cx),
-//                 "b.txt"
-//             );
-//         });
-
-//         // Ensure opening a directory and one of its children only adds one worktree.
-//         workspace
-//             .update(cx, |view, cx| {
-//                 view.open_paths(vec!["/dir3".into(), "/dir3/c.txt".into()], true, cx)
-//             })
-//             .await;
-//         cx.read(|cx| {
-//             let workspace = workspace.read(cx);
-//             assert_project_panel_selection(workspace, Path::new("/dir3"), Path::new("c.txt"), cx);
-//             let worktree_roots = workspace
-//                 .worktrees(cx)
-//                 .map(|w| w.read(cx).as_local().unwrap().abs_path().as_ref())
-//                 .collect::<HashSet<_>>();
-//             assert_eq!(
-//                 worktree_roots,
-//                 vec!["/dir1", "/dir2/b.txt", "/dir3"]
-//                     .into_iter()
-//                     .map(Path::new)
-//                     .collect(),
-//             );
-//             assert_eq!(
-//                 workspace
-//                     .active_pane()
-//                     .read(cx)
-//                     .active_item()
-//                     .unwrap()
-//                     .as_any()
-//                     .downcast_ref::<Editor>()
-//                     .unwrap()
-//                     .read(cx)
-//                     .title(cx),
-//                 "c.txt"
-//             );
-//         });
-
-//         // Ensure opening invisibly a file outside an existing worktree adds a new, invisible worktree.
-//         workspace
-//             .update(cx, |view, cx| {
-//                 view.open_paths(vec!["/d.txt".into()], false, cx)
-//             })
-//             .await;
-//         cx.read(|cx| {
-//             let workspace = workspace.read(cx);
-//             assert_project_panel_selection(workspace, Path::new("/d.txt"), Path::new(""), cx);
-//             let worktree_roots = workspace
-//                 .worktrees(cx)
-//                 .map(|w| w.read(cx).as_local().unwrap().abs_path().as_ref())
-//                 .collect::<HashSet<_>>();
-//             assert_eq!(
-//                 worktree_roots,
-//                 vec!["/dir1", "/dir2/b.txt", "/dir3", "/d.txt"]
-//                     .into_iter()
-//                     .map(Path::new)
-//                     .collect(),
-//             );
-
-//             let visible_worktree_roots = workspace
-//                 .visible_worktrees(cx)
-//                 .map(|w| w.read(cx).as_local().unwrap().abs_path().as_ref())
-//                 .collect::<HashSet<_>>();
-//             assert_eq!(
-//                 visible_worktree_roots,
-//                 vec!["/dir1", "/dir2/b.txt", "/dir3"]
-//                     .into_iter()
-//                     .map(Path::new)
-//                     .collect(),
-//             );
-
-//             assert_eq!(
-//                 workspace
-//                     .active_pane()
-//                     .read(cx)
-//                     .active_item()
-//                     .unwrap()
-//                     .as_any()
-//                     .downcast_ref::<Editor>()
-//                     .unwrap()
-//                     .read(cx)
-//                     .title(cx),
-//                 "d.txt"
-//             );
-//         });
-//     }
-
-//     #[gpui::test]
-//     async fn test_opening_excluded_paths(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         cx.update(|cx| {
-//             cx.update_global::<SettingsStore, _, _>(|store, cx| {
-//                 store.update_user_settings::<ProjectSettings>(cx, |project_settings| {
-//                     project_settings.file_scan_exclusions =
-//                         Some(vec!["excluded_dir".to_string(), "**/.git".to_string()]);
-//                 });
-//             });
-//         });
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree(
-//                 "/root",
-//                 json!({
-//                     ".gitignore": "ignored_dir\n",
-//                     ".git": {
-//                         "HEAD": "ref: refs/heads/main",
-//                     },
-//                     "regular_dir": {
-//                         "file": "regular file contents",
-//                     },
-//                     "ignored_dir": {
-//                         "ignored_subdir": {
-//                             "file": "ignored subfile contents",
-//                         },
-//                         "file": "ignored file contents",
-//                     },
-//                     "excluded_dir": {
-//                         "file": "excluded file contents",
-//                     },
-//                 }),
-//             )
-//             .await;
-
-//         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
-//         let window = cx.add_window(|cx| Workspace::test_new(project, cx));
-//         let workspace = window.root(cx);
-
-//         let initial_entries = cx.read(|cx| workspace.file_project_paths(cx));
-//         let paths_to_open = [
-//             Path::new("/root/excluded_dir/file").to_path_buf(),
-//             Path::new("/root/.git/HEAD").to_path_buf(),
-//             Path::new("/root/excluded_dir/ignored_subdir").to_path_buf(),
-//         ];
-//         let (opened_workspace, new_items) = cx
-//             .update(|cx| workspace::open_paths(&paths_to_open, &app_state, None, cx))
-//             .await
-//             .unwrap();
-
-//         assert_eq!(
-//             opened_workspace.id(),
-//             workspace.id(),
-//             "Excluded files in subfolders of a workspace root should be opened in the workspace"
-//         );
-//         let mut opened_paths = cx.read(|cx| {
-//             assert_eq!(
-//                 new_items.len(),
-//                 paths_to_open.len(),
-//                 "Expect to get the same number of opened items as submitted paths to open"
-//             );
-//             new_items
-//                 .iter()
-//                 .zip(paths_to_open.iter())
-//                 .map(|(i, path)| {
-//                     match i {
-//                         Some(Ok(i)) => {
-//                             Some(i.project_path(cx).map(|p| p.path.display().to_string()))
-//                         }
-//                         Some(Err(e)) => panic!("Excluded file {path:?} failed to open: {e:?}"),
-//                         None => None,
-//                     }
-//                     .flatten()
-//                 })
-//                 .collect::<Vec<_>>()
-//         });
-//         opened_paths.sort();
-//         assert_eq!(
-//             opened_paths,
-//             vec![
-//                 None,
-//                 Some(".git/HEAD".to_string()),
-//                 Some("excluded_dir/file".to_string()),
-//             ],
-//             "Excluded files should get opened, excluded dir should not get opened"
-//         );
-
-//         let entries = cx.read(|cx| workspace.file_project_paths(cx));
-//         assert_eq!(
-//             initial_entries, entries,
-//             "Workspace entries should not change after opening excluded files and directories paths"
-//         );
-
-//         cx.read(|cx| {
-//             let pane = workspace.read(cx).active_pane().read(cx);
-//             let mut opened_buffer_paths = pane
-//                 .items()
-//                 .map(|i| {
-//                     i.project_path(cx)
-//                         .expect("all excluded files that got open should have a path")
-//                         .path
-//                         .display()
-//                         .to_string()
-//                 })
-//                 .collect::<Vec<_>>();
-//             opened_buffer_paths.sort();
-//             assert_eq!(
-//                 opened_buffer_paths,
-//                 vec![".git/HEAD".to_string(), "excluded_dir/file".to_string()],
-//                 "Despite not being present in the worktrees, buffers for excluded files are opened and added to the pane"
-//             );
-//         });
-//     }
-
-//     #[gpui::test]
-//     async fn test_save_conflicting_item(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree("/root", json!({ "a.txt": "" }))
-//             .await;
-
-//         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
-//         let window = cx.add_window(|cx| Workspace::test_new(project, cx));
-//         let workspace = window.root(cx);
-
-//         // Open a file within an existing worktree.
-//         workspace
-//             .update(cx, |view, cx| {
-//                 view.open_paths(vec![PathBuf::from("/root/a.txt")], true, cx)
-//             })
-//             .await;
-//         let editor = cx.read(|cx| {
-//             let pane = workspace.read(cx).active_pane().read(cx);
-//             let item = pane.active_item().unwrap();
-//             item.downcast::<Editor>().unwrap()
-//         });
-
-//         editor.update(cx, |editor, cx| editor.handle_input("x", cx));
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_file("/root/a.txt", "changed".to_string())
-//             .await;
-//         editor
-//             .condition(cx, |editor, cx| editor.has_conflict(cx))
-//             .await;
-//         cx.read(|cx| assert!(editor.is_dirty(cx)));
-
-//         let save_task = workspace.update(cx, |workspace, cx| {
-//             workspace.save_active_item(SaveIntent::Save, cx)
-//         });
-//         cx.foreground().run_until_parked();
-//         window.simulate_prompt_answer(0, cx);
-//         save_task.await.unwrap();
-//         editor.read_with(cx, |editor, cx| {
-//             assert!(!editor.is_dirty(cx));
-//             assert!(!editor.has_conflict(cx));
-//         });
-//     }
-
-//     #[gpui::test]
-//     async fn test_open_and_save_new_file(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state.fs.create_dir(Path::new("/root")).await.unwrap();
-
-//         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
-//         project.update(cx, |project, _| project.languages().add(rust_lang()));
-//         let window = cx.add_window(|cx| Workspace::test_new(project, cx));
-//         let workspace = window.root(cx);
-//         let worktree = cx.read(|cx| workspace.read(cx).worktrees(cx).next().unwrap());
-
-//         // Create a new untitled buffer
-//         cx.dispatch_action(window.into(), NewFile);
-//         let editor = workspace.read_with(cx, |workspace, cx| {
-//             workspace
-//                 .active_item(cx)
-//                 .unwrap()
-//                 .downcast::<Editor>()
-//                 .unwrap()
-//         });
-
-//         editor.update(cx, |editor, cx| {
-//             assert!(!editor.is_dirty(cx));
-//             assert_eq!(editor.title(cx), "untitled");
-//             assert!(Arc::ptr_eq(
-//                 &editor.language_at(0, cx).unwrap(),
-//                 &languages::PLAIN_TEXT
-//             ));
-//             editor.handle_input("hi", cx);
-//             assert!(editor.is_dirty(cx));
-//         });
-
-//         // Save the buffer. This prompts for a filename.
-//         let save_task = workspace.update(cx, |workspace, cx| {
-//             workspace.save_active_item(SaveIntent::Save, cx)
-//         });
-//         cx.foreground().run_until_parked();
-//         cx.simulate_new_path_selection(|parent_dir| {
-//             assert_eq!(parent_dir, Path::new("/root"));
-//             Some(parent_dir.join("the-new-name.rs"))
-//         });
-//         cx.read(|cx| {
-//             assert!(editor.is_dirty(cx));
-//             assert_eq!(editor.read(cx).title(cx), "untitled");
-//         });
-
-//         // When the save completes, the buffer's title is updated and the language is assigned based
-//         // on the path.
-//         save_task.await.unwrap();
-//         editor.read_with(cx, |editor, cx| {
-//             assert!(!editor.is_dirty(cx));
-//             assert_eq!(editor.title(cx), "the-new-name.rs");
-//             assert_eq!(editor.language_at(0, cx).unwrap().name().as_ref(), "Rust");
-//         });
-
-//         // Edit the file and save it again. This time, there is no filename prompt.
-//         editor.update(cx, |editor, cx| {
-//             editor.handle_input(" there", cx);
-//             assert!(editor.is_dirty(cx));
-//         });
-//         let save_task = workspace.update(cx, |workspace, cx| {
-//             workspace.save_active_item(SaveIntent::Save, cx)
-//         });
-//         save_task.await.unwrap();
-//         assert!(!cx.did_prompt_for_new_path());
-//         editor.read_with(cx, |editor, cx| {
-//             assert!(!editor.is_dirty(cx));
-//             assert_eq!(editor.title(cx), "the-new-name.rs")
-//         });
-
-//         // Open the same newly-created file in another pane item. The new editor should reuse
-//         // the same buffer.
-//         cx.dispatch_action(window.into(), NewFile);
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.split_and_clone(
-//                     workspace.active_pane().clone(),
-//                     SplitDirection::Right,
-//                     cx,
-//                 );
-//                 workspace.open_path((worktree.read(cx).id(), "the-new-name.rs"), None, true, cx)
-//             })
-//             .await
-//             .unwrap();
-//         let editor2 = workspace.update(cx, |workspace, cx| {
-//             workspace
-//                 .active_item(cx)
-//                 .unwrap()
-//                 .downcast::<Editor>()
-//                 .unwrap()
-//         });
-//         cx.read(|cx| {
-//             assert_eq!(
-//                 editor2.read(cx).buffer().read(cx).as_singleton().unwrap(),
-//                 editor.read(cx).buffer().read(cx).as_singleton().unwrap()
-//             );
-//         })
-//     }
-
-//     #[gpui::test]
-//     async fn test_setting_language_when_saving_as_single_file_worktree(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state.fs.create_dir(Path::new("/root")).await.unwrap();
-
-//         let project = Project::test(app_state.fs.clone(), [], cx).await;
-//         project.update(cx, |project, _| project.languages().add(rust_lang()));
-//         let window = cx.add_window(|cx| Workspace::test_new(project, cx));
-//         let workspace = window.root(cx);
-
-//         // Create a new untitled buffer
-//         cx.dispatch_action(window.into(), NewFile);
-//         let editor = workspace.read_with(cx, |workspace, cx| {
-//             workspace
-//                 .active_item(cx)
-//                 .unwrap()
-//                 .downcast::<Editor>()
-//                 .unwrap()
-//         });
-
-//         editor.update(cx, |editor, cx| {
-//             assert!(Arc::ptr_eq(
-//                 &editor.language_at(0, cx).unwrap(),
-//                 &languages::PLAIN_TEXT
-//             ));
-//             editor.handle_input("hi", cx);
-//             assert!(editor.is_dirty(cx));
-//         });
-
-//         // Save the buffer. This prompts for a filename.
-//         let save_task = workspace.update(cx, |workspace, cx| {
-//             workspace.save_active_item(SaveIntent::Save, cx)
-//         });
-//         cx.foreground().run_until_parked();
-//         cx.simulate_new_path_selection(|_| Some(PathBuf::from("/root/the-new-name.rs")));
-//         save_task.await.unwrap();
-//         // The buffer is not dirty anymore and the language is assigned based on the path.
-//         editor.read_with(cx, |editor, cx| {
-//             assert!(!editor.is_dirty(cx));
-//             assert_eq!(editor.language_at(0, cx).unwrap().name().as_ref(), "Rust")
-//         });
-//     }
-
-//     #[gpui::test]
-//     async fn test_pane_actions(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree(
-//                 "/root",
-//                 json!({
-//                     "a": {
-//                         "file1": "contents 1",
-//                         "file2": "contents 2",
-//                         "file3": "contents 3",
-//                     },
-//                 }),
-//             )
-//             .await;
-
-//         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
-//         let window = cx.add_window(|cx| Workspace::test_new(project, cx));
-//         let workspace = window.root(cx);
-
-//         let entries = cx.read(|cx| workspace.file_project_paths(cx));
-//         let file1 = entries[0].clone();
-
-//         let pane_1 = cx.read(|cx| workspace.read(cx).active_pane().clone());
-
-//         workspace
-//             .update(cx, |w, cx| w.open_path(file1.clone(), None, true, cx))
-//             .await
-//             .unwrap();
-
-//         let (editor_1, buffer) = pane_1.update(cx, |pane_1, cx| {
-//             let editor = pane_1.active_item().unwrap().downcast::<Editor>().unwrap();
-//             assert_eq!(editor.project_path(cx), Some(file1.clone()));
-//             let buffer = editor.update(cx, |editor, cx| {
-//                 editor.insert("dirt", cx);
-//                 editor.buffer().downgrade()
-//             });
-//             (editor.downgrade(), buffer)
-//         });
-
-//         cx.dispatch_action(window.into(), pane::SplitRight);
-//         let editor_2 = cx.update(|cx| {
-//             let pane_2 = workspace.read(cx).active_pane().clone();
-//             assert_ne!(pane_1, pane_2);
-
-//             let pane2_item = pane_2.read(cx).active_item().unwrap();
-//             assert_eq!(pane2_item.project_path(cx), Some(file1.clone()));
-
-//             pane2_item.downcast::<Editor>().unwrap().downgrade()
-//         });
-//         cx.dispatch_action(
-//             window.into(),
-//             workspace::CloseActiveItem { save_intent: None },
-//         );
-
-//         cx.foreground().run_until_parked();
-//         workspace.read_with(cx, |workspace, _| {
-//             assert_eq!(workspace.panes().len(), 1);
-//             assert_eq!(workspace.active_pane(), &pane_1);
-//         });
-
-//         cx.dispatch_action(
-//             window.into(),
-//             workspace::CloseActiveItem { save_intent: None },
-//         );
-//         cx.foreground().run_until_parked();
-//         window.simulate_prompt_answer(1, cx);
-//         cx.foreground().run_until_parked();
-
-//         workspace.read_with(cx, |workspace, cx| {
-//             assert_eq!(workspace.panes().len(), 1);
-//             assert!(workspace.active_item(cx).is_none());
-//         });
-
-//         cx.assert_dropped(editor_1);
-//         cx.assert_dropped(editor_2);
-//         cx.assert_dropped(buffer);
-//     }
-
-//     #[gpui::test]
-//     async fn test_navigation(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree(
-//                 "/root",
-//                 json!({
-//                     "a": {
-//                         "file1": "contents 1\n".repeat(20),
-//                         "file2": "contents 2\n".repeat(20),
-//                         "file3": "contents 3\n".repeat(20),
-//                     },
-//                 }),
-//             )
-//             .await;
-
-//         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
-//         let workspace = cx
-//             .add_window(|cx| Workspace::test_new(project.clone(), cx))
-//             .root(cx);
-//         let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
-
-//         let entries = cx.read(|cx| workspace.file_project_paths(cx));
-//         let file1 = entries[0].clone();
-//         let file2 = entries[1].clone();
-//         let file3 = entries[2].clone();
-
-//         let editor1 = workspace
-//             .update(cx, |w, cx| w.open_path(file1.clone(), None, true, cx))
-//             .await
-//             .unwrap()
-//             .downcast::<Editor>()
-//             .unwrap();
-//         editor1.update(cx, |editor, cx| {
-//             editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
-//                 s.select_display_ranges([DisplayPoint::new(10, 0)..DisplayPoint::new(10, 0)])
-//             });
-//         });
-//         let editor2 = workspace
-//             .update(cx, |w, cx| w.open_path(file2.clone(), None, true, cx))
-//             .await
-//             .unwrap()
-//             .downcast::<Editor>()
-//             .unwrap();
-//         let editor3 = workspace
-//             .update(cx, |w, cx| w.open_path(file3.clone(), None, true, cx))
-//             .await
-//             .unwrap()
-//             .downcast::<Editor>()
-//             .unwrap();
-
-//         editor3
-//             .update(cx, |editor, cx| {
-//                 editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
-//                     s.select_display_ranges([DisplayPoint::new(12, 0)..DisplayPoint::new(12, 0)])
-//                 });
-//                 editor.newline(&Default::default(), cx);
-//                 editor.newline(&Default::default(), cx);
-//                 editor.move_down(&Default::default(), cx);
-//                 editor.move_down(&Default::default(), cx);
-//                 editor.save(project.clone(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         editor3.update(cx, |editor, cx| {
-//             editor.set_scroll_position(vec2f(0., 12.5), cx)
-//         });
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file3.clone(), DisplayPoint::new(16, 0), 12.5)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file3.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file2.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file1.clone(), DisplayPoint::new(10, 0), 0.)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file1.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         // Go back one more time and ensure we don't navigate past the first item in the history.
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file1.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file1.clone(), DisplayPoint::new(10, 0), 0.)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file2.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         // Go forward to an item that has been closed, ensuring it gets re-opened at the same
-//         // location.
-//         pane.update(cx, |pane, cx| {
-//             let editor3_id = editor3.id();
-//             drop(editor3);
-//             pane.close_item_by_id(editor3_id, SaveIntent::Close, cx)
-//         })
-//         .await
-//         .unwrap();
-//         workspace
-//             .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file3.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file3.clone(), DisplayPoint::new(16, 0), 12.5)
-//         );
-
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file3.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         // Go back to an item that has been closed and removed from disk, ensuring it gets skipped.
-//         pane.update(cx, |pane, cx| {
-//             let editor2_id = editor2.id();
-//             drop(editor2);
-//             pane.close_item_by_id(editor2_id, SaveIntent::Close, cx)
-//         })
-//         .await
-//         .unwrap();
-//         app_state
-//             .fs
-//             .remove_file(Path::new("/root/a/file2"), Default::default())
-//             .await
-//             .unwrap();
-//         cx.foreground().run_until_parked();
-
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file1.clone(), DisplayPoint::new(10, 0), 0.)
-//         );
-//         workspace
-//             .update(cx, |w, cx| w.go_forward(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file3.clone(), DisplayPoint::new(0, 0), 0.)
-//         );
-
-//         // Modify file to collapse multiple nav history entries into the same location.
-//         // Ensure we don't visit the same location twice when navigating.
-//         editor1.update(cx, |editor, cx| {
-//             editor.change_selections(None, cx, |s| {
-//                 s.select_display_ranges([DisplayPoint::new(15, 0)..DisplayPoint::new(15, 0)])
-//             })
-//         });
-
-//         for _ in 0..5 {
-//             editor1.update(cx, |editor, cx| {
-//                 editor.change_selections(None, cx, |s| {
-//                     s.select_display_ranges([DisplayPoint::new(3, 0)..DisplayPoint::new(3, 0)])
-//                 });
-//             });
-//             editor1.update(cx, |editor, cx| {
-//                 editor.change_selections(None, cx, |s| {
-//                     s.select_display_ranges([DisplayPoint::new(13, 0)..DisplayPoint::new(13, 0)])
-//                 })
-//             });
-//         }
-
-//         editor1.update(cx, |editor, cx| {
-//             editor.transact(cx, |editor, cx| {
-//                 editor.change_selections(None, cx, |s| {
-//                     s.select_display_ranges([DisplayPoint::new(2, 0)..DisplayPoint::new(14, 0)])
-//                 });
-//                 editor.insert("", cx);
-//             })
-//         });
-
-//         editor1.update(cx, |editor, cx| {
-//             editor.change_selections(None, cx, |s| {
-//                 s.select_display_ranges([DisplayPoint::new(1, 0)..DisplayPoint::new(1, 0)])
-//             })
-//         });
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file1.clone(), DisplayPoint::new(2, 0), 0.)
-//         );
-//         workspace
-//             .update(cx, |w, cx| w.go_back(w.active_pane().downgrade(), cx))
-//             .await
-//             .unwrap();
-//         assert_eq!(
-//             active_location(&workspace, cx),
-//             (file1.clone(), DisplayPoint::new(3, 0), 0.)
-//         );
-
-//         fn active_location(
-//             workspace: &ViewHandle<Workspace>,
-//             cx: &mut TestAppContext,
-//         ) -> (ProjectPath, DisplayPoint, f32) {
-//             workspace.update(cx, |workspace, cx| {
-//                 let item = workspace.active_item(cx).unwrap();
-//                 let editor = item.downcast::<Editor>().unwrap();
-//                 let (selections, scroll_position) = editor.update(cx, |editor, cx| {
-//                     (
-//                         editor.selections.display_ranges(cx),
-//                         editor.scroll_position(cx),
-//                     )
-//                 });
-//                 (
-//                     item.project_path(cx).unwrap(),
-//                     selections[0].start,
-//                     scroll_position.y(),
-//                 )
-//             })
-//         }
-//     }
-
-//     #[gpui::test]
-//     async fn test_reopening_closed_items(cx: &mut TestAppContext) {
-//         let app_state = init_test(cx);
-//         app_state
-//             .fs
-//             .as_fake()
-//             .insert_tree(
-//                 "/root",
-//                 json!({
-//                     "a": {
-//                         "file1": "",
-//                         "file2": "",
-//                         "file3": "",
-//                         "file4": "",
-//                     },
-//                 }),
-//             )
-//             .await;
-
-//         let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
-//         let workspace = cx
-//             .add_window(|cx| Workspace::test_new(project, cx))
-//             .root(cx);
-//         let pane = workspace.read_with(cx, |workspace, _| workspace.active_pane().clone());
-
-//         let entries = cx.read(|cx| workspace.file_project_paths(cx));
-//         let file1 = entries[0].clone();
-//         let file2 = entries[1].clone();
-//         let file3 = entries[2].clone();
-//         let file4 = entries[3].clone();
-
-//         let file1_item_id = workspace
-//             .update(cx, |w, cx| w.open_path(file1.clone(), None, true, cx))
-//             .await
-//             .unwrap()
-//             .id();
-//         let file2_item_id = workspace
-//             .update(cx, |w, cx| w.open_path(file2.clone(), None, true, cx))
-//             .await
-//             .unwrap()
-//             .id();
-//         let file3_item_id = workspace
-//             .update(cx, |w, cx| w.open_path(file3.clone(), None, true, cx))
-//             .await
-//             .unwrap()
-//             .id();
-//         let file4_item_id = workspace
-//             .update(cx, |w, cx| w.open_path(file4.clone(), None, true, cx))
-//             .await
-//             .unwrap()
-//             .id();
-//         assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
-
-//         // Close all the pane items in some arbitrary order.
-//         pane.update(cx, |pane, cx| {
-//             pane.close_item_by_id(file1_item_id, SaveIntent::Close, cx)
-//         })
-//         .await
-//         .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
-
-//         pane.update(cx, |pane, cx| {
-//             pane.close_item_by_id(file4_item_id, SaveIntent::Close, cx)
-//         })
-//         .await
-//         .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
-
-//         pane.update(cx, |pane, cx| {
-//             pane.close_item_by_id(file2_item_id, SaveIntent::Close, cx)
-//         })
-//         .await
-//         .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
-
-//         pane.update(cx, |pane, cx| {
-//             pane.close_item_by_id(file3_item_id, SaveIntent::Close, cx)
-//         })
-//         .await
-//         .unwrap();
-//         assert_eq!(active_path(&workspace, cx), None);
-
-//         // Reopen all the closed items, ensuring they are reopened in the same order
-//         // in which they were closed.
-//         workspace
-//             .update(cx, Workspace::reopen_closed_item)
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
-
-//         workspace
-//             .update(cx, Workspace::reopen_closed_item)
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file2.clone()));
-
-//         workspace
-//             .update(cx, Workspace::reopen_closed_item)
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
-
-//         workspace
-//             .update(cx, Workspace::reopen_closed_item)
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file1.clone()));
-
-//         // Reopening past the last closed item is a no-op.
-//         workspace
-//             .update(cx, Workspace::reopen_closed_item)
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file1.clone()));
-
-//         // Reopening closed items doesn't interfere with navigation history.
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
-
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file2.clone()));
-
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
-
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file4.clone()));
-
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file3.clone()));
-
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file2.clone()));
-
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file1.clone()));
-
-//         workspace
-//             .update(cx, |workspace, cx| {
-//                 workspace.go_back(workspace.active_pane().downgrade(), cx)
-//             })
-//             .await
-//             .unwrap();
-//         assert_eq!(active_path(&workspace, cx), Some(file1.clone()));
-
-//         fn active_path(
-//             workspace: &ViewHandle<Workspace>,
-//             cx: &TestAppContext,
-//         ) -> Option<ProjectPath> {
-//             workspace.read_with(cx, |workspace, cx| {
-//                 let item = workspace.active_item(cx)?;
-//                 item.project_path(cx)
-//             })
-//         }
-//     }
-
-//     #[gpui::test]
-//     async fn test_base_keymap(cx: &mut gpui::TestAppContext) {
-//         struct TestView;
-
-//         impl Entity for TestView {
-//             type Event = ();
-//         }
-
-//         impl View for TestView {
-//             fn ui_name() -> &'static str {
-//                 "TestView"
-//             }
-
-//             fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
-//                 Empty::new().into_any()
-//             }
-//         }
-
-//         let executor = cx.background();
-//         let fs = FakeFs::new(executor.clone());
-
-//         actions!(test, [A, B]);
-//         // From the Atom keymap
-//         actions!(workspace, [ActivatePreviousPane]);
-//         // From the JetBrains keymap
-//         actions!(pane, [ActivatePrevItem]);
-
-//         fs.save(
-//             "/settings.json".as_ref(),
-//             &r#"
-//             {
-//                 "base_keymap": "Atom"
-//             }
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         fs.save(
-//             "/keymap.json".as_ref(),
-//             &r#"
-//             [
-//                 {
-//                     "bindings": {
-//                         "backspace": "test::A"
-//                     }
-//                 }
-//             ]
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         cx.update(|cx| {
-//             cx.set_global(SettingsStore::test(cx));
-//             theme::init(Assets, cx);
-//             welcome::init(cx);
-
-//             cx.add_global_action(|_: &A, _cx| {});
-//             cx.add_global_action(|_: &B, _cx| {});
-//             cx.add_global_action(|_: &ActivatePreviousPane, _cx| {});
-//             cx.add_global_action(|_: &ActivatePrevItem, _cx| {});
-
-//             let settings_rx = watch_config_file(
-//                 executor.clone(),
-//                 fs.clone(),
-//                 PathBuf::from("/settings.json"),
-//             );
-//             let keymap_rx =
-//                 watch_config_file(executor.clone(), fs.clone(), PathBuf::from("/keymap.json"));
-
-//             handle_keymap_file_changes(keymap_rx, cx);
-//             handle_settings_file_changes(settings_rx, cx);
-//         });
-
-//         cx.foreground().run_until_parked();
-
-//         let window = cx.add_window(|_| TestView);
-
-//         // Test loading the keymap base at all
-//         assert_key_bindings_for(
-//             window.into(),
-//             cx,
-//             vec![("backspace", &A), ("k", &ActivatePreviousPane)],
-//             line!(),
-//         );
-
-//         // Test modifying the users keymap, while retaining the base keymap
-//         fs.save(
-//             "/keymap.json".as_ref(),
-//             &r#"
-//             [
-//                 {
-//                     "bindings": {
-//                         "backspace": "test::B"
-//                     }
-//                 }
-//             ]
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         cx.foreground().run_until_parked();
-
-//         assert_key_bindings_for(
-//             window.into(),
-//             cx,
-//             vec![("backspace", &B), ("k", &ActivatePreviousPane)],
-//             line!(),
-//         );
-
-//         // Test modifying the base, while retaining the users keymap
-//         fs.save(
-//             "/settings.json".as_ref(),
-//             &r#"
-//             {
-//                 "base_keymap": "JetBrains"
-//             }
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         cx.foreground().run_until_parked();
-
-//         assert_key_bindings_for(
-//             window.into(),
-//             cx,
-//             vec![("backspace", &B), ("[", &ActivatePrevItem)],
-//             line!(),
-//         );
-
-//         #[track_caller]
-//         fn assert_key_bindings_for<'a>(
-//             window: AnyWindowHandle,
-//             cx: &TestAppContext,
-//             actions: Vec<(&'static str, &'a dyn Action)>,
-//             line: u32,
-//         ) {
-//             for (key, action) in actions {
-//                 // assert that...
-//                 assert!(
-//                     cx.available_actions(window, 0)
-//                         .into_iter()
-//                         .any(|(_, bound_action, b)| {
-//                             // action names match...
-//                             bound_action.name() == action.name()
-//                         && bound_action.namespace() == action.namespace()
-//                         // and key strokes contain the given key
-//                         && b.iter()
-//                             .any(|binding| binding.keystrokes().iter().any(|k| k.key == key))
-//                         }),
-//                     "On {} Failed to find {} with key binding {}",
-//                     line,
-//                     action.name(),
-//                     key
-//                 );
-//             }
-//         }
-//     }
-
-//     #[gpui::test]
-//     async fn test_disabled_keymap_binding(cx: &mut gpui::TestAppContext) {
-//         struct TestView;
-
-//         impl Entity for TestView {
-//             type Event = ();
-//         }
-
-//         impl View for TestView {
-//             fn ui_name() -> &'static str {
-//                 "TestView"
-//             }
-
-//             fn render(&mut self, _: &mut ViewContext<Self>) -> AnyElement<Self> {
-//                 Empty::new().into_any()
-//             }
-//         }
-
-//         let executor = cx.background();
-//         let fs = FakeFs::new(executor.clone());
-
-//         actions!(test, [A, B]);
-//         // From the Atom keymap
-//         actions!(workspace, [ActivatePreviousPane]);
-//         // From the JetBrains keymap
-//         actions!(pane, [ActivatePrevItem]);
-
-//         fs.save(
-//             "/settings.json".as_ref(),
-//             &r#"
-//             {
-//                 "base_keymap": "Atom"
-//             }
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         fs.save(
-//             "/keymap.json".as_ref(),
-//             &r#"
-//             [
-//                 {
-//                     "bindings": {
-//                         "backspace": "test::A"
-//                     }
-//                 }
-//             ]
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         cx.update(|cx| {
-//             cx.set_global(SettingsStore::test(cx));
-//             theme::init(Assets, cx);
-//             welcome::init(cx);
-
-//             cx.add_global_action(|_: &A, _cx| {});
-//             cx.add_global_action(|_: &B, _cx| {});
-//             cx.add_global_action(|_: &ActivatePreviousPane, _cx| {});
-//             cx.add_global_action(|_: &ActivatePrevItem, _cx| {});
-
-//             let settings_rx = watch_config_file(
-//                 executor.clone(),
-//                 fs.clone(),
-//                 PathBuf::from("/settings.json"),
-//             );
-//             let keymap_rx =
-//                 watch_config_file(executor.clone(), fs.clone(), PathBuf::from("/keymap.json"));
-
-//             handle_keymap_file_changes(keymap_rx, cx);
-//             handle_settings_file_changes(settings_rx, cx);
-//         });
-
-//         cx.foreground().run_until_parked();
-
-//         let window = cx.add_window(|_| TestView);
-
-//         // Test loading the keymap base at all
-//         assert_key_bindings_for(
-//             window.into(),
-//             cx,
-//             vec![("backspace", &A), ("k", &ActivatePreviousPane)],
-//             line!(),
-//         );
-
-//         // Test disabling the key binding for the base keymap
-//         fs.save(
-//             "/keymap.json".as_ref(),
-//             &r#"
-//             [
-//                 {
-//                     "bindings": {
-//                         "backspace": null
-//                     }
-//                 }
-//             ]
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         cx.foreground().run_until_parked();
-
-//         assert_key_bindings_for(
-//             window.into(),
-//             cx,
-//             vec![("k", &ActivatePreviousPane)],
-//             line!(),
-//         );
-
-//         // Test modifying the base, while retaining the users keymap
-//         fs.save(
-//             "/settings.json".as_ref(),
-//             &r#"
-//             {
-//                 "base_keymap": "JetBrains"
-//             }
-//             "#
-//             .into(),
-//             Default::default(),
-//         )
-//         .await
-//         .unwrap();
-
-//         cx.foreground().run_until_parked();
-
-//         assert_key_bindings_for(window.into(), cx, vec![("[", &ActivatePrevItem)], line!());
-
-//         #[track_caller]
-//         fn assert_key_bindings_for<'a>(
-//             window: AnyWindowHandle,
-//             cx: &TestAppContext,
-//             actions: Vec<(&'static str, &'a dyn Action)>,
-//             line: u32,
-//         ) {
-//             for (key, action) in actions {
-//                 // assert that...
-//                 assert!(
-//                     cx.available_actions(window, 0)
-//                         .into_iter()
-//                         .any(|(_, bound_action, b)| {
-//                             // action names match...
-//                             bound_action.name() == action.name()
-//                         && bound_action.namespace() == action.namespace()
-//                         // and key strokes contain the given key
-//                         && b.iter()
-//                             .any(|binding| binding.keystrokes().iter().any(|k| k.key == key))
-//                         }),
-//                     "On {} Failed to find {} with key binding {}",
-//                     line,
-//                     action.name(),
-//                     key
-//                 );
-//             }
-//         }
-//     }
-
-//     #[gpui::test]
-//     fn test_bundled_settings_and_themes(cx: &mut AppContext) {
-//         cx.platform()
-//             .fonts()
-//             .add_fonts(&[
-//                 Assets
-//                     .load("fonts/zed-sans/zed-sans-extended.ttf")
-//                     .unwrap()
-//                     .to_vec()
-//                     .into(),
-//                 Assets
-//                     .load("fonts/zed-mono/zed-mono-extended.ttf")
-//                     .unwrap()
-//                     .to_vec()
-//                     .into(),
-//                 Assets
-//                     .load("fonts/plex/IBMPlexSans-Regular.ttf")
-//                     .unwrap()
-//                     .to_vec()
-//                     .into(),
-//             ])
-//             .unwrap();
-//         let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
-//         let mut settings = SettingsStore::default();
-//         settings
-//             .set_default_settings(&settings::default_settings(), cx)
-//             .unwrap();
-//         cx.set_global(settings);
-//         theme::init(Assets, cx);
-
-//         let mut has_default_theme = false;
-//         for theme_name in themes.list(false).map(|meta| meta.name) {
-//             let theme = themes.get(&theme_name).unwrap();
-//             assert_eq!(theme.meta.name, theme_name);
-//             if theme.meta.name == settings::get::<ThemeSettings>(cx).theme.meta.name {
-//                 has_default_theme = true;
-//             }
-//         }
-//         assert!(has_default_theme);
-//     }
-
-//     #[gpui::test]
-//     fn test_bundled_languages(cx: &mut AppContext) {
-//         cx.set_global(SettingsStore::test(cx));
-//         let mut languages = LanguageRegistry::test();
-//         languages.set_executor(cx.background().clone());
-//         let languages = Arc::new(languages);
-//         let node_runtime = node_runtime::FakeNodeRuntime::new();
-//         languages::init(languages.clone(), node_runtime, cx);
-//         for name in languages.language_names() {
-//             languages.language_for_name(&name);
-//         }
-//         cx.foreground().run_until_parked();
-//     }
-
-//     fn init_test(cx: &mut TestAppContext) -> Arc<AppState> {
-//         cx.foreground().forbid_parking();
-//         cx.update(|cx| {
-//             let mut app_state = AppState::test(cx);
-//             let state = Arc::get_mut(&mut app_state).unwrap();
-//             state.initialize_workspace = initialize_workspace;
-//             state.build_window_options = build_window_options;
-//             theme::init((), cx);
-//             audio::init((), cx);
-//             channel::init(&app_state.client, app_state.user_store.clone(), cx);
-//             call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
-//             notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx);
-//             workspace::init(app_state.clone(), cx);
-//             Project::init_settings(cx);
-//             language::init(cx);
-//             editor::init(cx);
-//             project_panel::init_settings(cx);
-//             collab_ui::init(&app_state, cx);
-//             pane::init(cx);
-//             project_panel::init((), cx);
-//             terminal_view::init(cx);
-//             assistant::init(cx);
-//             app_state
-//         })
-//     }
-
-//     fn rust_lang() -> Arc<language::Language> {
-//         Arc::new(language::Language::new(
-//             language::LanguageConfig {
-//                 name: "Rust".into(),
-//                 path_suffixes: vec!["rs".to_string()],
-//                 ..Default::default()
-//             },
-//             Some(tree_sitter_rust::language()),
-//         ))
-//     }
-// }

docs/old/local-collaboration.md 🔗

@@ -17,6 +17,6 @@
 ## Testing collab locally
 
 1. Run `foreman start` from the root of the repo.
-1. In another terminal run `script/zed-local -2`.
+1. In another terminal run `script/zed-local`.
 1. Two copies of Zed will open. Add yourself as a contact in the one that is not you.
 1. Start a collaboration session as normal with any open project.

docs/src/developing_zed__local_collaboration.md 🔗

@@ -17,6 +17,6 @@
 ## Testing collab locally
 
 1. Run `foreman start` from the root of the repo.
-1. In another terminal run `script/zed-local -2`.
+1. In another terminal run `script/zed-local`.
 1. Two copies of Zed will open. Add yourself as a contact in the one that is not you.
 1. Start a collaboration session as normal with any open project.

script/bundle 🔗

@@ -27,11 +27,10 @@ Options:
   -o    Open the resulting DMG or the app itself in local mode.
   -f    Overwrite the local app bundle if it exists.
   -h    Display this help and exit.
-  -2    Build zed 2 instead of zed 1.
   "
 }
 
-while getopts 'dlfoh2' flag
+while getopts 'dlfoh' flag
 do
     case "${flag}" in
         o) open_result=true;;
@@ -50,10 +49,6 @@ do
             target_dir="debug"
             ;;
         f) overwrite_local_app=true;;
-        2)
-            zed_crate="zed2"
-            binary_name="Zed2"
-            ;;
         h)
            help_info
            exit 0
@@ -152,12 +147,7 @@ if [[ -n $MACOS_CERTIFICATE && -n $MACOS_CERTIFICATE_PASSWORD && -n $APPLE_NOTAR
 
     # sequence of codesign commands modeled after this example: https://developer.apple.com/forums/thread/701514
     /usr/bin/codesign --deep --force --timestamp --sign "Zed Industries, Inc." "${app_path}/Contents/Frameworks/WebRTC.framework" -v
-
-    # todo!(restore cli to zed2)
-    if [[ "$zed_crate" == "zed" ]]; then
-        /usr/bin/codesign --deep --force --timestamp --options runtime --sign "Zed Industries, Inc." "${app_path}/Contents/MacOS/cli" -v
-    fi
-
+    /usr/bin/codesign --deep --force --timestamp --options runtime --sign "Zed Industries, Inc." "${app_path}/Contents/MacOS/cli" -v
     /usr/bin/codesign --deep --force --timestamp --options runtime --entitlements crates/${zed_crate}/resources/zed.entitlements --sign "Zed Industries, Inc." "${app_path}/Contents/MacOS/${zed_crate}" -v
     /usr/bin/codesign --force --timestamp --options runtime --entitlements crates/${zed_crate}/resources/zed.entitlements --sign "Zed Industries, Inc." "${app_path}" -v
 

script/crate-dep-graph 🔗

@@ -11,7 +11,7 @@ graph_file=target/crate-graph.html
 cargo depgraph \
     --workspace-only \
     --offline \
-    --root=zed2,cli,collab2 \
+    --root=zed,cli,collab2 \
     --dedup-transitive-deps \
     | dot -Tsvg > $graph_file
 

script/zed-2-progress-report.py 🔗

@@ -1,27 +0,0 @@
-import os
-from pathlib import Path
-
-THIS_SCRIPT_PATH: Path = Path(__file__)
-CRATES_DIR: Path = THIS_SCRIPT_PATH.parent.parent / "crates"
-
-zed_1_crate_count: int = 0
-zed_2_crate_count: int = 0
-
-for child in os.listdir(CRATES_DIR):
-    child_path: str = os.path.join(CRATES_DIR, child)
-
-    if not os.path.isdir(child_path):
-        continue
-
-    if child.endswith("2"):
-        zed_2_crate_count += 1
-    else:
-        zed_1_crate_count += 1
-
-print(f"crates ported: {zed_2_crate_count}")
-print(f"crates in total: {zed_1_crate_count}")
-
-percent_complete: float = (zed_2_crate_count / zed_1_crate_count) * 100
-percent_complete_rounded: float = round(percent_complete, 2)
-
-print(f"progress: {percent_complete_rounded}%")

script/zed-local 🔗

@@ -4,7 +4,6 @@ const { spawn, execFileSync } = require("child_process");
 
 const RESOLUTION_REGEX = /(\d+) x (\d+)/;
 const DIGIT_FLAG_REGEX = /^--?(\d+)$/;
-const ZED_2_MODE = "--zed2";
 const RELEASE_MODE = "--release";
 
 const args = process.argv.slice(2);
@@ -16,7 +15,6 @@ if (digitMatch) {
   instanceCount = parseInt(digitMatch[1]);
   args.shift();
 }
-const isZed2 = args.some((arg) => arg === ZED_2_MODE);
 const isReleaseMode = args.some((arg) => arg === RELEASE_MODE);
 if (instanceCount > 4) {
   throw new Error("Cannot spawn more than 4 instances");
@@ -71,17 +69,11 @@ const buildArgs = (() => {
     buildArgs.push("--release");
   }
 
-  if (isZed2) {
-    buildArgs.push("-p", "zed2");
-  }
-
   return buildArgs;
 })();
 const zedBinary = (() => {
   const target = isReleaseMode ? "release" : "debug";
-  const binary = isZed2 ? "Zed2" : "Zed";
-
-  return `target/${target}/${binary}`;
+  return `target/${target}/Zed`;
 })();
 
 execFileSync("cargo", buildArgs, { stdio: "inherit" });