Compare commits
1 Commits
simplify-p
...
macos-chec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d3890e595 |
2
.github/workflows/issue_response.yml
vendored
2
.github/workflows/issue_response.yml
vendored
@@ -29,5 +29,5 @@ jobs:
|
||||
- name: Run Issue Response
|
||||
run: pnpm run --dir script/issue_response start
|
||||
env:
|
||||
ISSUE_RESPONSE_GITHUB_TOKEN: ${{ secrets.ISSUE_RESPONSE_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SLACK_ISSUE_RESPONSE_WEBHOOK_URL: ${{ secrets.SLACK_ISSUE_RESPONSE_WEBHOOK_URL }}
|
||||
|
||||
398
Cargo.lock
generated
398
Cargo.lock
generated
@@ -27,7 +27,7 @@ version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
"gimli 0.31.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -83,9 +83,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "alacritty_terminal"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bccc2e60c2112dc8e8a722d6d30f2bb1a6a7b5d0e65fa695e09e57415dca7f7"
|
||||
version = "0.25.0-dev"
|
||||
source = "git+https://github.com/alacritty/alacritty.git?rev=5e78d20c709cb1ab8d44ca7a8702cc26d779227c#5e78d20c709cb1ab8d44ca7a8702cc26d779227c"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bitflags 2.8.0",
|
||||
@@ -1142,6 +1141,7 @@ dependencies = [
|
||||
"gpui",
|
||||
"http_client",
|
||||
"markdown_preview",
|
||||
"menu",
|
||||
"release_channel",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2057,9 +2057,6 @@ name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "by_address"
|
||||
@@ -2424,7 +2421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
"target-lexicon 0.12.16",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3331,18 +3328,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e15d04a0ce86cb36ead88ad68cf693ffd6cda47052b9e0ac114bc47fd9cd23c4"
|
||||
checksum = "69792bd40d21be8059f7c709f44200ded3bbd073df7eb3fa3c282b387c7ffa5b"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bitset"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c6e3969a7ce267259ce244b7867c5d3bc9e65b0a87e81039588dfdeaede9f34"
|
||||
checksum = "38da1eb6f7d8cdfa92f05acfae63c9a1d7a337e49ce7a2d0769c7fa03a2613a5"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@@ -3350,9 +3347,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c22032c4cb42558371cf516bb47f26cdad1819d3475c133e93c49f50ebf304e"
|
||||
checksum = "709f5567a2bff9f06edf911a7cb5ebb091e4c81701714dc6ab574d08b4a69a0d"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"cranelift-bforest",
|
||||
@@ -3362,45 +3359,44 @@ dependencies = [
|
||||
"cranelift-control",
|
||||
"cranelift-entity",
|
||||
"cranelift-isle",
|
||||
"gimli",
|
||||
"gimli 0.29.0",
|
||||
"hashbrown 0.14.5",
|
||||
"log",
|
||||
"regalloc2",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"target-lexicon 0.13.2",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c904bc71c61b27fc57827f4a1379f29de64fe95653b620a3db77d59655eee0b8"
|
||||
checksum = "72d39a6b194c069fd091ca1f17b9d86ff1a4627ccad8806095828f61989a691f"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40180f5497572f644ce88c255480981ae2ec1d7bb4d8e0c0136a13b87a2f2ceb"
|
||||
checksum = "18f81aefad1f80ed4132ae33f40b92779eeb57edeb1e28bb24424a4098c963a2"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-control"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d132c6d0bd8a489563472afc171759da0707804a65ece7ceb15a8c6d7dd5ef"
|
||||
checksum = "6adbaac785ad4683c4f199686f9e15c1471f52ae2f4c013a3be039b4719db754"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b2d0d9618275474fbf679dd018ac6e009acbd6ae6850f6a67be33fb3b00b323"
|
||||
checksum = "70b85ed43567e13782cd1b25baf42a8167ee57169a60dfd3d7307c6ca3839da0"
|
||||
dependencies = [
|
||||
"cranelift-bitset",
|
||||
"serde",
|
||||
@@ -3409,31 +3405,47 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fac41e16729107393174b0c9e3730fb072866100e1e64e80a1a963b2e484d57"
|
||||
checksum = "8349f71373bb69c6f73992c6c1606236a66c8134e7a60e04e03fbd64b1aa7dcf"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
"smallvec",
|
||||
"target-lexicon 0.13.2",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-isle"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ca20d576e5070044d0a72a9effc2deacf4d6aa650403189d8ea50126483944d"
|
||||
checksum = "464a6b958ce05e0c237c8b25508012b6c644e8c37348213a8c786ba29e28cfdb"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.116.1"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8dee82f3f1f2c4cba9177f1cc5e350fe98764379bcd29340caa7b01f85076c7"
|
||||
checksum = "ffc4acaf6894ee323ff4e9ce786bec09f0ebbe49941e8012f1c1052f1d965034"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
"target-lexicon 0.13.2",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-wasm"
|
||||
version = "0.112.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b878860895cca97454ef8d8b12bfda9d0889dd49efee175dba78d54ff8363ec2"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"cranelift-entity",
|
||||
"cranelift-frontend",
|
||||
"itertools 0.12.1",
|
||||
"log",
|
||||
"smallvec",
|
||||
"wasmparser 0.217.1",
|
||||
"wasmtime-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4433,9 +4445,9 @@ dependencies = [
|
||||
"serde_json",
|
||||
"toml 0.8.20",
|
||||
"util",
|
||||
"wasm-encoder 0.221.3",
|
||||
"wasmparser 0.221.3",
|
||||
"wit-component 0.221.3",
|
||||
"wasm-encoder 0.217.1",
|
||||
"wasmparser 0.217.1",
|
||||
"wit-component",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4503,7 +4515,7 @@ dependencies = [
|
||||
"toml 0.8.20",
|
||||
"url",
|
||||
"util",
|
||||
"wasmparser 0.221.3",
|
||||
"wasmparser 0.217.1",
|
||||
"wasmtime",
|
||||
"wasmtime-wasi",
|
||||
]
|
||||
@@ -5251,15 +5263,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
dependencies = [
|
||||
"fallible-iterator",
|
||||
"indexmap",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "git"
|
||||
version = "0.1.0"
|
||||
@@ -5688,6 +5706,7 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash 0.8.11",
|
||||
"allocator-api2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5699,7 +5718,6 @@ dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6951,7 +6969,6 @@ dependencies = [
|
||||
"serde_json",
|
||||
"smol",
|
||||
"strum",
|
||||
"thiserror 1.0.69",
|
||||
"ui",
|
||||
"util",
|
||||
]
|
||||
@@ -6963,7 +6980,6 @@ dependencies = [
|
||||
"feature_flags",
|
||||
"gpui",
|
||||
"language_model",
|
||||
"log",
|
||||
"picker",
|
||||
"proto",
|
||||
"ui",
|
||||
@@ -7652,6 +7668,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"assets",
|
||||
"env_logger 0.11.6",
|
||||
"futures 0.3.31",
|
||||
"gpui",
|
||||
"language",
|
||||
"languages",
|
||||
@@ -9759,7 +9776,6 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"ui",
|
||||
"util",
|
||||
"workspace",
|
||||
]
|
||||
|
||||
@@ -10432,18 +10448,6 @@ version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd348ff538bc9caeda7ee8cad2d1d48236a1f443c1fa3913c6a02fe0043b1dd3"
|
||||
|
||||
[[package]]
|
||||
name = "pulley-interpreter"
|
||||
version = "29.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62d95f8575df49a2708398182f49a888cf9dc30210fb1fd2df87c889edcee75d"
|
||||
dependencies = [
|
||||
"cranelift-bitset",
|
||||
"log",
|
||||
"sptr",
|
||||
"wasmtime-math",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qoi"
|
||||
version = "0.4.1"
|
||||
@@ -10824,15 +10828,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regalloc2"
|
||||
version = "0.11.1"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "145c1c267e14f20fb0f88aa76a1c5ffec42d592c1d28b3cd9148ae35916158d3"
|
||||
checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"bumpalo",
|
||||
"hashbrown 0.15.2",
|
||||
"hashbrown 0.14.5",
|
||||
"log",
|
||||
"rustc-hash 2.1.1",
|
||||
"slice-group-by",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
@@ -11133,7 +11136,6 @@ dependencies = [
|
||||
"gpui",
|
||||
"http_client",
|
||||
"log",
|
||||
"regex",
|
||||
"reqwest 0.12.8",
|
||||
"serde",
|
||||
"smol",
|
||||
@@ -12347,6 +12349,12 @@ dependencies = [
|
||||
"zed_extension_api 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slice-group-by"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
|
||||
|
||||
[[package]]
|
||||
name = "slotmap"
|
||||
version = "1.0.7"
|
||||
@@ -13262,12 +13270,6 @@ version = "0.12.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
|
||||
|
||||
[[package]]
|
||||
name = "task"
|
||||
version = "0.1.0"
|
||||
@@ -13482,7 +13484,6 @@ dependencies = [
|
||||
"serde_repr",
|
||||
"settings",
|
||||
"strum",
|
||||
"thiserror 1.0.69",
|
||||
"util",
|
||||
"uuid",
|
||||
]
|
||||
@@ -14111,27 +14112,15 @@ dependencies = [
|
||||
"tracing-serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trait-variant"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter"
|
||||
version = "0.25.2"
|
||||
version = "0.24.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5168a515fe492af54c5cc8800ff8c840be09fa5168de45838afaecd3e008bce4"
|
||||
checksum = "a5387dffa7ffc7d2dae12b50c6f7aab8ff79d6210147c6613561fc3d474c6f75"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"regex",
|
||||
"regex-syntax 0.8.5",
|
||||
"serde_json",
|
||||
"streaming-iterator",
|
||||
"tree-sitter-language",
|
||||
"wasmtime-c-api-impl",
|
||||
@@ -14255,12 +14244,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-html"
|
||||
version = "0.23.2"
|
||||
version = "0.20.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "261b708e5d92061ede329babaaa427b819329a9d427a1d710abb0f67bbef63ee"
|
||||
checksum = "8766b5ad3721517f8259e6394aefda9c686aebf7a8c74ab8624f2c3b46902fd5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter-language",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -14863,26 +14852,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "vte"
|
||||
version = "0.13.1"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a0b683b20ef64071ff03745b14391751f6beab06a54347885459b77a3f2caa5"
|
||||
checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"cursor-icon",
|
||||
"log",
|
||||
"memchr",
|
||||
"serde",
|
||||
"utf8parse",
|
||||
"vte_generate_state_changes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vte_generate_state_changes"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -15043,12 +15021,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.221.3"
|
||||
version = "0.217.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc8444fe4920de80a4fe5ab564fff2ae58b6b73166b89751f8c6c93509da32e5"
|
||||
checksum = "10961fd76db420582926af70816dd205019d8152d9e51e1b939125dd1639f854"
|
||||
dependencies = [
|
||||
"leb128",
|
||||
"wasmparser 0.221.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -15067,22 +15044,6 @@ dependencies = [
|
||||
"wasmparser 0.201.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.221.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11f4ef50d17e103a88774cd4aa5d06bfb1ae44036a8f3f1325e0e9b3e3417ac4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"spdx",
|
||||
"wasm-encoder 0.221.3",
|
||||
"wasmparser 0.221.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.4.2"
|
||||
@@ -15109,12 +15070,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.221.3"
|
||||
version = "0.217.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d06bfa36ab3ac2be0dee563380147a5b81ba10dd8885d7fbbc9eb574be67d185"
|
||||
checksum = "65a5a0689975b9fd93c02f5400cfd9669858b99607e54e7b892c6080cba598bb"
|
||||
dependencies = [
|
||||
"ahash 0.8.11",
|
||||
"bitflags 2.8.0",
|
||||
"hashbrown 0.15.2",
|
||||
"hashbrown 0.14.5",
|
||||
"indexmap",
|
||||
"semver",
|
||||
"serde",
|
||||
@@ -15122,20 +15084,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmprinter"
|
||||
version = "0.221.3"
|
||||
version = "0.217.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7343c42a97f2926c7819ff81b64012092ae954c5d83ddd30c9fcdefd97d0b283"
|
||||
checksum = "324c6782d7b81c01625335d252653b26ea68e835ddb4aef4cb1ed3ea40ae3a49"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"termcolor",
|
||||
"wasmparser 0.221.3",
|
||||
"wasmparser 0.217.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11976a250672556d1c4c04c6d5d7656ac9192ac9edc42a4587d6c21460010e69"
|
||||
checksum = "f38dbf42dc56a6fe41ccd77211ea8ec90855de05e52cd00df5a0a3bca87d6147"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -15147,6 +15109,7 @@ dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"indexmap",
|
||||
"libc",
|
||||
"libm",
|
||||
"log",
|
||||
"mach2",
|
||||
"memfd",
|
||||
@@ -15155,16 +15118,14 @@ dependencies = [
|
||||
"paste",
|
||||
"postcard",
|
||||
"psm",
|
||||
"pulley-interpreter",
|
||||
"rustix",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"smallvec",
|
||||
"sptr",
|
||||
"target-lexicon 0.13.2",
|
||||
"trait-variant",
|
||||
"wasmparser 0.221.3",
|
||||
"target-lexicon",
|
||||
"wasmparser 0.217.1",
|
||||
"wasmtime-asm-macros",
|
||||
"wasmtime-component-macro",
|
||||
"wasmtime-component-util",
|
||||
@@ -15172,30 +15133,30 @@ dependencies = [
|
||||
"wasmtime-environ",
|
||||
"wasmtime-fiber",
|
||||
"wasmtime-jit-icache-coherence",
|
||||
"wasmtime-math",
|
||||
"wasmtime-slab",
|
||||
"wasmtime-versioned-export-macros",
|
||||
"wasmtime-winch",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-asm-macros"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f178b0d125201fbe9f75beaf849bd3e511891f9e45ba216a5b620802ccf64f2"
|
||||
checksum = "30e0c7f9983c2d60109a939d9ab0e0df301901085c3608e1c22c27c98390a027"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-c-api-impl"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea30cef3608f2de5797c7bbb94c1ba4f3676d9a7f81ae86ced1b512e2766ed0c"
|
||||
checksum = "ebfcdb4aa0f68020934099815cf6ef11dbbedaf070ef800b3f0a7f6ec7b7d005"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"log",
|
||||
"once_cell",
|
||||
"tracing",
|
||||
"wasmtime",
|
||||
"wasmtime-c-api-macros",
|
||||
@@ -15203,9 +15164,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-c-api-macros"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "022a79ebe1124d5d384d82463d7e61c6b4dd857d81f15cb8078974eeb86db65b"
|
||||
checksum = "842c213ad4546fb0178735910b96ee7da303e1d745c3f42f4178b0de1da138b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -15213,9 +15174,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-component-macro"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d74de6592ed945d0a602f71243982a304d5d02f1e501b638addf57f42d57dfaf"
|
||||
checksum = "0929ffffaca32dd8770b56848c94056036963ca05de25fb47cac644e20262168"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"proc-macro2",
|
||||
@@ -15223,20 +15184,20 @@ dependencies = [
|
||||
"syn 2.0.90",
|
||||
"wasmtime-component-util",
|
||||
"wasmtime-wit-bindgen",
|
||||
"wit-parser 0.221.3",
|
||||
"wit-parser 0.217.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-component-util"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "707dc7b3c112ab5a366b30cfe2fb5b2f8e6a0f682f16df96a5ec582bfe6f056e"
|
||||
checksum = "fdc29d2b56629d66d2fd791d1b46471d0016e0d684ed2dc299e870d127082268"
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-cranelift"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "366be722674d4bf153290fbcbc4d7d16895cc82fb3e869f8d550ff768f9e9e87"
|
||||
checksum = "f8c8af1197703f4de556a274384adf5db36a146f9892bc9607bad16881e75c80"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
@@ -15245,29 +15206,29 @@ dependencies = [
|
||||
"cranelift-entity",
|
||||
"cranelift-frontend",
|
||||
"cranelift-native",
|
||||
"gimli",
|
||||
"itertools 0.12.1",
|
||||
"cranelift-wasm",
|
||||
"gimli 0.29.0",
|
||||
"log",
|
||||
"object",
|
||||
"smallvec",
|
||||
"target-lexicon 0.13.2",
|
||||
"target-lexicon",
|
||||
"thiserror 1.0.69",
|
||||
"wasmparser 0.221.3",
|
||||
"wasmparser 0.217.1",
|
||||
"wasmtime-environ",
|
||||
"wasmtime-versioned-export-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-environ"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdadc1af7097347aa276a4f008929810f726b5b46946971c660b6d421e9994ad"
|
||||
checksum = "3f1b5af7bac868c5bce3b78a366a10677caacf6e6467c156301297e36ed31f3e"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cpp_demangle",
|
||||
"cranelift-bitset",
|
||||
"cranelift-entity",
|
||||
"gimli",
|
||||
"gimli 0.29.0",
|
||||
"indexmap",
|
||||
"log",
|
||||
"object",
|
||||
@@ -15276,19 +15237,19 @@ dependencies = [
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"smallvec",
|
||||
"target-lexicon 0.13.2",
|
||||
"wasm-encoder 0.221.3",
|
||||
"wasmparser 0.221.3",
|
||||
"target-lexicon",
|
||||
"wasm-encoder 0.217.1",
|
||||
"wasmparser 0.217.1",
|
||||
"wasmprinter",
|
||||
"wasmtime-component-util",
|
||||
"wasmtime-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-fiber"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccba90d4119f081bca91190485650730a617be1fff5228f8c4757ce133d21117"
|
||||
checksum = "665ccc1bb0f28496e6fa02e94c575ee9ad6e3202c7df8591e5dda78106d5aa4a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cc",
|
||||
@@ -15296,41 +15257,46 @@ dependencies = [
|
||||
"rustix",
|
||||
"wasmtime-asm-macros",
|
||||
"wasmtime-versioned-export-macros",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-jit-icache-coherence"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec5e8552e01692e6c2e5293171704fed8abdec79d1a6995a0870ab190e5747d1"
|
||||
checksum = "5d7314e32c624f645ad7d6b9fc3ac89eb7d2b9aa06695d6445cec087958ec27d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-math"
|
||||
version = "29.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29210ec2aa25e00f4d54605cedaf080f39ec01a872c5bd520ad04c67af1dde17"
|
||||
dependencies = [
|
||||
"libm",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-slab"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcb5821a96fa04ac14bc7b158bb3d5cd7729a053db5a74dad396cd513a5e5ccf"
|
||||
checksum = "f75cba1a8cc327839f493cfc3036c9de3d077d59ab76296bc710ee5f95be5391"
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-types"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6d83a7816947a4974e2380c311eacb1db009b8bad86081dc726b705603c93c7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-entity",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"smallvec",
|
||||
"wasmparser 0.217.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-versioned-export-macros"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86ff86db216dc0240462de40c8290887a613dddf9685508eb39479037ba97b5b"
|
||||
checksum = "6879a8e168aef3fe07335343b7fbede12fa494215e83322e173d4018e124a846"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -15339,9 +15305,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-wasi"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d1be69bfcab1bdac74daa7a1f9695ab992b9c8e21b9b061e7d66434097e0ca4"
|
||||
checksum = "d042ea66b2834fb03b8a6968ef1a99a4b537211b00f7502a4d6a37f4eb2049b2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -15356,30 +15322,30 @@ dependencies = [
|
||||
"futures 0.3.31",
|
||||
"io-extras",
|
||||
"io-lifetimes",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"system-interface",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"trait-variant",
|
||||
"url",
|
||||
"wasmtime",
|
||||
"wiggle",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-winch"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdbabfb8f20502d5e1d81092b9ead3682ae59988487aafcd7567387b7a43cf8f"
|
||||
checksum = "6baca2a919a288df653246069868b4de80f07e9679a8ef9b78ad79fc658ffd12"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"gimli",
|
||||
"gimli 0.29.0",
|
||||
"object",
|
||||
"target-lexicon 0.13.2",
|
||||
"wasmparser 0.221.3",
|
||||
"target-lexicon",
|
||||
"wasmparser 0.217.1",
|
||||
"wasmtime-cranelift",
|
||||
"wasmtime-environ",
|
||||
"winch-codegen",
|
||||
@@ -15387,14 +15353,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-wit-bindgen"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8358319c2dd1e4db79e3c1c5d3a5af84956615343f9f89f4e4996a36816e06e6"
|
||||
checksum = "3f571f63ac1d532e986eb3973bbef3a45e4ae83de521a8d573b0fe0594dc9608"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck 0.5.0",
|
||||
"heck 0.4.1",
|
||||
"indexmap",
|
||||
"wit-parser 0.221.3",
|
||||
"wit-parser 0.217.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -15622,9 +15588,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wiggle"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b9af35bc9629c52c261465320a9a07959164928b4241980ba1cf923b9e6751d"
|
||||
checksum = "4c8fdcd81702e0f46a8ab2ed28a5bf824aabf4a1af1673af496a020aacd0b6f9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -15637,12 +15603,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wiggle-generate"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cf267dd05673912c8138f4b54acabe6bd53407d9d1536f0fadb6520dd16e101"
|
||||
checksum = "14f745361f0a9071aaabd05de1bb2b782d9f0597f30d9c0f20326224902e64d5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck 0.5.0",
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"shellexpand 2.1.2",
|
||||
@@ -15652,9 +15618,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wiggle-macro"
|
||||
version = "29.0.1"
|
||||
version = "25.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c5c473d4198e6c2d377f3809f713ff0c110cab88a0805ae099a82119ee250c"
|
||||
checksum = "bfbdae3574621921ed3c13325edc910388487759d10fb330f656cfc69bee38db"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -15695,18 +15661,17 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "winch-codegen"
|
||||
version = "29.0.1"
|
||||
version = "0.23.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f849ef2c5f46cb0a20af4b4487aaa239846e52e2c03f13fa3c784684552859c"
|
||||
checksum = "01cd1dc56c5a45d509ff06e7ca8817eaa9ec3240096f07e71915d5d528658e8a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"gimli",
|
||||
"gimli 0.29.0",
|
||||
"regalloc2",
|
||||
"smallvec",
|
||||
"target-lexicon 0.13.2",
|
||||
"thiserror 1.0.69",
|
||||
"wasmparser 0.221.3",
|
||||
"target-lexicon",
|
||||
"wasmparser 0.217.1",
|
||||
"wasmtime-cranelift",
|
||||
"wasmtime-environ",
|
||||
]
|
||||
@@ -16200,9 +16165,9 @@ dependencies = [
|
||||
"anyhow",
|
||||
"heck 0.4.1",
|
||||
"indexmap",
|
||||
"wasm-metadata 0.201.0",
|
||||
"wasm-metadata",
|
||||
"wit-bindgen-core",
|
||||
"wit-component 0.201.0",
|
||||
"wit-component",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -16233,30 +16198,11 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-encoder 0.201.0",
|
||||
"wasm-metadata 0.201.0",
|
||||
"wasm-metadata",
|
||||
"wasmparser 0.201.0",
|
||||
"wit-parser 0.201.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-component"
|
||||
version = "0.221.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66c55ca8772d2b270e28066caed50ce4e53a28c3ac10e01efbd90e5be31e448b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.8.0",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-encoder 0.221.3",
|
||||
"wasm-metadata 0.221.3",
|
||||
"wasmparser 0.221.3",
|
||||
"wit-parser 0.221.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.201.0"
|
||||
@@ -16277,9 +16223,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.221.3"
|
||||
version = "0.217.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "896112579ed56b4a538b07a3d16e562d101ff6265c46b515ce0c701eef16b2ac"
|
||||
checksum = "e5aaf02882453eaeec4fe30f1e4263cfd8b8ea36dd00e1fe7d902d9cb498bccd"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
@@ -16290,7 +16236,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"unicode-xid",
|
||||
"wasmparser 0.221.3",
|
||||
"wasmparser 0.217.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
18
Cargo.toml
18
Cargo.toml
@@ -364,7 +364,8 @@ zeta = { path = "crates/zeta" }
|
||||
#
|
||||
|
||||
aho-corasick = "1.1"
|
||||
alacritty_terminal = "0.25"
|
||||
# TODO(#18342): Update to version 0.25 from crates.io when it is released.
|
||||
alacritty_terminal = { git = "https://github.com/alacritty/alacritty.git", rev = "5e78d20c709cb1ab8d44ca7a8702cc26d779227c" }
|
||||
any_vec = "0.14"
|
||||
anyhow = "1.0.86"
|
||||
arrayvec = { version = "0.7.4", features = ["serde"] }
|
||||
@@ -526,7 +527,7 @@ tiny_http = "0.8"
|
||||
toml = "0.8"
|
||||
tokio = { version = "1" }
|
||||
tower-http = "0.4.4"
|
||||
tree-sitter = { version = "0.25.2", features = ["wasm"] }
|
||||
tree-sitter = { version = "0.24", features = ["wasm"] }
|
||||
tree-sitter-bash = "0.23"
|
||||
tree-sitter-c = "0.23"
|
||||
tree-sitter-cpp = "0.23"
|
||||
@@ -539,7 +540,7 @@ tree-sitter-go-mod = { git = "https://github.com/camdencheek/tree-sitter-go-mod"
|
||||
tree-sitter-gowork = { git = "https://github.com/zed-industries/tree-sitter-go-work", rev = "acb0617bf7f4fda02c6217676cc64acb89536dc7" }
|
||||
tree-sitter-heex = { git = "https://github.com/zed-industries/tree-sitter-heex", rev = "1dd45142fbb05562e35b2040c6129c9bca346592" }
|
||||
tree-sitter-diff = "0.1.0"
|
||||
tree-sitter-html = "0.23"
|
||||
tree-sitter-html = "0.20"
|
||||
tree-sitter-jsdoc = "0.23"
|
||||
tree-sitter-json = "0.24"
|
||||
tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", rev = "9a23c1a96c0513d8fc6520972beedd419a973539" }
|
||||
@@ -555,18 +556,18 @@ unicode-segmentation = "1.10"
|
||||
unicode-script = "0.5.7"
|
||||
url = "2.2"
|
||||
uuid = { version = "1.1.2", features = ["v4", "v5", "v7", "serde"] }
|
||||
wasmparser = "0.221"
|
||||
wasm-encoder = "0.221"
|
||||
wasmtime = { version = "29", default-features = false, features = [
|
||||
wasmparser = "0.217"
|
||||
wasm-encoder = "0.217"
|
||||
wasmtime = { version = "25", default-features = false, features = [
|
||||
"async",
|
||||
"demangle",
|
||||
"runtime",
|
||||
"cranelift",
|
||||
"component-model",
|
||||
] }
|
||||
wasmtime-wasi = "29"
|
||||
wasmtime-wasi = "25"
|
||||
which = "6.0.0"
|
||||
wit-component = "0.221"
|
||||
wit-component = "0.201"
|
||||
zed_llm_client = "0.4"
|
||||
zstd = "0.11"
|
||||
metal = "0.31"
|
||||
@@ -701,7 +702,6 @@ codegen-units = 16
|
||||
[workspace.lints.clippy]
|
||||
dbg_macro = "deny"
|
||||
todo = "deny"
|
||||
too_many_arguments = "allow"
|
||||
|
||||
# Motivation: We use `vec![a..b]` a lot when dealing with ranges in text, so
|
||||
# warning on this rule produces a lot of noise.
|
||||
|
||||
@@ -587,7 +587,6 @@
|
||||
"save": "workspace::Save",
|
||||
"ctrl->": "assistant::QuoteSelection",
|
||||
"ctrl-<": "assistant::InsertIntoEditor",
|
||||
"ctrl-alt-/": "assistant::ToggleModelSelector",
|
||||
"shift-enter": "assistant::Split",
|
||||
"ctrl-r": "assistant::CycleMessageRole",
|
||||
"enter": "assistant::ConfirmCommand",
|
||||
@@ -767,7 +766,13 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder || (FileFinder > Picker > Editor) || (FileFinder > Picker > menu)",
|
||||
"context": "FileFinder",
|
||||
"bindings": {
|
||||
"ctrl": "file_finder::ToggleMenu"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && !menu_open",
|
||||
"bindings": {
|
||||
"ctrl-shift-p": "file_finder::SelectPrev",
|
||||
"ctrl-j": "pane::SplitDown",
|
||||
@@ -776,6 +781,15 @@
|
||||
"ctrl-l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && menu_open",
|
||||
"bindings": {
|
||||
"j": "pane::SplitDown",
|
||||
"k": "pane::SplitUp",
|
||||
"h": "pane::SplitLeft",
|
||||
"l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "TabSwitcher",
|
||||
"bindings": {
|
||||
|
||||
@@ -218,7 +218,6 @@
|
||||
"cmd-s": "workspace::Save",
|
||||
"cmd->": "assistant::QuoteSelection",
|
||||
"cmd-<": "assistant::InsertIntoEditor",
|
||||
"cmd-alt-/": "assistant::ToggleModelSelector",
|
||||
"shift-enter": "assistant::Split",
|
||||
"ctrl-r": "assistant::CycleMessageRole",
|
||||
"enter": "assistant::ConfirmCommand",
|
||||
@@ -785,7 +784,14 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder || (FileFinder > Picker > Editor) || (FileFinder > Picker > menu)",
|
||||
"context": "FileFinder",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd": "file_finder::ToggleMenu"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && !menu_open",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-shift-p": "file_finder::SelectPrev",
|
||||
@@ -795,6 +801,16 @@
|
||||
"cmd-l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && menu_open",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"j": "pane::SplitDown",
|
||||
"k": "pane::SplitUp",
|
||||
"h": "pane::SplitLeft",
|
||||
"l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "TabSwitcher",
|
||||
"use_key_equivalents": true,
|
||||
|
||||
@@ -154,10 +154,6 @@
|
||||
// 4. Highlight the full line (default):
|
||||
// "all"
|
||||
"current_line_highlight": "all",
|
||||
// Whether to highlight all occurrences of the selected text in an editor.
|
||||
"selection_highlight": true,
|
||||
// The debounce delay before querying highlights based on the selected text.
|
||||
"selection_highlight_debounce": 50,
|
||||
// The debounce delay before querying highlights from the language
|
||||
// server based on the current cursor location.
|
||||
"lsp_highlight_debounce": 75,
|
||||
@@ -263,8 +259,6 @@
|
||||
"git_diff": true,
|
||||
// Whether to show buffer search results in the scrollbar.
|
||||
"search_results": true,
|
||||
// Whether to show selected text occurrences in the scrollbar.
|
||||
"selected_text": true,
|
||||
// Whether to show selected symbol occurrences in the scrollbar.
|
||||
"selected_symbol": true,
|
||||
// Which diagnostic indicators to show in the scrollbar:
|
||||
@@ -736,8 +730,9 @@
|
||||
// Whether to show warnings or not by default.
|
||||
"include_warnings": true
|
||||
},
|
||||
// Files or globs of files that will be excluded by Zed entirely. They will be skipped during file
|
||||
// scans, file searches, and not be displayed in the project file tree. Takes precedence over `file_scan_inclusions`.
|
||||
// Add files or globs of files that will be excluded by Zed entirely:
|
||||
// they will be skipped during FS scan(s), file tree and file search
|
||||
// will lack the corresponding file entries. Overrides `file_scan_inclusions`.
|
||||
"file_scan_exclusions": [
|
||||
"**/.git",
|
||||
"**/.svn",
|
||||
@@ -749,10 +744,10 @@
|
||||
"**/.classpath",
|
||||
"**/.settings"
|
||||
],
|
||||
// Files or globs of files that will be included by Zed, even when ignored by git. This is useful
|
||||
// for files that are not tracked by git, but are still important to your project. Note that globs
|
||||
// that are overly broad can slow down Zed's file scanning. `file_scan_exclusions` takes
|
||||
// precedence over these inclusions.
|
||||
// Add files or globs of files that will be included by Zed, even when
|
||||
// ignored by git. This is useful for files that are not tracked by git,
|
||||
// but are still important to your project. Note that globs that are
|
||||
// overly broad can slow down Zed's file scanning. Overridden by `file_scan_exclusions`.
|
||||
"file_scan_inclusions": [".env*"],
|
||||
// Git gutter behavior configuration.
|
||||
"git": {
|
||||
|
||||
@@ -105,6 +105,16 @@
|
||||
"terminal.ansi.bright_white": "#fbf1c7ff",
|
||||
"terminal.ansi.dim_white": "#b0a189ff",
|
||||
"link_text.hover": "#83a598ff",
|
||||
"version_control.added": "#b7bb26ff",
|
||||
"version_control.added_background": "#b7bb2614",
|
||||
"version_control.deleted": "#fb4a35ff",
|
||||
"version_control.deleted_background": "#fb4a3514",
|
||||
"version_control.modified": "#f9bd2fff",
|
||||
"version_control.modified_background": "#f9bd2f14",
|
||||
"version_control.renamed": "#83a598ff",
|
||||
"version_control.conflict": "#f9bd2fff",
|
||||
"version_control.conflict_background": "#f9bd2f14",
|
||||
"version_control.ignored": "#998b78ff",
|
||||
"conflict": "#f9bd2fff",
|
||||
"conflict.background": "#572e10ff",
|
||||
"conflict.border": "#754916ff",
|
||||
@@ -490,6 +500,16 @@
|
||||
"terminal.ansi.bright_white": "#fbf1c7ff",
|
||||
"terminal.ansi.dim_white": "#b0a189ff",
|
||||
"link_text.hover": "#83a598ff",
|
||||
"version_control.added": "#b7bb26ff",
|
||||
"version_control.added_background": "#b7bb2614",
|
||||
"version_control.deleted": "#fb4a35ff",
|
||||
"version_control.deleted_background": "#fb4a3514",
|
||||
"version_control.modified": "#f9bd2fff",
|
||||
"version_control.modified_background": "#f9bd2f14",
|
||||
"version_control.renamed": "#83a598ff",
|
||||
"version_control.conflict": "#f9bd2fff",
|
||||
"version_control.conflict_background": "#f9bd2f14",
|
||||
"version_control.ignored": "#998b78ff",
|
||||
"conflict": "#f9bd2fff",
|
||||
"conflict.background": "#572e10ff",
|
||||
"conflict.border": "#754916ff",
|
||||
@@ -875,6 +895,16 @@
|
||||
"terminal.ansi.bright_white": "#fbf1c7ff",
|
||||
"terminal.ansi.dim_white": "#b0a189ff",
|
||||
"link_text.hover": "#83a598ff",
|
||||
"version_control.added": "#b7bb26ff",
|
||||
"version_control.added_background": "#b7bb2614",
|
||||
"version_control.deleted": "#fb4a35ff",
|
||||
"version_control.deleted_background": "#fb4a3514",
|
||||
"version_control.modified": "#f9bd2fff",
|
||||
"version_control.modified_background": "#f9bd2f14",
|
||||
"version_control.renamed": "#83a598ff",
|
||||
"version_control.conflict": "#f9bd2fff",
|
||||
"version_control.conflict_background": "#f9bd2f14",
|
||||
"version_control.ignored": "#998b78ff",
|
||||
"conflict": "#f9bd2fff",
|
||||
"conflict.background": "#572e10ff",
|
||||
"conflict.border": "#754916ff",
|
||||
@@ -1260,6 +1290,16 @@
|
||||
"terminal.ansi.bright_white": "#282828ff",
|
||||
"terminal.ansi.dim_white": "#73675eff",
|
||||
"link_text.hover": "#0b6678ff",
|
||||
"version_control.added": "#79740eff",
|
||||
"version_control.added_background": "#79740e14",
|
||||
"version_control.deleted": "#9d0006ff",
|
||||
"version_control.deleted_background": "#9d000614",
|
||||
"version_control.modified": "#b57614ff",
|
||||
"version_control.modified_background": "#b5761414",
|
||||
"version_control.renamed": "#076678ff",
|
||||
"version_control.conflict": "#b57614ff",
|
||||
"version_control.conflict_background": "#b5761414",
|
||||
"version_control.ignored": "#928374ff",
|
||||
"conflict": "#b57615ff",
|
||||
"conflict.background": "#f5e2d0ff",
|
||||
"conflict.border": "#ebccabff",
|
||||
@@ -1645,6 +1685,16 @@
|
||||
"terminal.ansi.bright_white": "#282828ff",
|
||||
"terminal.ansi.dim_white": "#73675eff",
|
||||
"link_text.hover": "#0b6678ff",
|
||||
"version_control.added": "#79740eff",
|
||||
"version_control.added_background": "#79740e14",
|
||||
"version_control.deleted": "#9d0006ff",
|
||||
"version_control.deleted_background": "#9d000614",
|
||||
"version_control.modified": "#b57614ff",
|
||||
"version_control.modified_background": "#b5761414",
|
||||
"version_control.renamed": "#076678ff",
|
||||
"version_control.conflict": "#b57614ff",
|
||||
"version_control.conflict_background": "#b5761414",
|
||||
"version_control.ignored": "#928374ff",
|
||||
"conflict": "#b57615ff",
|
||||
"conflict.background": "#f5e2d0ff",
|
||||
"conflict.border": "#ebccabff",
|
||||
@@ -2030,6 +2080,16 @@
|
||||
"terminal.ansi.bright_white": "#282828ff",
|
||||
"terminal.ansi.dim_white": "#73675eff",
|
||||
"link_text.hover": "#0b6678ff",
|
||||
"version_control.added": "#79740eff",
|
||||
"version_control.added_background": "#79740e14",
|
||||
"version_control.deleted": "#9d0006ff",
|
||||
"version_control.deleted_background": "#9d000614",
|
||||
"version_control.modified": "#b57614ff",
|
||||
"version_control.modified_background": "#b5761414",
|
||||
"version_control.renamed": "#076678ff",
|
||||
"version_control.conflict": "#b57614ff",
|
||||
"version_control.conflict_background": "#b5761414",
|
||||
"version_control.ignored": "#928374ff",
|
||||
"conflict": "#b57615ff",
|
||||
"conflict.background": "#f5e2d0ff",
|
||||
"conflict.border": "#ebccabff",
|
||||
|
||||
@@ -96,6 +96,16 @@
|
||||
"terminal.ansi.bright_white": "#dce0e5ff",
|
||||
"terminal.ansi.dim_white": "#575d65ff",
|
||||
"link_text.hover": "#74ade8ff",
|
||||
"version_control.added": "#a1c181ff",
|
||||
"version_control.added_background": "#a1c18114",
|
||||
"version_control.deleted": "#d07277ff",
|
||||
"version_control.deleted_background": "#d0727714",
|
||||
"version_control.modified": "#dec184ff",
|
||||
"version_control.modified_background": "#dec18414",
|
||||
"version_control.renamed": "#74ade8ff",
|
||||
"version_control.conflict": "#dec184ff",
|
||||
"version_control.conflict_background": "#dec18414",
|
||||
"version_control.ignored": "#878a98ff",
|
||||
"conflict": "#dec184ff",
|
||||
"conflict.background": "#dec1841a",
|
||||
"conflict.border": "#5d4c2fff",
|
||||
@@ -441,7 +451,7 @@
|
||||
"editor.invisible": "#a3a3a4ff",
|
||||
"editor.wrap_guide": "#383a410d",
|
||||
"editor.active_wrap_guide": "#383a411a",
|
||||
"editor.document_highlight.read_background": "#5c78e225",
|
||||
"editor.document_highlight.read_background": "#5c78e21a",
|
||||
"editor.document_highlight.write_background": "#a3a3a466",
|
||||
"terminal.background": "#fafafaff",
|
||||
"terminal.foreground": "#242529ff",
|
||||
|
||||
@@ -7,7 +7,7 @@ use assistant_context_editor::{
|
||||
make_lsp_adapter_delegate, AssistantContext, AssistantPanelDelegate, ContextEditor,
|
||||
ContextEditorToolbarItem, ContextEditorToolbarItemEvent, ContextHistory, ContextId,
|
||||
ContextStore, ContextStoreEvent, InsertDraggedFiles, SlashCommandCompletionProvider,
|
||||
DEFAULT_TAB_TITLE,
|
||||
ToggleModelSelector, DEFAULT_TAB_TITLE,
|
||||
};
|
||||
use assistant_settings::{AssistantDockPosition, AssistantSettings};
|
||||
use assistant_slash_command::SlashCommandWorkingSet;
|
||||
@@ -20,9 +20,8 @@ use gpui::{
|
||||
Subscription, Task, UpdateGlobal, WeakEntity,
|
||||
};
|
||||
use language::LanguageRegistry;
|
||||
use language_model::{
|
||||
AuthenticateError, LanguageModelProviderId, LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID,
|
||||
};
|
||||
use language_model::{LanguageModelProviderId, LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID};
|
||||
use language_model_selector::LanguageModelSelector;
|
||||
use project::Project;
|
||||
use prompt_library::{open_prompt_library, PromptBuilder, PromptLibrary};
|
||||
use search::{buffer_search::DivRegistrar, BufferSearchBar};
|
||||
@@ -30,7 +29,7 @@ use settings::{update_settings_file, Settings};
|
||||
use smol::stream::StreamExt;
|
||||
use std::{ops::ControlFlow, path::PathBuf, sync::Arc};
|
||||
use terminal_view::{terminal_panel::TerminalPanel, TerminalView};
|
||||
use ui::{prelude::*, ContextMenu, PopoverMenu, Tooltip};
|
||||
use ui::{prelude::*, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip};
|
||||
use util::{maybe, ResultExt};
|
||||
use workspace::DraggedTab;
|
||||
use workspace::{
|
||||
@@ -78,6 +77,7 @@ pub struct AssistantPanel {
|
||||
languages: Arc<LanguageRegistry>,
|
||||
fs: Arc<dyn Fs>,
|
||||
subscriptions: Vec<Subscription>,
|
||||
model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
|
||||
model_summary_editor: Entity<Editor>,
|
||||
authenticate_provider_task: Option<(LanguageModelProviderId, Task<()>)>,
|
||||
configuration_subscription: Option<Subscription>,
|
||||
@@ -119,9 +119,17 @@ impl AssistantPanel {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let model_selector_menu_handle = PopoverMenuHandle::default();
|
||||
let model_summary_editor = cx.new(|cx| Editor::single_line(window, cx));
|
||||
let context_editor_toolbar =
|
||||
cx.new(|_| ContextEditorToolbarItem::new(model_summary_editor.clone()));
|
||||
let context_editor_toolbar = cx.new(|cx| {
|
||||
ContextEditorToolbarItem::new(
|
||||
workspace,
|
||||
model_selector_menu_handle.clone(),
|
||||
model_summary_editor.clone(),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
let pane = cx.new(|cx| {
|
||||
let mut pane = Pane::new(
|
||||
@@ -323,6 +331,7 @@ impl AssistantPanel {
|
||||
languages: workspace.app_state().languages.clone(),
|
||||
fs: workspace.app_state().fs.clone(),
|
||||
subscriptions,
|
||||
model_selector_menu_handle,
|
||||
model_summary_editor,
|
||||
authenticate_provider_task: None,
|
||||
configuration_subscription: None,
|
||||
@@ -1045,6 +1054,15 @@ impl AssistantPanel {
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn toggle_model_selector(
|
||||
&mut self,
|
||||
_: &ToggleModelSelector,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.model_selector_menu_handle.toggle(window, cx);
|
||||
}
|
||||
|
||||
pub(crate) fn active_context_editor(&self, cx: &App) -> Option<Entity<ContextEditor>> {
|
||||
self.pane
|
||||
.read(cx)
|
||||
@@ -1158,10 +1176,7 @@ impl AssistantPanel {
|
||||
.map_or(false, |provider| provider.is_authenticated(cx))
|
||||
}
|
||||
|
||||
fn authenticate(
|
||||
&mut self,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<Task<Result<(), AuthenticateError>>> {
|
||||
fn authenticate(&mut self, cx: &mut Context<Self>) -> Option<Task<Result<()>>> {
|
||||
LanguageModelRegistry::read_global(cx)
|
||||
.active_provider()
|
||||
.map_or(None, |provider| Some(provider.authenticate(cx)))
|
||||
@@ -1214,6 +1229,7 @@ impl Render for AssistantPanel {
|
||||
}))
|
||||
.on_action(cx.listener(AssistantPanel::deploy_history))
|
||||
.on_action(cx.listener(AssistantPanel::deploy_prompt_library))
|
||||
.on_action(cx.listener(AssistantPanel::toggle_model_selector))
|
||||
.child(registrar.size_full().child(self.pane.clone()))
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
@@ -387,6 +387,7 @@ impl InlineAssistant {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn suggest_assist(
|
||||
&mut self,
|
||||
editor: &Entity<Editor>,
|
||||
@@ -1610,7 +1611,6 @@ impl Render for PromptEditor {
|
||||
cx,
|
||||
)
|
||||
},
|
||||
gpui::Corner::TopRight,
|
||||
))
|
||||
.map(|el| {
|
||||
let CodegenStatus::Error(error) = self.codegen.read(cx).status(cx) else {
|
||||
@@ -1674,6 +1674,7 @@ impl Focusable for PromptEditor {
|
||||
impl PromptEditor {
|
||||
const MAX_LINES: u8 = 8;
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new(
|
||||
id: InlineAssistId,
|
||||
gutter_dimensions: Arc<Mutex<GutterDimensions>>,
|
||||
@@ -2332,6 +2333,7 @@ struct InlineAssist {
|
||||
}
|
||||
|
||||
impl InlineAssist {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new(
|
||||
assist_id: InlineAssistId,
|
||||
group_id: InlineAssistGroupId,
|
||||
@@ -3013,7 +3015,7 @@ impl CodegenAlternative {
|
||||
let executor = cx.background_executor().clone();
|
||||
let message_id = message_id.clone();
|
||||
let line_based_stream_diff: Task<anyhow::Result<()>> =
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut response_latency = None;
|
||||
let request_start = Instant::now();
|
||||
let diff = async {
|
||||
@@ -3327,7 +3329,8 @@ impl CodegenAlternative {
|
||||
|
||||
cx.spawn(|codegen, mut cx| async move {
|
||||
let (deleted_row_ranges, inserted_row_ranges) = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
let old_text = old_snapshot
|
||||
.text_for_range(
|
||||
Point::new(old_range.start.row, 0)
|
||||
|
||||
@@ -662,7 +662,6 @@ impl Render for PromptEditor {
|
||||
cx,
|
||||
)
|
||||
},
|
||||
gpui::Corner::TopRight,
|
||||
))
|
||||
.children(
|
||||
if let CodegenStatus::Error(error) = &self.codegen.read(cx).status {
|
||||
@@ -702,6 +701,7 @@ impl Focusable for PromptEditor {
|
||||
impl PromptEditor {
|
||||
const MAX_LINES: u8 = 8;
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new(
|
||||
id: TerminalInlineAssistId,
|
||||
prompt_history: VecDeque<String>,
|
||||
@@ -1150,7 +1150,7 @@ impl Codegen {
|
||||
|
||||
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
|
||||
|
||||
let task = cx.background_spawn({
|
||||
let task = cx.background_executor().spawn({
|
||||
let message_id = message_id.clone();
|
||||
let executor = cx.background_executor().clone();
|
||||
async move {
|
||||
|
||||
@@ -179,7 +179,7 @@ impl ActiveThread {
|
||||
|
||||
let markdown = cx.new(|cx| {
|
||||
Markdown::new(
|
||||
text.into(),
|
||||
text,
|
||||
markdown_style,
|
||||
Some(self.language_registry.clone()),
|
||||
None,
|
||||
|
||||
@@ -66,7 +66,6 @@ pub fn init(
|
||||
cx: &mut App,
|
||||
) {
|
||||
AssistantSettings::register(cx);
|
||||
thread_store::init(cx);
|
||||
assistant_panel::init(cx);
|
||||
|
||||
inline_assistant::init(
|
||||
|
||||
@@ -61,9 +61,13 @@ impl Render for AssistantModelSelector {
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Label::new(model_name)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
div().max_w_32().child(
|
||||
Label::new(model_name)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted)
|
||||
.text_ellipsis()
|
||||
.into_any_element(),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
Icon::new(IconName::ChevronDown)
|
||||
@@ -80,7 +84,6 @@ impl Render for AssistantModelSelector {
|
||||
cx,
|
||||
)
|
||||
},
|
||||
gpui::Corner::BottomRight,
|
||||
)
|
||||
.with_handle(self.menu_handle.clone())
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use assistant_context_editor::{
|
||||
make_lsp_adapter_delegate, render_remaining_tokens, AssistantPanelDelegate, ConfigurationError,
|
||||
ContextEditor, ContextHistory, SlashCommandCompletionProvider,
|
||||
make_lsp_adapter_delegate, AssistantPanelDelegate, ConfigurationError, ContextEditor,
|
||||
ContextHistory, SlashCommandCompletionProvider,
|
||||
};
|
||||
use assistant_settings::{AssistantDockPosition, AssistantSettings};
|
||||
use assistant_slash_command::SlashCommandWorkingSet;
|
||||
@@ -323,9 +323,6 @@ impl AssistantPanel {
|
||||
}
|
||||
|
||||
fn open_history(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.thread_store
|
||||
.update(cx, |thread_store, cx| thread_store.reload(cx))
|
||||
.detach_and_log_err(cx);
|
||||
self.active_view = ActiveView::History;
|
||||
self.history.focus_handle(cx).focus(window);
|
||||
cx.notify();
|
||||
@@ -481,10 +478,6 @@ impl AssistantPanel {
|
||||
.update(cx, |this, cx| this.delete_thread(thread_id, cx))
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
pub(crate) fn active_context_editor(&self) -> Option<Entity<ContextEditor>> {
|
||||
self.context_editor.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for AssistantPanel {
|
||||
@@ -642,33 +635,20 @@ impl AssistantPanel {
|
||||
.border_color(cx.theme().colors().border)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_1()
|
||||
.justify_between()
|
||||
.child(
|
||||
h_flex()
|
||||
.child(Label::new(title))
|
||||
.when(sub_title.is_some(), |this| {
|
||||
this.child(
|
||||
h_flex()
|
||||
.pl_1p5()
|
||||
.gap_1p5()
|
||||
.child(
|
||||
Label::new("/")
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Disabled)
|
||||
.alpha(0.5),
|
||||
)
|
||||
.child(Label::new(sub_title.unwrap())),
|
||||
.child(Label::new(title))
|
||||
.when(sub_title.is_some(), |this| {
|
||||
this.child(
|
||||
h_flex()
|
||||
.pl_1p5()
|
||||
.gap_1p5()
|
||||
.child(
|
||||
Label::new("/")
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Disabled)
|
||||
.alpha(0.5),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.children(if matches!(self.active_view, ActiveView::PromptEditor) {
|
||||
self.context_editor
|
||||
.as_ref()
|
||||
.and_then(|editor| render_remaining_tokens(editor, cx))
|
||||
} else {
|
||||
None
|
||||
.child(Label::new(sub_title.unwrap())),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
|
||||
@@ -493,7 +493,7 @@ impl CodegenAlternative {
|
||||
let executor = cx.background_executor().clone();
|
||||
let message_id = message_id.clone();
|
||||
let line_based_stream_diff: Task<anyhow::Result<()>> =
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut response_latency = None;
|
||||
let request_start = Instant::now();
|
||||
let diff = async {
|
||||
@@ -807,7 +807,8 @@ impl CodegenAlternative {
|
||||
|
||||
cx.spawn(|codegen, mut cx| async move {
|
||||
let (deleted_row_ranges, inserted_row_ranges) = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
let old_text = old_snapshot
|
||||
.text_for_range(
|
||||
Point::new(old_range.start.row, 0)
|
||||
|
||||
@@ -208,7 +208,8 @@ impl PickerDelegate for FetchContextPickerDelegate {
|
||||
let confirm_behavior = self.confirm_behavior;
|
||||
cx.spawn_in(window, |this, mut cx| async move {
|
||||
let text = cx
|
||||
.background_spawn(Self::build_message(http_client, url.clone()))
|
||||
.background_executor()
|
||||
.spawn(Self::build_message(http_client, url.clone()))
|
||||
.await?;
|
||||
|
||||
this.update_in(&mut cx, |this, window, cx| {
|
||||
|
||||
@@ -288,11 +288,8 @@ impl PickerDelegate for FileContextPickerDelegate {
|
||||
|
||||
editor.insert("\n", window, cx); // Needed to end the fold
|
||||
|
||||
let file_icon = FileIcons::get_icon(&Path::new(&full_path), cx)
|
||||
.unwrap_or_else(|| SharedString::new(""));
|
||||
|
||||
let placeholder = FoldPlaceholder {
|
||||
render: render_fold_icon_button(file_icon, file_name.into()),
|
||||
render: render_fold_icon_button(IconName::File, file_name.into()),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
@@ -462,27 +459,15 @@ pub fn render_file_context_entry(
|
||||
}
|
||||
|
||||
fn render_fold_icon_button(
|
||||
icon: SharedString,
|
||||
icon: IconName,
|
||||
label: SharedString,
|
||||
) -> Arc<dyn Send + Sync + Fn(FoldId, Range<Anchor>, &mut Window, &mut App) -> AnyElement> {
|
||||
Arc::new(move |fold_id, _fold_range, _window, _cx| {
|
||||
ButtonLike::new(fold_id)
|
||||
.style(ButtonStyle::Filled)
|
||||
.layer(ElevationIndex::ElevatedSurface)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
Icon::from_path(icon.clone())
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
Label::new(label.clone())
|
||||
.size(LabelSize::Small)
|
||||
.single_line(),
|
||||
),
|
||||
)
|
||||
.child(Icon::new(icon))
|
||||
.child(Label::new(label.clone()).single_line())
|
||||
.into_any_element()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ impl PickerDelegate for ThreadContextPickerDelegate {
|
||||
};
|
||||
|
||||
let executor = cx.background_executor().clone();
|
||||
let search_task = cx.background_spawn(async move {
|
||||
let search_task = cx.background_executor().spawn(async move {
|
||||
if query.is_empty() {
|
||||
threads
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::sync::Arc;
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use collections::{BTreeMap, HashMap, HashSet};
|
||||
use futures::{self, future, Future, FutureExt};
|
||||
use gpui::{App, AppContext as _, AsyncApp, Context, Entity, SharedString, Task, WeakEntity};
|
||||
use gpui::{App, AsyncApp, Context, Entity, SharedString, Task, WeakEntity};
|
||||
use language::Buffer;
|
||||
use project::{ProjectPath, Worktree};
|
||||
use rope::Rope;
|
||||
@@ -456,7 +456,9 @@ fn collect_buffer_info_and_text(
|
||||
};
|
||||
// Important to collect version at the same time as content so that staleness logic is correct.
|
||||
let content = buffer.as_rope().clone();
|
||||
let text_task = cx.background_spawn(async move { to_fenced_codeblock(&path, content) });
|
||||
let text_task = cx
|
||||
.background_executor()
|
||||
.spawn(async move { to_fenced_codeblock(&path, content) });
|
||||
(buffer_info, text_task)
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ pub struct ContextStrip {
|
||||
}
|
||||
|
||||
impl ContextStrip {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
context_store: Entity<ContextStore>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
|
||||
@@ -228,12 +228,8 @@ impl InlineAssistant {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(inline_assist_target) = Self::resolve_inline_assist_target(
|
||||
workspace,
|
||||
workspace.panel::<AssistantPanel>(cx),
|
||||
window,
|
||||
cx,
|
||||
) else {
|
||||
let Some(inline_assist_target) = Self::resolve_inline_assist_target(workspace, window, cx)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -480,6 +476,7 @@ impl InlineAssistant {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn suggest_assist(
|
||||
&mut self,
|
||||
editor: &Entity<Editor>,
|
||||
@@ -1387,7 +1384,6 @@ impl InlineAssistant {
|
||||
|
||||
fn resolve_inline_assist_target(
|
||||
workspace: &mut Workspace,
|
||||
assistant_panel: Option<Entity<AssistantPanel>>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Option<InlineAssistTarget> {
|
||||
@@ -1407,20 +1403,7 @@ impl InlineAssistant {
|
||||
}
|
||||
}
|
||||
|
||||
let context_editor = assistant_panel
|
||||
.and_then(|panel| panel.read(cx).active_context_editor())
|
||||
.and_then(|editor| {
|
||||
let editor = &editor.read(cx).editor().clone();
|
||||
if editor.read(cx).is_focused(window) {
|
||||
Some(editor.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(context_editor) = context_editor {
|
||||
Some(InlineAssistTarget::Editor(context_editor))
|
||||
} else if let Some(workspace_editor) = workspace
|
||||
if let Some(workspace_editor) = workspace
|
||||
.active_item(cx)
|
||||
.and_then(|item| item.act_as::<Editor>(cx))
|
||||
{
|
||||
@@ -1450,6 +1433,7 @@ struct InlineAssistScrollLock {
|
||||
}
|
||||
|
||||
impl EditorInlineAssists {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new(editor: &Entity<Editor>, window: &mut Window, cx: &mut App) -> Self {
|
||||
let (highlight_updates_tx, mut highlight_updates_rx) = async_watch::channel(());
|
||||
Self {
|
||||
@@ -1561,6 +1545,7 @@ pub struct InlineAssist {
|
||||
}
|
||||
|
||||
impl InlineAssist {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new(
|
||||
assist_id: InlineAssistId,
|
||||
group_id: InlineAssistGroupId,
|
||||
|
||||
@@ -823,6 +823,7 @@ impl InlineAssistId {
|
||||
}
|
||||
|
||||
impl PromptEditor<BufferCodegen> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_buffer(
|
||||
id: InlineAssistId,
|
||||
gutter_dimensions: Arc<Mutex<GutterDimensions>>,
|
||||
@@ -983,6 +984,7 @@ impl TerminalInlineAssistId {
|
||||
}
|
||||
|
||||
impl PromptEditor<TerminalCodegen> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new_terminal(
|
||||
id: TerminalInlineAssistId,
|
||||
prompt_history: VecDeque<String>,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::inline_prompt_editor::CodegenStatus;
|
||||
use client::telemetry::Telemetry;
|
||||
use futures::{channel::mpsc, SinkExt, StreamExt};
|
||||
use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Task};
|
||||
use gpui::{App, Context, Entity, EventEmitter, Task};
|
||||
use language_model::{LanguageModelRegistry, LanguageModelRequest};
|
||||
use language_models::report_assistant_event;
|
||||
use std::{sync::Arc, time::Instant};
|
||||
@@ -53,7 +53,7 @@ impl TerminalCodegen {
|
||||
|
||||
let (mut hunks_tx, mut hunks_rx) = mpsc::channel(1);
|
||||
|
||||
let task = cx.background_spawn({
|
||||
let task = cx.background_executor().spawn({
|
||||
let message_id = message_id.clone();
|
||||
let executor = cx.background_executor().clone();
|
||||
async move {
|
||||
|
||||
@@ -9,9 +9,7 @@ use context_server::manager::ContextServerManager;
|
||||
use context_server::{ContextServerFactoryRegistry, ContextServerTool};
|
||||
use futures::future::{self, BoxFuture, Shared};
|
||||
use futures::FutureExt as _;
|
||||
use gpui::{
|
||||
prelude::*, App, BackgroundExecutor, Context, Entity, Global, ReadGlobal, SharedString, Task,
|
||||
};
|
||||
use gpui::{prelude::*, App, BackgroundExecutor, Context, Entity, SharedString, Task};
|
||||
use heed::types::SerdeBincode;
|
||||
use heed::Database;
|
||||
use language_model::Role;
|
||||
@@ -21,10 +19,6 @@ use util::ResultExt as _;
|
||||
|
||||
use crate::thread::{MessageId, Thread, ThreadId};
|
||||
|
||||
pub fn init(cx: &mut App) {
|
||||
ThreadsDatabase::init(cx);
|
||||
}
|
||||
|
||||
pub struct ThreadStore {
|
||||
#[allow(unused)]
|
||||
project: Entity<Project>,
|
||||
@@ -32,6 +26,7 @@ pub struct ThreadStore {
|
||||
context_server_manager: Entity<ContextServerManager>,
|
||||
context_server_tool_ids: HashMap<Arc<str>, Vec<ToolId>>,
|
||||
threads: Vec<SavedThreadMetadata>,
|
||||
database_future: Shared<BoxFuture<'static, Result<Arc<ThreadsDatabase>, Arc<anyhow::Error>>>>,
|
||||
}
|
||||
|
||||
impl ThreadStore {
|
||||
@@ -46,12 +41,24 @@ impl ThreadStore {
|
||||
ContextServerManager::new(context_server_factory_registry, project.clone(), cx)
|
||||
});
|
||||
|
||||
let executor = cx.background_executor().clone();
|
||||
let database_future = executor
|
||||
.spawn({
|
||||
let executor = executor.clone();
|
||||
let database_path = paths::support_dir().join("threads/threads-db.0.mdb");
|
||||
async move { ThreadsDatabase::new(database_path, executor) }
|
||||
})
|
||||
.then(|result| future::ready(result.map(Arc::new).map_err(Arc::new)))
|
||||
.boxed()
|
||||
.shared();
|
||||
|
||||
let this = Self {
|
||||
project,
|
||||
tools,
|
||||
context_server_manager,
|
||||
context_server_tool_ids: HashMap::default(),
|
||||
threads: Vec::new(),
|
||||
database_future,
|
||||
};
|
||||
this.register_context_server_handlers(cx);
|
||||
this.reload(cx).detach_and_log_err(cx);
|
||||
@@ -87,7 +94,7 @@ impl ThreadStore {
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<Entity<Thread>>> {
|
||||
let id = id.clone();
|
||||
let database_future = ThreadsDatabase::global_future(cx);
|
||||
let database_future = self.database_future.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let database = database_future.await.map_err(|err| anyhow!(err))?;
|
||||
let thread = database
|
||||
@@ -120,7 +127,7 @@ impl ThreadStore {
|
||||
(id, thread)
|
||||
});
|
||||
|
||||
let database_future = ThreadsDatabase::global_future(cx);
|
||||
let database_future = self.database_future.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let database = database_future.await.map_err(|err| anyhow!(err))?;
|
||||
database.save_thread(metadata, thread).await?;
|
||||
@@ -131,7 +138,7 @@ impl ThreadStore {
|
||||
|
||||
pub fn delete_thread(&mut self, id: &ThreadId, cx: &mut Context<Self>) -> Task<Result<()>> {
|
||||
let id = id.clone();
|
||||
let database_future = ThreadsDatabase::global_future(cx);
|
||||
let database_future = self.database_future.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let database = database_future.await.map_err(|err| anyhow!(err))?;
|
||||
database.delete_thread(id.clone()).await?;
|
||||
@@ -142,8 +149,8 @@ impl ThreadStore {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reload(&self, cx: &mut Context<Self>) -> Task<Result<()>> {
|
||||
let database_future = ThreadsDatabase::global_future(cx);
|
||||
fn reload(&self, cx: &mut Context<Self>) -> Task<Result<()>> {
|
||||
let database_future = self.database_future.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let threads = database_future
|
||||
.await
|
||||
@@ -246,40 +253,13 @@ pub struct SavedMessage {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
struct GlobalThreadsDatabase(
|
||||
Shared<BoxFuture<'static, Result<Arc<ThreadsDatabase>, Arc<anyhow::Error>>>>,
|
||||
);
|
||||
|
||||
impl Global for GlobalThreadsDatabase {}
|
||||
|
||||
pub(crate) struct ThreadsDatabase {
|
||||
struct ThreadsDatabase {
|
||||
executor: BackgroundExecutor,
|
||||
env: heed::Env,
|
||||
threads: Database<SerdeBincode<ThreadId>, SerdeBincode<SavedThread>>,
|
||||
}
|
||||
|
||||
impl ThreadsDatabase {
|
||||
fn global_future(
|
||||
cx: &mut App,
|
||||
) -> Shared<BoxFuture<'static, Result<Arc<ThreadsDatabase>, Arc<anyhow::Error>>>> {
|
||||
GlobalThreadsDatabase::global(cx).0.clone()
|
||||
}
|
||||
|
||||
fn init(cx: &mut App) {
|
||||
let executor = cx.background_executor().clone();
|
||||
let database_future = executor
|
||||
.spawn({
|
||||
let executor = executor.clone();
|
||||
let database_path = paths::support_dir().join("threads/threads-db.0.mdb");
|
||||
async move { ThreadsDatabase::new(database_path, executor) }
|
||||
})
|
||||
.then(|result| future::ready(result.map(Arc::new).map_err(Arc::new)))
|
||||
.boxed()
|
||||
.shared();
|
||||
|
||||
cx.set_global(GlobalThreadsDatabase(database_future));
|
||||
}
|
||||
|
||||
pub fn new(path: PathBuf, executor: BackgroundExecutor) -> Result<Self> {
|
||||
std::fs::create_dir_all(&path)?;
|
||||
|
||||
|
||||
@@ -650,6 +650,7 @@ impl AssistantContext {
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
id: ContextId,
|
||||
replica_id: ReplicaId,
|
||||
@@ -770,6 +771,7 @@ impl AssistantContext {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn deserialize(
|
||||
saved_context: SavedContext,
|
||||
path: PathBuf,
|
||||
@@ -849,7 +851,7 @@ impl AssistantContext {
|
||||
.collect::<Vec<_>>();
|
||||
context_ops.extend(self.pending_ops.iter().cloned());
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let buffer_ops = buffer_ops.await;
|
||||
context_ops.sort_unstable_by_key(|op| op.timestamp());
|
||||
buffer_ops
|
||||
@@ -1190,14 +1192,11 @@ impl AssistantContext {
|
||||
let Some(model) = LanguageModelRegistry::read_global(cx).active_model() else {
|
||||
return;
|
||||
};
|
||||
let debounce = self.token_count.is_some();
|
||||
self.pending_token_count = cx.spawn(|this, mut cx| {
|
||||
async move {
|
||||
if debounce {
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(200))
|
||||
.await;
|
||||
}
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(200))
|
||||
.await;
|
||||
|
||||
let token_count = cx.update(|cx| model.count_tokens(request, cx))?.await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
|
||||
@@ -193,8 +193,6 @@ pub struct ContextEditor {
|
||||
// the file is opened. In order to keep the worktree alive for the duration of the
|
||||
// context editor, we keep a reference here.
|
||||
dragged_file_worktrees: Vec<Entity<Worktree>>,
|
||||
language_model_selector: Entity<LanguageModelSelector>,
|
||||
language_model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
|
||||
}
|
||||
|
||||
pub const DEFAULT_TAB_TITLE: &str = "New Chat";
|
||||
@@ -240,22 +238,6 @@ impl ContextEditor {
|
||||
cx.subscribe_in(&editor, window, Self::handle_editor_search_event),
|
||||
];
|
||||
|
||||
let fs_clone = fs.clone();
|
||||
let language_model_selector = cx.new(|cx| {
|
||||
LanguageModelSelector::new(
|
||||
move |model, cx| {
|
||||
update_settings_file::<AssistantSettings>(
|
||||
fs_clone.clone(),
|
||||
cx,
|
||||
move |settings, _| settings.set_model(model.clone()),
|
||||
);
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
let language_model_selector_menu_handle = PopoverMenuHandle::default();
|
||||
let sections = context.read(cx).slash_command_output_sections().to_vec();
|
||||
let patch_ranges = context.read(cx).patch_ranges().collect::<Vec<_>>();
|
||||
let slash_commands = context.read(cx).slash_commands().clone();
|
||||
@@ -280,8 +262,6 @@ impl ContextEditor {
|
||||
show_accept_terms: false,
|
||||
slash_menu_handle: Default::default(),
|
||||
dragged_file_worktrees: Vec::new(),
|
||||
language_model_selector,
|
||||
language_model_selector_menu_handle,
|
||||
};
|
||||
this.update_message_headers(cx);
|
||||
this.update_image_blocks(cx);
|
||||
@@ -517,6 +497,7 @@ impl ContextEditor {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn run_command(
|
||||
&mut self,
|
||||
command_range: Range<language::Anchor>,
|
||||
@@ -2057,6 +2038,7 @@ impl ContextEditor {
|
||||
.unwrap_or_else(|| Cow::Borrowed(DEFAULT_TAB_TITLE))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn render_patch_block(
|
||||
&mut self,
|
||||
range: Range<text::Anchor>,
|
||||
@@ -2373,61 +2355,15 @@ impl ContextEditor {
|
||||
slash_command_picker::SlashCommandSelector::new(
|
||||
self.slash_commands.clone(),
|
||||
cx.entity().downgrade(),
|
||||
IconButton::new("trigger", IconName::Plus)
|
||||
Button::new("trigger", "Add Context")
|
||||
.icon(IconName::Plus)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_color(Color::Muted),
|
||||
move |window, cx| {
|
||||
Tooltip::with_meta(
|
||||
"Add Context",
|
||||
None,
|
||||
"Type / to insert via keyboard",
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
},
|
||||
.icon_color(Color::Muted)
|
||||
.icon_position(IconPosition::Start),
|
||||
Tooltip::text("Type / to insert via keyboard"),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_language_model_selector(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let active_model = LanguageModelRegistry::read_global(cx).active_model();
|
||||
let focus_handle = self.editor().focus_handle(cx).clone();
|
||||
let model_name = match active_model {
|
||||
Some(model) => model.name().0,
|
||||
None => SharedString::from("No model selected"),
|
||||
};
|
||||
|
||||
LanguageModelSelectorPopoverMenu::new(
|
||||
self.language_model_selector.clone(),
|
||||
ButtonLike::new("active-model")
|
||||
.style(ButtonStyle::Subtle)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Label::new(model_name)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
Icon::new(IconName::ChevronDown)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
),
|
||||
),
|
||||
move |window, cx| {
|
||||
Tooltip::for_action_in(
|
||||
"Change Model",
|
||||
&ToggleModelSelector,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
},
|
||||
gpui::Corner::BottomLeft,
|
||||
)
|
||||
.with_handle(self.language_model_selector_menu_handle.clone())
|
||||
}
|
||||
|
||||
fn render_last_error(&self, cx: &mut Context<Self>) -> Option<AnyElement> {
|
||||
let last_error = self.last_error.as_ref()?;
|
||||
|
||||
@@ -2916,17 +2852,7 @@ impl Render for ContextEditor {
|
||||
.border_t_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(self.render_inject_context_menu(cx))
|
||||
.child(ui::Divider::vertical())
|
||||
.child(
|
||||
div()
|
||||
.pl_0p5()
|
||||
.child(self.render_language_model_selector(cx)),
|
||||
),
|
||||
)
|
||||
.child(h_flex().gap_1().child(self.render_inject_context_menu(cx)))
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
@@ -3237,67 +3163,80 @@ impl FollowableItem for ContextEditor {
|
||||
pub struct ContextEditorToolbarItem {
|
||||
active_context_editor: Option<WeakEntity<ContextEditor>>,
|
||||
model_summary_editor: Entity<Editor>,
|
||||
language_model_selector: Entity<LanguageModelSelector>,
|
||||
language_model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
|
||||
}
|
||||
|
||||
impl ContextEditorToolbarItem {
|
||||
pub fn new(model_summary_editor: Entity<Editor>) -> Self {
|
||||
pub fn new(
|
||||
workspace: &Workspace,
|
||||
model_selector_menu_handle: PopoverMenuHandle<LanguageModelSelector>,
|
||||
model_summary_editor: Entity<Editor>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
Self {
|
||||
active_context_editor: None,
|
||||
model_summary_editor,
|
||||
language_model_selector: cx.new(|cx| {
|
||||
let fs = workspace.app_state().fs.clone();
|
||||
LanguageModelSelector::new(
|
||||
move |model, cx| {
|
||||
update_settings_file::<AssistantSettings>(
|
||||
fs.clone(),
|
||||
cx,
|
||||
move |settings, _| settings.set_model(model.clone()),
|
||||
);
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
language_model_selector_menu_handle: model_selector_menu_handle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_remaining_tokens(
|
||||
context_editor: &Entity<ContextEditor>,
|
||||
cx: &App,
|
||||
) -> Option<impl IntoElement> {
|
||||
let context = &context_editor.read(cx).context;
|
||||
|
||||
let (token_count_color, token_count, max_token_count, tooltip) = match token_state(context, cx)?
|
||||
{
|
||||
TokenState::NoTokensLeft {
|
||||
max_token_count,
|
||||
token_count,
|
||||
} => (
|
||||
Color::Error,
|
||||
token_count,
|
||||
max_token_count,
|
||||
Some("Token Limit Reached"),
|
||||
),
|
||||
TokenState::HasMoreTokens {
|
||||
max_token_count,
|
||||
token_count,
|
||||
over_warn_threshold,
|
||||
} => {
|
||||
let (color, tooltip) = if over_warn_threshold {
|
||||
(Color::Warning, Some("Token Limit is Close to Exhaustion"))
|
||||
} else {
|
||||
(Color::Muted, None)
|
||||
};
|
||||
(color, token_count, max_token_count, tooltip)
|
||||
}
|
||||
};
|
||||
|
||||
Some(
|
||||
h_flex()
|
||||
.id("token-count")
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Label::new(humanize_token_count(token_count))
|
||||
.size(LabelSize::Small)
|
||||
.color(token_count_color),
|
||||
)
|
||||
.child(Label::new("/").size(LabelSize::Small).color(Color::Muted))
|
||||
.child(
|
||||
Label::new(humanize_token_count(max_token_count))
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.when_some(tooltip, |element, tooltip| {
|
||||
element.tooltip(Tooltip::text(tooltip))
|
||||
}),
|
||||
)
|
||||
fn render_remaining_tokens(&self, cx: &mut Context<Self>) -> Option<impl IntoElement> {
|
||||
let context = &self
|
||||
.active_context_editor
|
||||
.as_ref()?
|
||||
.upgrade()?
|
||||
.read(cx)
|
||||
.context;
|
||||
let (token_count_color, token_count, max_token_count) = match token_state(context, cx)? {
|
||||
TokenState::NoTokensLeft {
|
||||
max_token_count,
|
||||
token_count,
|
||||
} => (Color::Error, token_count, max_token_count),
|
||||
TokenState::HasMoreTokens {
|
||||
max_token_count,
|
||||
token_count,
|
||||
over_warn_threshold,
|
||||
} => {
|
||||
let color = if over_warn_threshold {
|
||||
Color::Warning
|
||||
} else {
|
||||
Color::Muted
|
||||
};
|
||||
(color, token_count, max_token_count)
|
||||
}
|
||||
};
|
||||
Some(
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Label::new(humanize_token_count(token_count))
|
||||
.size(LabelSize::Small)
|
||||
.color(token_count_color),
|
||||
)
|
||||
.child(Label::new("/").size(LabelSize::Small).color(Color::Muted))
|
||||
.child(
|
||||
Label::new(humanize_token_count(max_token_count))
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ContextEditorToolbarItem {
|
||||
@@ -3324,7 +3263,8 @@ impl Render for ContextEditorToolbarItem {
|
||||
})),
|
||||
),
|
||||
);
|
||||
|
||||
let active_provider = LanguageModelRegistry::read_global(cx).active_provider();
|
||||
let active_model = LanguageModelRegistry::read_global(cx).active_model();
|
||||
let right_side = h_flex()
|
||||
.gap_2()
|
||||
// TODO display this in a nicer way, once we have a design for it.
|
||||
@@ -3340,12 +3280,57 @@ impl Render for ContextEditorToolbarItem {
|
||||
// scan_items_remaining
|
||||
// .map(|remaining_items| format!("Files to scan: {}", remaining_items))
|
||||
// })
|
||||
.children(
|
||||
self.active_context_editor
|
||||
.as_ref()
|
||||
.and_then(|editor| editor.upgrade())
|
||||
.and_then(|editor| render_remaining_tokens(&editor, cx)),
|
||||
);
|
||||
.child(
|
||||
LanguageModelSelectorPopoverMenu::new(
|
||||
self.language_model_selector.clone(),
|
||||
ButtonLike::new("active-model")
|
||||
.style(ButtonStyle::Subtle)
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
div()
|
||||
.overflow_x_hidden()
|
||||
.flex_grow()
|
||||
.whitespace_nowrap()
|
||||
.child(match (active_provider, active_model) {
|
||||
(Some(provider), Some(model)) => h_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
Icon::new(
|
||||
model
|
||||
.icon()
|
||||
.unwrap_or_else(|| provider.icon()),
|
||||
)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
)
|
||||
.child(
|
||||
Label::new(model.name().0)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.into_any_element(),
|
||||
_ => Label::new("No model selected")
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted)
|
||||
.into_any_element(),
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
Icon::new(IconName::ChevronDown)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
),
|
||||
),
|
||||
move |window, cx| {
|
||||
Tooltip::for_action("Change Model", &ToggleModelSelector, window, cx)
|
||||
},
|
||||
)
|
||||
.with_handle(self.language_model_selector_menu_handle.clone()),
|
||||
)
|
||||
.children(self.render_remaining_tokens(cx));
|
||||
|
||||
h_flex()
|
||||
.px_0p5()
|
||||
|
||||
@@ -265,18 +265,19 @@ impl ContextStore {
|
||||
local_versions.push(context.version(cx).to_proto(context_id.clone()));
|
||||
let client = this.client.clone();
|
||||
let project_id = envelope.payload.project_id;
|
||||
cx.background_spawn(async move {
|
||||
let operations = operations.await;
|
||||
for operation in operations {
|
||||
client.send(proto::UpdateContext {
|
||||
project_id,
|
||||
context_id: context_id.to_proto(),
|
||||
operation: Some(operation),
|
||||
})?;
|
||||
}
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let operations = operations.await;
|
||||
for operation in operations {
|
||||
client.send(proto::UpdateContext {
|
||||
project_id,
|
||||
context_id: context_id.to_proto(),
|
||||
operation: Some(operation),
|
||||
})?;
|
||||
}
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +401,8 @@ impl ContextStore {
|
||||
)
|
||||
})?;
|
||||
let operations = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
context_proto
|
||||
.operations
|
||||
.into_iter()
|
||||
@@ -434,7 +436,7 @@ impl ContextStore {
|
||||
let languages = self.languages.clone();
|
||||
let project = self.project.clone();
|
||||
let telemetry = self.telemetry.clone();
|
||||
let load = cx.background_spawn({
|
||||
let load = cx.background_executor().spawn({
|
||||
let path = path.clone();
|
||||
async move {
|
||||
let saved_context = fs.load(&path).await?;
|
||||
@@ -537,7 +539,8 @@ impl ContextStore {
|
||||
)
|
||||
})?;
|
||||
let operations = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
context_proto
|
||||
.operations
|
||||
.into_iter()
|
||||
@@ -690,7 +693,7 @@ impl ContextStore {
|
||||
pub fn search(&self, query: String, cx: &App) -> Task<Vec<SavedContextMetadata>> {
|
||||
let metadata = self.contexts_metadata.clone();
|
||||
let executor = cx.background_executor().clone();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
if query.is_empty() {
|
||||
metadata
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,7 @@ use anyhow::{anyhow, Context as _, Result};
|
||||
use collections::HashMap;
|
||||
use editor::ProposedChangesEditor;
|
||||
use futures::{future, TryFutureExt as _};
|
||||
use gpui::{App, AppContext as _, AsyncApp, Entity, SharedString};
|
||||
use gpui::{App, AsyncApp, Entity, SharedString};
|
||||
use language::{AutoindentMode, Buffer, BufferSnapshot};
|
||||
use project::{Project, ProjectPath};
|
||||
use std::{cmp, ops::Range, path::Path, sync::Arc};
|
||||
@@ -258,7 +258,8 @@ impl AssistantEdit {
|
||||
|
||||
let snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot())?;
|
||||
let suggestion = cx
|
||||
.background_spawn(async move { kind.resolve(&snapshot) })
|
||||
.background_executor()
|
||||
.spawn(async move { kind.resolve(&snapshot) })
|
||||
.await;
|
||||
|
||||
Ok((buffer, suggestion))
|
||||
@@ -546,7 +547,7 @@ impl Eq for AssistantPatch {}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use gpui::App;
|
||||
use gpui::{App, AppContext as _};
|
||||
use language::{
|
||||
language_settings::AllLanguageSettings, Language, LanguageConfig, LanguageMatcher,
|
||||
};
|
||||
|
||||
@@ -4,10 +4,10 @@ pub use assistant_slash_command::SlashCommand;
|
||||
use assistant_slash_command::{AfterCompletion, SlashCommandLine, SlashCommandWorkingSet};
|
||||
use editor::{CompletionProvider, Editor};
|
||||
use fuzzy::{match_strings, StringMatchCandidate};
|
||||
use gpui::{App, AppContext as _, Context, Entity, Task, WeakEntity, Window};
|
||||
use language::{Anchor, Buffer, LanguageServerId, ToPoint};
|
||||
use gpui::{App, Context, Entity, Task, WeakEntity, Window};
|
||||
use language::{Anchor, Buffer, CompletionDocumentation, LanguageServerId, ToPoint};
|
||||
use parking_lot::Mutex;
|
||||
use project::{lsp_store::CompletionDocumentation, CompletionIntent};
|
||||
use project::CompletionIntent;
|
||||
use rope::Point;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
@@ -121,7 +121,7 @@ impl SlashCommandCompletionProvider {
|
||||
Some(project::Completion {
|
||||
old_range: name_range.clone(),
|
||||
documentation: Some(CompletionDocumentation::SingleLine(
|
||||
command.description().into(),
|
||||
command.description(),
|
||||
)),
|
||||
new_text,
|
||||
label: command.label(cx),
|
||||
@@ -136,6 +136,7 @@ impl SlashCommandCompletionProvider {
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn complete_command_argument(
|
||||
&self,
|
||||
command_name: &str,
|
||||
@@ -162,7 +163,7 @@ impl SlashCommandCompletionProvider {
|
||||
let editor = self.editor.clone();
|
||||
let workspace = self.workspace.clone();
|
||||
let arguments = arguments.to_vec();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
Ok(completions
|
||||
.await?
|
||||
.into_iter()
|
||||
|
||||
@@ -102,7 +102,8 @@ impl PickerDelegate for SlashCommandDelegate {
|
||||
let all_commands = self.all_commands.clone();
|
||||
cx.spawn_in(window, |this, mut cx| async move {
|
||||
let filtered_commands = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
if query.is_empty() {
|
||||
all_commands
|
||||
} else {
|
||||
|
||||
@@ -88,7 +88,7 @@ pub trait SlashCommand: 'static + Send + Sync {
|
||||
fn accepts_arguments(&self) -> bool {
|
||||
self.requires_argument()
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn run(
|
||||
self: Arc<Self>,
|
||||
arguments: &[String],
|
||||
|
||||
@@ -103,7 +103,7 @@ impl SlashCommand for ExtensionSlashCommand {
|
||||
) -> Task<Result<Vec<ArgumentCompletion>>> {
|
||||
let command = self.command.clone();
|
||||
let arguments = arguments.to_owned();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let completions = self
|
||||
.extension
|
||||
.complete_slash_command_argument(command, arguments)
|
||||
@@ -135,7 +135,7 @@ impl SlashCommand for ExtensionSlashCommand {
|
||||
) -> Task<SlashCommandResult> {
|
||||
let command = self.command.clone();
|
||||
let arguments = arguments.to_owned();
|
||||
let output = cx.background_spawn(async move {
|
||||
let output = cx.background_executor().spawn(async move {
|
||||
let delegate =
|
||||
delegate.map(|delegate| Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _);
|
||||
let output = self
|
||||
|
||||
@@ -82,7 +82,7 @@ impl SlashCommand for AutoCommand {
|
||||
project_index.flush_summary_backlogs(cx)
|
||||
})?;
|
||||
|
||||
cx.background_spawn(task).await;
|
||||
cx.background_executor().spawn(task).await;
|
||||
|
||||
anyhow::Ok(Vec::new())
|
||||
})
|
||||
@@ -129,7 +129,7 @@ impl SlashCommand for AutoCommand {
|
||||
// so you don't have to write it again.
|
||||
let original_prompt = argument.to_string();
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let commands = task.await?;
|
||||
let mut prompt = String::new();
|
||||
|
||||
@@ -285,56 +285,57 @@ async fn commands_for_summaries(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let futures = completion_streams
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(ix, (stream, tx))| async move {
|
||||
let start = std::time::Instant::now();
|
||||
let events = stream.await?;
|
||||
log::info!("Time taken for awaiting /await chunk stream #{ix}: {:?}", start.elapsed());
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let futures = completion_streams
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(ix, (stream, tx))| async move {
|
||||
let start = std::time::Instant::now();
|
||||
let events = stream.await?;
|
||||
log::info!("Time taken for awaiting /await chunk stream #{ix}: {:?}", start.elapsed());
|
||||
|
||||
let completion: String = events
|
||||
.filter_map(|event| async {
|
||||
if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
|
||||
Some(text)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
log::info!("Time taken for all /auto chunks to come back for #{ix}: {:?}", start.elapsed());
|
||||
|
||||
for line in completion.split('\n') {
|
||||
if let Some(first_space) = line.find(' ') {
|
||||
let command = &line[..first_space].trim();
|
||||
let arg = &line[first_space..].trim();
|
||||
|
||||
tx.send(CommandToRun {
|
||||
name: command.to_string(),
|
||||
arg: arg.to_string(),
|
||||
let completion: String = events
|
||||
.filter_map(|event| async {
|
||||
if let Ok(LanguageModelCompletionEvent::Text(text)) = event {
|
||||
Some(text)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
} else if !line.trim().is_empty() {
|
||||
// All slash-commands currently supported in context inference need a space for the argument.
|
||||
log::warn!(
|
||||
"Context inference returned a non-blank line that contained no spaces (meaning no argument for the slash command): {:?}",
|
||||
line
|
||||
);
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
log::info!("Time taken for all /auto chunks to come back for #{ix}: {:?}", start.elapsed());
|
||||
|
||||
for line in completion.split('\n') {
|
||||
if let Some(first_space) = line.find(' ') {
|
||||
let command = &line[..first_space].trim();
|
||||
let arg = &line[first_space..].trim();
|
||||
|
||||
tx.send(CommandToRun {
|
||||
name: command.to_string(),
|
||||
arg: arg.to_string(),
|
||||
})
|
||||
.await?;
|
||||
} else if !line.trim().is_empty() {
|
||||
// All slash-commands currently supported in context inference need a space for the argument.
|
||||
log::warn!(
|
||||
"Context inference returned a non-blank line that contained no spaces (meaning no argument for the slash command): {:?}",
|
||||
line
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let _ = futures::future::try_join_all(futures).await.log_err();
|
||||
let _ = futures::future::try_join_all(futures).await.log_err();
|
||||
|
||||
let duration = all_start.elapsed();
|
||||
eprintln!("All futures completed in {:?}", duration);
|
||||
})
|
||||
let duration = all_start.elapsed();
|
||||
eprintln!("All futures completed in {:?}", duration);
|
||||
})
|
||||
.await;
|
||||
|
||||
drop(tx); // Close the channel so that rx.collect() won't hang. This is safe because all futures have completed.
|
||||
|
||||
@@ -132,7 +132,7 @@ impl SlashCommand for CargoWorkspaceSlashCommand {
|
||||
let project = workspace.project().clone();
|
||||
let fs = workspace.project().read(cx).fs().clone();
|
||||
let path = Self::path_to_cargo_toml(project, cx);
|
||||
let output = cx.background_spawn(async move {
|
||||
let output = cx.background_executor().spawn(async move {
|
||||
let path = path.with_context(|| "Cargo.toml not found")?;
|
||||
Self::build_message(fs, &path).await
|
||||
});
|
||||
|
||||
@@ -54,7 +54,7 @@ impl SlashCommand for DefaultSlashCommand {
|
||||
cx: &mut App,
|
||||
) -> Task<SlashCommandResult> {
|
||||
let store = PromptStore::global(cx);
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let store = store.await?;
|
||||
let prompts = store.default_prompt_metadata();
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ impl SlashCommand for DeltaSlashCommand {
|
||||
}
|
||||
}
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut output = SlashCommandOutput::default();
|
||||
let mut changes_detected = false;
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ impl SlashCommand for DiagnosticsSlashCommand {
|
||||
|
||||
let paths = self.search_paths(query.clone(), cancellation_flag.clone(), &workspace, cx);
|
||||
let executor = cx.background_executor().clone();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut matches: Vec<String> = paths
|
||||
.await
|
||||
.into_iter()
|
||||
|
||||
@@ -176,7 +176,7 @@ impl SlashCommand for DocsSlashCommand {
|
||||
.provider()
|
||||
.ok_or_else(|| anyhow!("no docs provider specified"))
|
||||
.and_then(|provider| IndexedDocsStore::try_global(provider, cx));
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
fn build_completions(items: Vec<String>) -> Vec<ArgumentCompletion> {
|
||||
items
|
||||
.into_iter()
|
||||
@@ -284,7 +284,7 @@ impl SlashCommand for DocsSlashCommand {
|
||||
|
||||
let args = DocsSlashCommandArgs::parse(arguments);
|
||||
let executor = cx.background_executor().clone();
|
||||
let task = cx.background_spawn({
|
||||
let task = cx.background_executor().spawn({
|
||||
let store = args
|
||||
.provider()
|
||||
.ok_or_else(|| anyhow!("no docs provider specified"))
|
||||
|
||||
@@ -151,7 +151,7 @@ impl SlashCommand for FetchSlashCommand {
|
||||
let http_client = workspace.read(cx).client().http_client();
|
||||
let url = argument.to_string();
|
||||
|
||||
let text = cx.background_spawn({
|
||||
let text = cx.background_executor().spawn({
|
||||
let url = url.clone();
|
||||
async move { Self::build_message(http_client, &url).await }
|
||||
});
|
||||
|
||||
@@ -156,7 +156,7 @@ impl SlashCommand for FileSlashCommand {
|
||||
cx,
|
||||
);
|
||||
let comment_id = cx.theme().syntax().highlight_id("comment").map(HighlightId);
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
Ok(paths
|
||||
.await
|
||||
.into_iter()
|
||||
|
||||
@@ -130,48 +130,49 @@ impl SlashCommand for ProjectSlashCommand {
|
||||
|
||||
let results = SemanticDb::load_results(results, &fs, &cx).await?;
|
||||
|
||||
cx.background_spawn(async move {
|
||||
let mut output = "Project context:\n".to_string();
|
||||
let mut sections = Vec::new();
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let mut output = "Project context:\n".to_string();
|
||||
let mut sections = Vec::new();
|
||||
|
||||
for (ix, query) in search_queries.into_iter().enumerate() {
|
||||
let start_ix = output.len();
|
||||
writeln!(&mut output, "Results for {query}:").unwrap();
|
||||
let mut has_results = false;
|
||||
for result in &results {
|
||||
if result.query_index == ix {
|
||||
add_search_result_section(result, &mut output, &mut sections);
|
||||
has_results = true;
|
||||
for (ix, query) in search_queries.into_iter().enumerate() {
|
||||
let start_ix = output.len();
|
||||
writeln!(&mut output, "Results for {query}:").unwrap();
|
||||
let mut has_results = false;
|
||||
for result in &results {
|
||||
if result.query_index == ix {
|
||||
add_search_result_section(result, &mut output, &mut sections);
|
||||
has_results = true;
|
||||
}
|
||||
}
|
||||
if has_results {
|
||||
sections.push(SlashCommandOutputSection {
|
||||
range: start_ix..output.len(),
|
||||
icon: IconName::MagnifyingGlass,
|
||||
label: query.into(),
|
||||
metadata: None,
|
||||
});
|
||||
output.push('\n');
|
||||
} else {
|
||||
output.truncate(start_ix);
|
||||
}
|
||||
}
|
||||
if has_results {
|
||||
sections.push(SlashCommandOutputSection {
|
||||
range: start_ix..output.len(),
|
||||
icon: IconName::MagnifyingGlass,
|
||||
label: query.into(),
|
||||
metadata: None,
|
||||
});
|
||||
output.push('\n');
|
||||
} else {
|
||||
output.truncate(start_ix);
|
||||
|
||||
sections.push(SlashCommandOutputSection {
|
||||
range: 0..output.len(),
|
||||
icon: IconName::Book,
|
||||
label: "Project context".into(),
|
||||
metadata: None,
|
||||
});
|
||||
|
||||
Ok(SlashCommandOutput {
|
||||
text: output,
|
||||
sections,
|
||||
run_commands_in_text: true,
|
||||
}
|
||||
}
|
||||
|
||||
sections.push(SlashCommandOutputSection {
|
||||
range: 0..output.len(),
|
||||
icon: IconName::Book,
|
||||
label: "Project context".into(),
|
||||
metadata: None,
|
||||
});
|
||||
|
||||
Ok(SlashCommandOutput {
|
||||
text: output,
|
||||
sections,
|
||||
run_commands_in_text: true,
|
||||
}
|
||||
.to_event_stream())
|
||||
})
|
||||
.await
|
||||
.to_event_stream())
|
||||
})
|
||||
.await
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ impl SlashCommand for PromptSlashCommand {
|
||||
) -> Task<Result<Vec<ArgumentCompletion>>> {
|
||||
let store = PromptStore::global(cx);
|
||||
let query = arguments.to_owned().join(" ");
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let prompts = store.await?.search(query).await;
|
||||
Ok(prompts
|
||||
.into_iter()
|
||||
@@ -77,7 +77,7 @@ impl SlashCommand for PromptSlashCommand {
|
||||
|
||||
let store = PromptStore::global(cx);
|
||||
let title = SharedString::from(title.clone());
|
||||
let prompt = cx.background_spawn({
|
||||
let prompt = cx.background_executor().spawn({
|
||||
let title = title.clone();
|
||||
async move {
|
||||
let store = store.await?;
|
||||
|
||||
@@ -119,7 +119,8 @@ impl SlashCommand for SearchSlashCommand {
|
||||
let loaded_results = SemanticDb::load_results(results, &fs, &cx).await?;
|
||||
|
||||
let output = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
let mut text = format!("Search results for {query}:\n");
|
||||
let mut sections = Vec::new();
|
||||
for loaded_result in &loaded_results {
|
||||
|
||||
@@ -63,55 +63,56 @@ impl SlashCommand for StreamingExampleSlashCommand {
|
||||
cx: &mut App,
|
||||
) -> Task<SlashCommandResult> {
|
||||
let (events_tx, events_rx) = mpsc::unbounded();
|
||||
cx.background_spawn(async move {
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||
icon: IconName::FileRust,
|
||||
label: "Section 1".into(),
|
||||
metadata: None,
|
||||
}))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
||||
SlashCommandContent::Text {
|
||||
text: "Hello".into(),
|
||||
run_commands_in_text: false,
|
||||
},
|
||||
)))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
||||
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||
icon: IconName::FileRust,
|
||||
label: "Section 2".into(),
|
||||
metadata: None,
|
||||
}))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
||||
SlashCommandContent::Text {
|
||||
text: "World".into(),
|
||||
run_commands_in_text: false,
|
||||
},
|
||||
)))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
||||
|
||||
for n in 1..=10 {
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||
icon: IconName::StarFilled,
|
||||
label: format!("Section {n}").into(),
|
||||
icon: IconName::FileRust,
|
||||
label: "Section 1".into(),
|
||||
metadata: None,
|
||||
}))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
||||
SlashCommandContent::Text {
|
||||
text: "lorem ipsum ".repeat(n).trim().into(),
|
||||
text: "Hello".into(),
|
||||
run_commands_in_text: false,
|
||||
},
|
||||
)))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
||||
}
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||
icon: IconName::FileRust,
|
||||
label: "Section 2".into(),
|
||||
metadata: None,
|
||||
}))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
||||
SlashCommandContent::Text {
|
||||
text: "World".into(),
|
||||
run_commands_in_text: false,
|
||||
},
|
||||
)))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
||||
|
||||
for n in 1..=10 {
|
||||
Timer::after(Duration::from_secs(1)).await;
|
||||
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::StartSection {
|
||||
icon: IconName::StarFilled,
|
||||
label: format!("Section {n}").into(),
|
||||
metadata: None,
|
||||
}))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::Content(
|
||||
SlashCommandContent::Text {
|
||||
text: "lorem ipsum ".repeat(n).trim().into(),
|
||||
run_commands_in_text: false,
|
||||
},
|
||||
)))?;
|
||||
events_tx.unbounded_send(Ok(SlashCommandEvent::EndSection))?;
|
||||
}
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
||||
Task::ready(Ok(events_rx.boxed()))
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use assistant_slash_command::{
|
||||
SlashCommandResult,
|
||||
};
|
||||
use editor::Editor;
|
||||
use gpui::{AppContext as _, Task, WeakEntity};
|
||||
use gpui::{Task, WeakEntity};
|
||||
use language::{BufferSnapshot, LspAdapterDelegate};
|
||||
use std::sync::Arc;
|
||||
use std::{path::Path, sync::atomic::AtomicBool};
|
||||
@@ -69,7 +69,7 @@ impl SlashCommand for OutlineSlashCommand {
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
let path = snapshot.resolve_file_path(cx, true);
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let outline = snapshot
|
||||
.outline(None)
|
||||
.context("no symbols for active tab")?;
|
||||
|
||||
@@ -152,7 +152,7 @@ impl SlashCommand for TabSlashCommand {
|
||||
cx,
|
||||
);
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut output = SlashCommandOutput::default();
|
||||
for (full_path, buffer, _) in tab_items_search.await? {
|
||||
append_buffer_to_output(&buffer, full_path.as_deref(), &mut output).log_err();
|
||||
@@ -212,73 +212,74 @@ fn tab_items_for_queries(
|
||||
})??;
|
||||
|
||||
let background_executor = cx.background_executor().clone();
|
||||
cx.background_spawn(async move {
|
||||
open_buffers.sort_by_key(|(_, _, timestamp)| *timestamp);
|
||||
if empty_query
|
||||
|| queries
|
||||
.iter()
|
||||
.any(|query| query == ALL_TABS_COMPLETION_ITEM)
|
||||
{
|
||||
return Ok(open_buffers);
|
||||
}
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
open_buffers.sort_by_key(|(_, _, timestamp)| *timestamp);
|
||||
if empty_query
|
||||
|| queries
|
||||
.iter()
|
||||
.any(|query| query == ALL_TABS_COMPLETION_ITEM)
|
||||
{
|
||||
return Ok(open_buffers);
|
||||
}
|
||||
|
||||
let matched_items = if strict_match {
|
||||
let match_candidates = open_buffers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(id, (full_path, ..))| {
|
||||
let path_string = full_path.as_deref()?.to_string_lossy().to_string();
|
||||
Some((id, path_string))
|
||||
})
|
||||
.fold(HashMap::default(), |mut candidates, (id, path_string)| {
|
||||
candidates
|
||||
.entry(path_string)
|
||||
.or_insert_with(Vec::new)
|
||||
.push(id);
|
||||
candidates
|
||||
let matched_items = if strict_match {
|
||||
let match_candidates = open_buffers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(id, (full_path, ..))| {
|
||||
let path_string = full_path.as_deref()?.to_string_lossy().to_string();
|
||||
Some((id, path_string))
|
||||
})
|
||||
.fold(HashMap::default(), |mut candidates, (id, path_string)| {
|
||||
candidates
|
||||
.entry(path_string)
|
||||
.or_insert_with(Vec::new)
|
||||
.push(id);
|
||||
candidates
|
||||
});
|
||||
|
||||
queries
|
||||
.iter()
|
||||
.filter_map(|query| match_candidates.get(query))
|
||||
.flatten()
|
||||
.copied()
|
||||
.filter_map(|id| open_buffers.get(id))
|
||||
.cloned()
|
||||
.collect()
|
||||
} else {
|
||||
let match_candidates = open_buffers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(id, (full_path, ..))| {
|
||||
let path_string = full_path.as_deref()?.to_string_lossy().to_string();
|
||||
Some(fuzzy::StringMatchCandidate::new(id, &path_string))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut processed_matches = HashSet::default();
|
||||
let file_queries = queries.iter().map(|query| {
|
||||
fuzzy::match_strings(
|
||||
&match_candidates,
|
||||
query,
|
||||
true,
|
||||
usize::MAX,
|
||||
&cancel,
|
||||
background_executor.clone(),
|
||||
)
|
||||
});
|
||||
|
||||
queries
|
||||
.iter()
|
||||
.filter_map(|query| match_candidates.get(query))
|
||||
.flatten()
|
||||
.copied()
|
||||
.filter_map(|id| open_buffers.get(id))
|
||||
.cloned()
|
||||
.collect()
|
||||
} else {
|
||||
let match_candidates = open_buffers
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(id, (full_path, ..))| {
|
||||
let path_string = full_path.as_deref()?.to_string_lossy().to_string();
|
||||
Some(fuzzy::StringMatchCandidate::new(id, &path_string))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut processed_matches = HashSet::default();
|
||||
let file_queries = queries.iter().map(|query| {
|
||||
fuzzy::match_strings(
|
||||
&match_candidates,
|
||||
query,
|
||||
true,
|
||||
usize::MAX,
|
||||
&cancel,
|
||||
background_executor.clone(),
|
||||
)
|
||||
});
|
||||
|
||||
join_all(file_queries)
|
||||
.await
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|string_match| processed_matches.insert(string_match.candidate_id))
|
||||
.filter_map(|string_match| open_buffers.get(string_match.candidate_id))
|
||||
.cloned()
|
||||
.collect()
|
||||
};
|
||||
Ok(matched_items)
|
||||
})
|
||||
.await
|
||||
join_all(file_queries)
|
||||
.await
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|string_match| processed_matches.insert(string_match.candidate_id))
|
||||
.filter_map(|string_match| open_buffers.get(string_match.candidate_id))
|
||||
.cloned()
|
||||
.collect()
|
||||
};
|
||||
Ok(matched_items)
|
||||
})
|
||||
.await
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -513,7 +513,7 @@ impl AutoUpdater {
|
||||
should_show: bool,
|
||||
cx: &App,
|
||||
) -> Task<Result<()>> {
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
if should_show {
|
||||
KEY_VALUE_STORE
|
||||
.write_kvp(
|
||||
@@ -531,7 +531,7 @@ impl AutoUpdater {
|
||||
}
|
||||
|
||||
pub fn should_show_update_notification(&self, cx: &App) -> Task<Result<bool>> {
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
Ok(KEY_VALUE_STORE
|
||||
.read_kvp(SHOULD_SHOW_UPDATE_NOTIFICATION_KEY)?
|
||||
.is_some())
|
||||
|
||||
@@ -19,6 +19,7 @@ editor.workspace = true
|
||||
gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
markdown_preview.workspace = true
|
||||
menu.workspace = true
|
||||
release_channel.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
mod update_notification;
|
||||
|
||||
use auto_update::AutoUpdater;
|
||||
use client::proto::UpdateNotification;
|
||||
use editor::{Editor, MultiBuffer};
|
||||
use gpui::{actions, prelude::*, App, Context, DismissEvent, Entity, SharedString, Window};
|
||||
use gpui::{actions, prelude::*, App, Context, Entity, SharedString, Window};
|
||||
use http_client::HttpClient;
|
||||
use markdown_preview::markdown_preview_view::{MarkdownPreviewMode, MarkdownPreviewView};
|
||||
use release_channel::{AppVersion, ReleaseChannel};
|
||||
use serde::Deserialize;
|
||||
use smol::io::AsyncReadExt;
|
||||
use util::ResultExt as _;
|
||||
use workspace::notifications::simple_message_notification::MessageNotification;
|
||||
use workspace::notifications::{show_app_notification, NotificationId};
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::update_notification::UpdateNotification;
|
||||
|
||||
actions!(auto_update, [ViewReleaseNotesLocally]);
|
||||
|
||||
pub fn init(cx: &mut App) {
|
||||
@@ -129,32 +131,19 @@ pub fn notify_if_app_was_updated(cx: &mut App) {
|
||||
let Some(updater) = AutoUpdater::get(cx) else {
|
||||
return;
|
||||
};
|
||||
let version = updater.read(cx).current_version();
|
||||
let should_show_notification = updater.read(cx).should_show_update_notification(cx);
|
||||
|
||||
cx.spawn(|cx| async move {
|
||||
let should_show_notification = should_show_notification.await?;
|
||||
if should_show_notification {
|
||||
cx.update(|cx| {
|
||||
let version = updater.read(cx).current_version();
|
||||
let app_name = ReleaseChannel::global(cx).display_name();
|
||||
show_app_notification(
|
||||
NotificationId::unique::<UpdateNotification>(),
|
||||
cx,
|
||||
move |cx| {
|
||||
let workspace_handle = cx.entity().downgrade();
|
||||
cx.new(|_cx| {
|
||||
MessageNotification::new(format!("Updated to {app_name} {}", version))
|
||||
.primary_message("View Release Notes")
|
||||
.primary_on_click(move |window, cx| {
|
||||
if let Some(workspace) = workspace_handle.upgrade() {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
crate::view_release_notes_locally(
|
||||
workspace, window, cx,
|
||||
);
|
||||
})
|
||||
}
|
||||
cx.emit(DismissEvent);
|
||||
})
|
||||
})
|
||||
cx.new(|_| UpdateNotification::new(version, workspace_handle))
|
||||
},
|
||||
);
|
||||
updater.update(cx, |updater, cx| {
|
||||
|
||||
70
crates/auto_update_ui/src/update_notification.rs
Normal file
70
crates/auto_update_ui/src/update_notification.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use gpui::{
|
||||
div, Context, DismissEvent, EventEmitter, InteractiveElement, IntoElement, ParentElement,
|
||||
Render, SemanticVersion, StatefulInteractiveElement, Styled, WeakEntity, Window,
|
||||
};
|
||||
use menu::Cancel;
|
||||
use release_channel::ReleaseChannel;
|
||||
use util::ResultExt;
|
||||
use workspace::{
|
||||
ui::{h_flex, v_flex, Icon, IconName, Label, StyledExt},
|
||||
Workspace,
|
||||
};
|
||||
|
||||
pub struct UpdateNotification {
|
||||
version: SemanticVersion,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
}
|
||||
|
||||
impl EventEmitter<DismissEvent> for UpdateNotification {}
|
||||
|
||||
impl Render for UpdateNotification {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let app_name = ReleaseChannel::global(cx).display_name();
|
||||
|
||||
v_flex()
|
||||
.on_action(cx.listener(UpdateNotification::dismiss))
|
||||
.elevation_3(cx)
|
||||
.p_4()
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.child(Label::new(format!(
|
||||
"Updated to {app_name} {}",
|
||||
self.version
|
||||
)))
|
||||
.child(
|
||||
div()
|
||||
.id("cancel")
|
||||
.child(Icon::new(IconName::Close))
|
||||
.cursor_pointer()
|
||||
.on_click(cx.listener(|this, _, window, cx| {
|
||||
this.dismiss(&menu::Cancel, window, cx)
|
||||
})),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("notes")
|
||||
.child(Label::new("View the release notes"))
|
||||
.cursor_pointer()
|
||||
.on_click(cx.listener(|this, _, window, cx| {
|
||||
this.workspace
|
||||
.update(cx, |workspace, cx| {
|
||||
crate::view_release_notes_locally(workspace, window, cx);
|
||||
})
|
||||
.log_err();
|
||||
this.dismiss(&menu::Cancel, window, cx)
|
||||
})),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl UpdateNotification {
|
||||
pub fn new(version: SemanticVersion, workspace: WeakEntity<Workspace>) -> Self {
|
||||
Self { version, workspace }
|
||||
}
|
||||
|
||||
pub fn dismiss(&mut self, _: &Cancel, _: &mut Window, cx: &mut Context<Self>) {
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
use futures::{channel::oneshot, future::OptionFuture};
|
||||
use git2::{DiffLineType as GitDiffLineType, DiffOptions as GitOptions, Patch as GitPatch};
|
||||
use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter};
|
||||
use gpui::{App, AsyncApp, Context, Entity, EventEmitter};
|
||||
use language::{Language, LanguageRegistry};
|
||||
use rope::Rope;
|
||||
use std::{cmp, future::Future, iter, ops::Range, sync::Arc};
|
||||
@@ -615,9 +615,11 @@ impl BufferDiff {
|
||||
cx,
|
||||
)
|
||||
});
|
||||
let base_text_snapshot = cx.background_spawn(OptionFuture::from(base_text_snapshot));
|
||||
let base_text_snapshot = cx
|
||||
.background_executor()
|
||||
.spawn(OptionFuture::from(base_text_snapshot));
|
||||
|
||||
let hunks = cx.background_spawn({
|
||||
let hunks = cx.background_executor().spawn({
|
||||
let buffer = buffer.clone();
|
||||
async move { compute_hunks(diff_base, buffer) }
|
||||
});
|
||||
@@ -639,7 +641,7 @@ impl BufferDiff {
|
||||
.clone()
|
||||
.map(|buffer| buffer.as_rope().clone()),
|
||||
);
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
BufferDiffInner {
|
||||
hunks: compute_hunks(diff_base, buffer),
|
||||
base_text: diff_base_buffer,
|
||||
@@ -719,6 +721,7 @@ impl BufferDiff {
|
||||
Some(start..end)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn update_diff(
|
||||
this: Entity<BufferDiff>,
|
||||
buffer: text::BufferSnapshot,
|
||||
@@ -996,7 +999,7 @@ mod tests {
|
||||
use std::fmt::Write as _;
|
||||
|
||||
use super::*;
|
||||
use gpui::TestAppContext;
|
||||
use gpui::{AppContext as _, TestAppContext};
|
||||
use rand::{rngs::StdRng, Rng as _};
|
||||
use text::{Buffer, BufferId, Rope};
|
||||
use unindent::Unindent as _;
|
||||
|
||||
@@ -241,7 +241,7 @@ impl ActiveCall {
|
||||
})
|
||||
.shared();
|
||||
self.pending_room_creation = Some(room.clone());
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
room.await.map_err(|err| anyhow!("{:?}", err))?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
@@ -278,7 +278,7 @@ impl ActiveCall {
|
||||
};
|
||||
|
||||
let client = self.client.clone();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
client
|
||||
.request(proto::CancelCall {
|
||||
room_id,
|
||||
|
||||
@@ -13,7 +13,7 @@ use client::{
|
||||
use collections::{BTreeMap, HashMap, HashSet};
|
||||
use fs::Fs;
|
||||
use futures::{FutureExt, StreamExt};
|
||||
use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
|
||||
use gpui::{App, AppContext, AsyncApp, Context, Entity, EventEmitter, Task, WeakEntity};
|
||||
use language::LanguageRegistry;
|
||||
#[cfg(not(all(target_os = "windows", target_env = "gnu")))]
|
||||
use livekit::{
|
||||
@@ -255,7 +255,7 @@ impl Room {
|
||||
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
|
||||
let task = if self.status.is_online() {
|
||||
let leave = self.leave_internal(cx);
|
||||
Some(cx.background_spawn(async move {
|
||||
Some(cx.background_executor().spawn(async move {
|
||||
leave.await.log_err();
|
||||
}))
|
||||
} else {
|
||||
@@ -322,7 +322,7 @@ impl Room {
|
||||
self.clear_state(cx);
|
||||
|
||||
let leave_room = self.client.request(proto::LeaveRoom {});
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
leave_room.await?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
@@ -1248,7 +1248,7 @@ impl Room {
|
||||
};
|
||||
|
||||
cx.notify();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
client
|
||||
.request(proto::UpdateParticipantLocation {
|
||||
room_id,
|
||||
@@ -1373,10 +1373,11 @@ impl Room {
|
||||
match publication {
|
||||
Ok(publication) => {
|
||||
if canceled {
|
||||
cx.background_spawn(async move {
|
||||
participant.unpublish_track(&publication.sid()).await
|
||||
})
|
||||
.detach_and_log_err(cx)
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
participant.unpublish_track(&publication.sid()).await
|
||||
})
|
||||
.detach_and_log_err(cx)
|
||||
} else {
|
||||
if live_kit.muted_by_user || live_kit.deafened {
|
||||
publication.mute();
|
||||
@@ -1464,10 +1465,11 @@ impl Room {
|
||||
match publication {
|
||||
Ok(publication) => {
|
||||
if canceled {
|
||||
cx.background_spawn(async move {
|
||||
participant.unpublish_track(&publication.sid()).await
|
||||
})
|
||||
.detach()
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
participant.unpublish_track(&publication.sid()).await
|
||||
})
|
||||
.detach()
|
||||
} else {
|
||||
live_kit.screen_track = LocalTrack::Published {
|
||||
track_publication: publication,
|
||||
@@ -1559,10 +1561,9 @@ impl Room {
|
||||
{
|
||||
let local_participant = live_kit.room.local_participant();
|
||||
let sid = track_publication.sid();
|
||||
cx.background_spawn(
|
||||
async move { local_participant.unpublish_track(&sid).await },
|
||||
)
|
||||
.detach_and_log_err(cx);
|
||||
cx.background_executor()
|
||||
.spawn(async move { local_participant.unpublish_track(&sid).await })
|
||||
.detach_and_log_err(cx);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
@@ -1721,12 +1722,13 @@ impl LiveKitRoom {
|
||||
}
|
||||
|
||||
let participant = self.room.local_participant();
|
||||
cx.background_spawn(async move {
|
||||
for sid in tracks_to_unpublish {
|
||||
participant.unpublish_track(&sid).await.log_err();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
for sid in tracks_to_unpublish {
|
||||
participant.unpublish_track(&sid).await.log_err();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ impl ActiveCall {
|
||||
})
|
||||
.shared();
|
||||
self.pending_room_creation = Some(room.clone());
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
room.await.map_err(|err| anyhow!("{:?}", err))?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
@@ -271,7 +271,7 @@ impl ActiveCall {
|
||||
};
|
||||
|
||||
let client = self.client.clone();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
client
|
||||
.request(proto::CancelCall {
|
||||
room_id,
|
||||
|
||||
@@ -311,7 +311,7 @@ impl Room {
|
||||
fn app_will_quit(&mut self, cx: &mut Context<Self>) -> impl Future<Output = ()> {
|
||||
let task = if self.status.is_online() {
|
||||
let leave = self.leave_internal(cx);
|
||||
Some(cx.background_spawn(async move {
|
||||
Some(cx.background_executor().spawn(async move {
|
||||
leave.await.log_err();
|
||||
}))
|
||||
} else {
|
||||
@@ -378,7 +378,7 @@ impl Room {
|
||||
self.clear_state(cx);
|
||||
|
||||
let leave_room = self.client.request(proto::LeaveRoom {});
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
leave_room.await?;
|
||||
anyhow::Ok(())
|
||||
})
|
||||
@@ -1268,7 +1268,7 @@ impl Room {
|
||||
};
|
||||
|
||||
cx.notify();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
client
|
||||
.request(proto::UpdateParticipantLocation {
|
||||
room_id,
|
||||
@@ -1385,7 +1385,9 @@ impl Room {
|
||||
live_kit.room.unpublish_track(publication);
|
||||
} else {
|
||||
if live_kit.muted_by_user || live_kit.deafened {
|
||||
cx.background_spawn(publication.set_mute(true)).detach();
|
||||
cx.background_executor()
|
||||
.spawn(publication.set_mute(true))
|
||||
.detach();
|
||||
}
|
||||
live_kit.microphone_track = LocalTrack::Published {
|
||||
track_publication: publication,
|
||||
|
||||
@@ -514,7 +514,8 @@ impl ChannelStore {
|
||||
}
|
||||
}
|
||||
};
|
||||
cx.background_spawn(async move { task.await.map_err(|error| anyhow!("{}", error)) })
|
||||
cx.background_executor()
|
||||
.spawn(async move { task.await.map_err(|error| anyhow!("{}", error)) })
|
||||
}
|
||||
|
||||
pub fn is_channel_admin(&self, channel_id: ChannelId) -> bool {
|
||||
@@ -780,7 +781,7 @@ impl ChannelStore {
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
let client = self.client.clone();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
client
|
||||
.request(proto::RespondToChannelInvite {
|
||||
channel_id: channel_id.0,
|
||||
@@ -974,18 +975,21 @@ impl ChannelStore {
|
||||
|
||||
if let Some(operations) = operations {
|
||||
let client = this.client.clone();
|
||||
cx.background_spawn(async move {
|
||||
let operations = operations.await;
|
||||
for chunk in language::proto::split_operations(operations) {
|
||||
client
|
||||
.send(proto::UpdateChannelBuffer {
|
||||
channel_id: channel_id.0,
|
||||
operations: chunk,
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let operations = operations.await;
|
||||
for chunk in
|
||||
language::proto::split_operations(operations)
|
||||
{
|
||||
client
|
||||
.send(proto::UpdateChannelBuffer {
|
||||
channel_id: channel_id.0,
|
||||
operations: chunk,
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use futures::{
|
||||
channel::oneshot, future::BoxFuture, AsyncReadExt, FutureExt, SinkExt, Stream, StreamExt,
|
||||
TryFutureExt as _, TryStreamExt,
|
||||
};
|
||||
use gpui::{actions, App, AppContext as _, AsyncApp, Entity, Global, Task, WeakEntity};
|
||||
use gpui::{actions, App, AsyncApp, Entity, Global, Task, WeakEntity};
|
||||
use http_client::{AsyncBody, HttpClient, HttpClientWithUrl};
|
||||
use parking_lot::RwLock;
|
||||
use postage::watch;
|
||||
@@ -1064,7 +1064,7 @@ impl Client {
|
||||
let rpc_url = self.rpc_url(http, release_channel);
|
||||
let system_id = self.telemetry.system_id();
|
||||
let metrics_id = self.telemetry.metrics_id();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
use HttpOrHttps::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -1743,7 +1743,7 @@ mod tests {
|
||||
use crate::test::FakeServer;
|
||||
|
||||
use clock::FakeSystemClock;
|
||||
use gpui::{BackgroundExecutor, TestAppContext};
|
||||
use gpui::{AppContext as _, BackgroundExecutor, TestAppContext};
|
||||
use http_client::FakeHttpClient;
|
||||
use parking_lot::Mutex;
|
||||
use proto::TypedEnvelope;
|
||||
@@ -1806,7 +1806,7 @@ mod tests {
|
||||
|
||||
// Time out when client tries to connect.
|
||||
client.override_authenticate(move |cx| {
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
Ok(Credentials {
|
||||
user_id,
|
||||
access_token: "token".into(),
|
||||
@@ -1814,7 +1814,7 @@ mod tests {
|
||||
})
|
||||
});
|
||||
client.override_establish_connection(|_, cx| {
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
future::pending::<()>().await;
|
||||
unreachable!()
|
||||
})
|
||||
@@ -1848,7 +1848,7 @@ mod tests {
|
||||
// Time out when re-establishing the connection.
|
||||
server.allow_connections();
|
||||
client.override_establish_connection(|_, cx| {
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
future::pending::<()>().await;
|
||||
unreachable!()
|
||||
})
|
||||
@@ -1887,7 +1887,7 @@ mod tests {
|
||||
move |cx| {
|
||||
let auth_count = auth_count.clone();
|
||||
let dropped_auth_count = dropped_auth_count.clone();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
*auth_count.lock() += 1;
|
||||
let _drop = util::defer(move || *dropped_auth_count.lock() += 1);
|
||||
future::pending::<()>().await;
|
||||
|
||||
@@ -5,7 +5,7 @@ use anyhow::Result;
|
||||
use clock::SystemClock;
|
||||
use futures::channel::mpsc;
|
||||
use futures::{Future, StreamExt};
|
||||
use gpui::{App, AppContext as _, BackgroundExecutor, Task};
|
||||
use gpui::{App, BackgroundExecutor, Task};
|
||||
use http_client::{self, AsyncBody, HttpClient, HttpClientWithUrl, Method, Request};
|
||||
use parking_lot::Mutex;
|
||||
use release_channel::ReleaseChannel;
|
||||
@@ -219,17 +219,18 @@ impl Telemetry {
|
||||
}));
|
||||
Self::log_file_path();
|
||||
|
||||
cx.background_spawn({
|
||||
let state = state.clone();
|
||||
let os_version = os_version();
|
||||
state.lock().os_version = Some(os_version.clone());
|
||||
async move {
|
||||
if let Some(tempfile) = File::create(Self::log_file_path()).log_err() {
|
||||
state.lock().log_file = Some(tempfile);
|
||||
cx.background_executor()
|
||||
.spawn({
|
||||
let state = state.clone();
|
||||
let os_version = os_version();
|
||||
state.lock().os_version = Some(os_version.clone());
|
||||
async move {
|
||||
if let Some(tempfile) = File::create(Self::log_file_path()).log_err() {
|
||||
state.lock().log_file = Some(tempfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
})
|
||||
.detach();
|
||||
|
||||
cx.observe_global::<SettingsStore>({
|
||||
let state = state.clone();
|
||||
@@ -251,16 +252,17 @@ impl Telemetry {
|
||||
let (tx, mut rx) = mpsc::unbounded();
|
||||
::telemetry::init(tx);
|
||||
|
||||
cx.background_spawn({
|
||||
let this = Arc::downgrade(&this);
|
||||
async move {
|
||||
while let Some(event) = rx.next().await {
|
||||
let Some(state) = this.upgrade() else { break };
|
||||
state.report_event(Event::Flexible(event))
|
||||
cx.background_executor()
|
||||
.spawn({
|
||||
let this = Arc::downgrade(&this);
|
||||
async move {
|
||||
while let Some(event) = rx.next().await {
|
||||
let Some(state) = this.upgrade() else { break };
|
||||
state.report_event(Event::Flexible(event))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
})
|
||||
.detach();
|
||||
|
||||
// We should only ever have one instance of Telemetry, leak the subscription to keep it alive
|
||||
// rather than store in TelemetryState, complicating spawn as subscriptions are not Send
|
||||
|
||||
@@ -85,7 +85,7 @@ impl FakeServer {
|
||||
Connection::in_memory(cx.background_executor().clone());
|
||||
let (connection_id, io, incoming) =
|
||||
peer.add_test_connection(server_conn, cx.background_executor().clone());
|
||||
cx.background_spawn(io).detach();
|
||||
cx.background_executor().spawn(io).detach();
|
||||
{
|
||||
let mut state = state.lock();
|
||||
state.connection_id = Some(connection_id);
|
||||
|
||||
@@ -229,6 +229,7 @@ impl Database {
|
||||
}
|
||||
|
||||
/// Creates a new channel message.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn create_channel_message(
|
||||
&self,
|
||||
channel_id: ChannelId,
|
||||
|
||||
@@ -122,6 +122,7 @@ impl Database {
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn get_or_create_user_by_github_account_tx(
|
||||
&self,
|
||||
github_login: &str,
|
||||
|
||||
@@ -289,6 +289,7 @@ impl LlmDatabase {
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn record_usage(
|
||||
&self,
|
||||
user_id: UserId,
|
||||
@@ -553,6 +554,7 @@ impl LlmDatabase {
|
||||
.await
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn update_usage_for_measure(
|
||||
&self,
|
||||
user_id: UserId,
|
||||
|
||||
@@ -33,6 +33,7 @@ pub struct LlmTokenClaims {
|
||||
const LLM_TOKEN_LIFETIME: Duration = Duration::from_secs(60 * 60);
|
||||
|
||||
impl LlmTokenClaims {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn create(
|
||||
user: &user::Model,
|
||||
is_staff: bool,
|
||||
|
||||
@@ -691,6 +691,7 @@ impl Server {
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn handle_connection(
|
||||
self: &Arc<Self>,
|
||||
connection: Connection,
|
||||
@@ -1074,6 +1075,7 @@ pub fn routes(server: Arc<Server>) -> Router<(), Body> {
|
||||
.layer(Extension(server))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn handle_websocket_request(
|
||||
TypedHeader(ProtocolVersion(protocol_version)): TypedHeader<ProtocolVersion>,
|
||||
app_version_header: Option<TypedHeader<AppVersionHeader>>,
|
||||
|
||||
@@ -463,6 +463,7 @@ impl<T: RandomizedTest> TestPlan<T> {
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn apply_server_operation(
|
||||
plan: Arc<Mutex<Self>>,
|
||||
deterministic: BackgroundExecutor,
|
||||
|
||||
@@ -244,17 +244,18 @@ impl TestServer {
|
||||
.await
|
||||
.expect("retrieving user failed")
|
||||
.unwrap();
|
||||
cx.background_spawn(server.handle_connection(
|
||||
server_conn,
|
||||
client_name,
|
||||
Principal::User(user),
|
||||
ZedVersion(SemanticVersion::new(1, 0, 0)),
|
||||
None,
|
||||
None,
|
||||
Some(connection_id_tx),
|
||||
Executor::Deterministic(cx.background_executor().clone()),
|
||||
))
|
||||
.detach();
|
||||
cx.background_executor()
|
||||
.spawn(server.handle_connection(
|
||||
server_conn,
|
||||
client_name,
|
||||
Principal::User(user),
|
||||
ZedVersion(SemanticVersion::new(1, 0, 0)),
|
||||
None,
|
||||
None,
|
||||
Some(connection_id_tx),
|
||||
Executor::Deterministic(cx.background_executor().clone()),
|
||||
))
|
||||
.detach();
|
||||
let connection_id = connection_id_rx.await.map_err(|e| {
|
||||
EstablishConnectionError::Other(anyhow!(
|
||||
"{} (is server shutting down?)",
|
||||
|
||||
@@ -201,7 +201,8 @@ impl ChatPanel {
|
||||
) -> Task<Result<Entity<Self>>> {
|
||||
cx.spawn(|mut cx| async move {
|
||||
let serialized_panel = if let Some(panel) = cx
|
||||
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
|
||||
.background_executor()
|
||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(CHAT_PANEL_KEY) })
|
||||
.await
|
||||
.log_err()
|
||||
.flatten()
|
||||
@@ -226,7 +227,7 @@ impl ChatPanel {
|
||||
|
||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||
let width = self.width;
|
||||
self.pending_serialization = cx.background_spawn(
|
||||
self.pending_serialization = cx.background_executor().spawn(
|
||||
async move {
|
||||
KEY_VALUE_STORE
|
||||
.write_kvp(
|
||||
|
||||
@@ -454,7 +454,8 @@ impl MessageEditor {
|
||||
mut cx: AsyncWindowContext,
|
||||
) {
|
||||
let (buffer, ranges) = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
let ranges = MENTIONS_SEARCH.search(&buffer, None).await;
|
||||
(buffer, ranges)
|
||||
})
|
||||
|
||||
@@ -319,7 +319,8 @@ impl CollabPanel {
|
||||
mut cx: AsyncWindowContext,
|
||||
) -> anyhow::Result<Entity<Self>> {
|
||||
let serialized_panel = cx
|
||||
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
|
||||
.background_executor()
|
||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(COLLABORATION_PANEL_KEY) })
|
||||
.await
|
||||
.map_err(|_| anyhow::anyhow!("Failed to read collaboration panel from key value store"))
|
||||
.log_err()
|
||||
@@ -350,7 +351,7 @@ impl CollabPanel {
|
||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||
let width = self.width;
|
||||
let collapsed_channels = self.collapsed_channels.clone();
|
||||
self.pending_serialization = cx.background_spawn(
|
||||
self.pending_serialization = cx.background_executor().spawn(
|
||||
async move {
|
||||
KEY_VALUE_STORE
|
||||
.write_kvp(
|
||||
@@ -869,6 +870,7 @@ impl CollabPanel {
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn render_participant_project(
|
||||
&self,
|
||||
project_id: u64,
|
||||
|
||||
@@ -183,7 +183,8 @@ impl NotificationPanel {
|
||||
) -> Task<Result<Entity<Self>>> {
|
||||
cx.spawn(|mut cx| async move {
|
||||
let serialized_panel = if let Some(panel) = cx
|
||||
.background_spawn(async move { KEY_VALUE_STORE.read_kvp(NOTIFICATION_PANEL_KEY) })
|
||||
.background_executor()
|
||||
.spawn(async move { KEY_VALUE_STORE.read_kvp(NOTIFICATION_PANEL_KEY) })
|
||||
.await
|
||||
.log_err()
|
||||
.flatten()
|
||||
@@ -208,7 +209,7 @@ impl NotificationPanel {
|
||||
|
||||
fn serialize(&mut self, cx: &mut Context<Self>) {
|
||||
let width = self.width;
|
||||
self.pending_serialization = cx.background_spawn(
|
||||
self.pending_serialization = cx.background_executor().spawn(
|
||||
async move {
|
||||
KEY_VALUE_STORE
|
||||
.write_kvp(
|
||||
|
||||
@@ -281,7 +281,7 @@ impl PickerDelegate for CommandPaletteDelegate {
|
||||
query = alias.to_string();
|
||||
}
|
||||
let (mut tx, mut rx) = postage::dispatch::channel(1);
|
||||
let task = cx.background_spawn({
|
||||
let task = cx.background_executor().spawn({
|
||||
let mut commands = self.all_commands.clone();
|
||||
let hit_counts = cx.global::<HitCounts>().clone();
|
||||
let executor = cx.background_executor().clone();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use collections::HashMap;
|
||||
use futures::{channel::oneshot, io::BufWriter, select, AsyncRead, AsyncWrite, FutureExt};
|
||||
use gpui::{AppContext as _, AsyncApp, BackgroundExecutor, Task};
|
||||
use gpui::{AsyncApp, BackgroundExecutor, Task};
|
||||
use parking_lot::Mutex;
|
||||
use postage::barrier;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
@@ -192,7 +192,7 @@ impl Client {
|
||||
let (stdout, stderr) = futures::join!(stdout_input_task, stderr_input_task);
|
||||
stdout.or(stderr)
|
||||
});
|
||||
let output_task = cx.background_spawn({
|
||||
let output_task = cx.background_executor().spawn({
|
||||
Self::handle_output(
|
||||
stdin,
|
||||
outbound_rx,
|
||||
|
||||
@@ -234,7 +234,8 @@ impl RegisteredBuffer {
|
||||
let new_snapshot = buffer.update(&mut cx, |buffer, _| buffer.snapshot()).ok()?;
|
||||
|
||||
let content_changes = cx
|
||||
.background_spawn({
|
||||
.background_executor()
|
||||
.spawn({
|
||||
let new_snapshot = new_snapshot.clone();
|
||||
async move {
|
||||
new_snapshot
|
||||
@@ -587,7 +588,8 @@ impl Copilot {
|
||||
}
|
||||
};
|
||||
|
||||
cx.background_spawn(task.map_err(|err| anyhow!("{:?}", err)))
|
||||
cx.background_executor()
|
||||
.spawn(task.map_err(|err| anyhow!("{:?}", err)))
|
||||
} else {
|
||||
// If we're downloading, wait until download is finished
|
||||
// If we're in a stuck state, display to the user
|
||||
@@ -599,7 +601,7 @@ impl Copilot {
|
||||
self.update_sign_in_status(request::SignInStatus::NotSignedIn, cx);
|
||||
if let CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) = &self.server {
|
||||
let server = server.clone();
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
server
|
||||
.request::<request::SignOut>(request::SignOutParams {})
|
||||
.await?;
|
||||
@@ -629,7 +631,7 @@ impl Copilot {
|
||||
|
||||
cx.notify();
|
||||
|
||||
cx.background_spawn(start_task)
|
||||
cx.background_executor().spawn(start_task)
|
||||
}
|
||||
|
||||
pub fn language_server(&self) -> Option<&Arc<LanguageServer>> {
|
||||
@@ -811,7 +813,7 @@ impl Copilot {
|
||||
.request::<request::NotifyAccepted>(request::NotifyAcceptedParams {
|
||||
uuid: completion.uuid.clone(),
|
||||
});
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
request.await?;
|
||||
Ok(())
|
||||
})
|
||||
@@ -835,7 +837,7 @@ impl Copilot {
|
||||
.map(|completion| completion.uuid.clone())
|
||||
.collect(),
|
||||
});
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
request.await?;
|
||||
Ok(())
|
||||
})
|
||||
@@ -882,7 +884,7 @@ impl Copilot {
|
||||
.map(|file| file.path().to_path_buf())
|
||||
.unwrap_or_default();
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let (version, snapshot) = snapshot.await?;
|
||||
let result = lsp
|
||||
.request::<R>(request::GetCompletionsParams {
|
||||
|
||||
@@ -40,15 +40,13 @@ pub enum Model {
|
||||
O3Mini,
|
||||
#[serde(alias = "claude-3-5-sonnet", rename = "claude-3.5-sonnet")]
|
||||
Claude3_5Sonnet,
|
||||
#[serde(alias = "gemini-2.0-flash", rename = "gemini-2.0-flash-001")]
|
||||
Gemini20Flash,
|
||||
}
|
||||
|
||||
impl Model {
|
||||
pub fn uses_streaming(&self) -> bool {
|
||||
match self {
|
||||
Self::Gpt4o | Self::Gpt4 | Self::Gpt3_5Turbo | Self::Claude3_5Sonnet => true,
|
||||
Self::O3Mini | Self::O1 | Self::Gemini20Flash => false,
|
||||
Self::O3Mini | Self::O1 => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +58,6 @@ impl Model {
|
||||
"o1" => Ok(Self::O1),
|
||||
"o3-mini" => Ok(Self::O3Mini),
|
||||
"claude-3-5-sonnet" => Ok(Self::Claude3_5Sonnet),
|
||||
"gemini-2.0-flash-001" => Ok(Self::Gemini20Flash),
|
||||
_ => Err(anyhow!("Invalid model id: {}", id)),
|
||||
}
|
||||
}
|
||||
@@ -73,7 +70,6 @@ impl Model {
|
||||
Self::O3Mini => "o3-mini",
|
||||
Self::O1 => "o1",
|
||||
Self::Claude3_5Sonnet => "claude-3-5-sonnet",
|
||||
Self::Gemini20Flash => "gemini-2.0-flash-001",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +81,6 @@ impl Model {
|
||||
Self::O3Mini => "o3-mini",
|
||||
Self::O1 => "o1",
|
||||
Self::Claude3_5Sonnet => "Claude 3.5 Sonnet",
|
||||
Self::Gemini20Flash => "Gemini 2.0 Flash",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +92,6 @@ impl Model {
|
||||
Self::O3Mini => 20000,
|
||||
Self::O1 => 20000,
|
||||
Self::Claude3_5Sonnet => 200_000,
|
||||
Model::Gemini20Flash => 128_000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ pub mod query;
|
||||
// Re-export
|
||||
pub use anyhow;
|
||||
use anyhow::Context as _;
|
||||
use gpui::{App, AppContext};
|
||||
use gpui::App;
|
||||
pub use indoc::indoc;
|
||||
pub use paths::database_dir;
|
||||
pub use smol;
|
||||
@@ -192,7 +192,8 @@ pub fn write_and_log<F>(cx: &App, db_write: impl FnOnce() -> F + Send + 'static)
|
||||
where
|
||||
F: Future<Output = anyhow::Result<()>> + Send,
|
||||
{
|
||||
cx.background_spawn(async move { db_write().await.log_err() })
|
||||
cx.background_executor()
|
||||
.spawn(async move { db_write().await.log_err() })
|
||||
.detach()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
div, px, uniform_list, AnyElement, BackgroundExecutor, Div, Entity, Focusable, FontWeight,
|
||||
div, px, uniform_list, AnyElement, BackgroundExecutor, Div, Entity, FontWeight,
|
||||
ListSizingBehavior, ScrollStrategy, SharedString, Size, StrikethroughStyle, StyledText,
|
||||
UniformListScrollHandle,
|
||||
UniformListScrollHandle, WeakEntity,
|
||||
};
|
||||
use language::Buffer;
|
||||
use language::CodeLabel;
|
||||
use language::{CodeLabel, CompletionDocumentation};
|
||||
use lsp::LanguageServerId;
|
||||
use markdown::Markdown;
|
||||
use multi_buffer::{Anchor, ExcerptId};
|
||||
use ordered_float::OrderedFloat;
|
||||
use project::lsp_store::CompletionDocumentation;
|
||||
use project::{CodeAction, Completion, TaskSourceKind};
|
||||
|
||||
use std::{
|
||||
@@ -23,12 +21,12 @@ use std::{
|
||||
use task::ResolvedTask;
|
||||
use ui::{prelude::*, Color, IntoElement, ListItem, Pixels, Popover, Styled};
|
||||
use util::ResultExt;
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::hover_popover::{hover_markdown_style, open_markdown_url};
|
||||
use crate::{
|
||||
actions::{ConfirmCodeAction, ConfirmCompletion},
|
||||
split_words, styled_runs_for_code_label, CodeActionProvider, CompletionId, CompletionProvider,
|
||||
DisplayRow, Editor, EditorStyle, ResolvedTasks,
|
||||
render_parsed_markdown, split_words, styled_runs_for_code_label, CodeActionProvider,
|
||||
CompletionId, CompletionProvider, DisplayRow, Editor, EditorStyle, ResolvedTasks,
|
||||
};
|
||||
|
||||
pub const MENU_GAP: Pixels = px(4.);
|
||||
@@ -139,27 +137,17 @@ impl CodeContextMenu {
|
||||
}
|
||||
|
||||
pub fn render_aside(
|
||||
&mut self,
|
||||
editor: &Editor,
|
||||
&self,
|
||||
style: &EditorStyle,
|
||||
max_size: Size<Pixels>,
|
||||
window: &mut Window,
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> Option<AnyElement> {
|
||||
match self {
|
||||
CodeContextMenu::Completions(menu) => menu.render_aside(editor, max_size, window, cx),
|
||||
CodeContextMenu::Completions(menu) => menu.render_aside(style, max_size, workspace, cx),
|
||||
CodeContextMenu::CodeActions(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn focused(&self, window: &mut Window, cx: &mut Context<Editor>) -> bool {
|
||||
match self {
|
||||
CodeContextMenu::Completions(completions_menu) => completions_menu
|
||||
.markdown_element
|
||||
.as_ref()
|
||||
.is_some_and(|markdown| markdown.focus_handle(cx).contains_focused(window, cx)),
|
||||
CodeContextMenu::CodeActions(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ContextMenuOrigin {
|
||||
@@ -181,7 +169,6 @@ pub struct CompletionsMenu {
|
||||
resolve_completions: bool,
|
||||
show_completion_documentation: bool,
|
||||
last_rendered_range: Rc<RefCell<Option<Range<usize>>>>,
|
||||
markdown_element: Option<Entity<Markdown>>,
|
||||
}
|
||||
|
||||
impl CompletionsMenu {
|
||||
@@ -212,7 +199,6 @@ impl CompletionsMenu {
|
||||
scroll_handle: UniformListScrollHandle::new(),
|
||||
resolve_completions: true,
|
||||
last_rendered_range: RefCell::new(None).into(),
|
||||
markdown_element: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +255,6 @@ impl CompletionsMenu {
|
||||
resolve_completions: false,
|
||||
show_completion_documentation: false,
|
||||
last_rendered_range: RefCell::new(None).into(),
|
||||
markdown_element: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,10 +556,10 @@ impl CompletionsMenu {
|
||||
}
|
||||
|
||||
fn render_aside(
|
||||
&mut self,
|
||||
editor: &Editor,
|
||||
&self,
|
||||
style: &EditorStyle,
|
||||
max_size: Size<Pixels>,
|
||||
window: &mut Window,
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> Option<AnyElement> {
|
||||
if !self.show_completion_documentation {
|
||||
@@ -586,35 +571,17 @@ impl CompletionsMenu {
|
||||
.documentation
|
||||
.as_ref()?
|
||||
{
|
||||
CompletionDocumentation::MultiLinePlainText(text) => div().child(text.clone()),
|
||||
CompletionDocumentation::MultiLineMarkdown(parsed) if !parsed.is_empty() => {
|
||||
let markdown = self.markdown_element.get_or_insert_with(|| {
|
||||
cx.new(|cx| {
|
||||
let languages = editor
|
||||
.workspace
|
||||
.as_ref()
|
||||
.and_then(|(workspace, _)| workspace.upgrade())
|
||||
.map(|workspace| workspace.read(cx).app_state().languages.clone());
|
||||
let language = editor
|
||||
.language_at(self.initial_position, cx)
|
||||
.map(|l| l.name().to_proto());
|
||||
Markdown::new(
|
||||
SharedString::default(),
|
||||
hover_markdown_style(window, cx),
|
||||
languages,
|
||||
language,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.copy_code_block_buttons(false)
|
||||
.open_url(open_markdown_url)
|
||||
})
|
||||
});
|
||||
markdown.update(cx, |markdown, cx| {
|
||||
markdown.reset(parsed.clone(), window, cx);
|
||||
});
|
||||
div().child(markdown.clone())
|
||||
CompletionDocumentation::MultiLinePlainText(text) => {
|
||||
div().child(SharedString::from(text.clone()))
|
||||
}
|
||||
CompletionDocumentation::MultiLineMarkdown(parsed) if !parsed.text.is_empty() => div()
|
||||
.child(render_parsed_markdown(
|
||||
"completions_markdown",
|
||||
parsed,
|
||||
&style,
|
||||
workspace,
|
||||
cx,
|
||||
)),
|
||||
CompletionDocumentation::MultiLineMarkdown(_) => return None,
|
||||
CompletionDocumentation::SingleLine(_) => return None,
|
||||
CompletionDocumentation::Undocumented => return None,
|
||||
|
||||
@@ -113,6 +113,7 @@ pub struct DisplayMap {
|
||||
}
|
||||
|
||||
impl DisplayMap {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
buffer: Entity<MultiBuffer>,
|
||||
font: Font,
|
||||
@@ -2069,30 +2070,18 @@ pub mod tests {
|
||||
)
|
||||
});
|
||||
|
||||
// Insert two blocks in the middle of a multi-line string literal.
|
||||
// The second block has zero height.
|
||||
// Insert a block in the middle of a multi-line string literal
|
||||
map.update(cx, |map, cx| {
|
||||
map.insert_blocks(
|
||||
[
|
||||
BlockProperties {
|
||||
placement: BlockPlacement::Below(
|
||||
buffer_snapshot.anchor_before(Point::new(1, 0)),
|
||||
),
|
||||
height: 1,
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| div().into_any()),
|
||||
priority: 0,
|
||||
},
|
||||
BlockProperties {
|
||||
placement: BlockPlacement::Below(
|
||||
buffer_snapshot.anchor_before(Point::new(2, 0)),
|
||||
),
|
||||
height: 0,
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| div().into_any()),
|
||||
priority: 0,
|
||||
},
|
||||
],
|
||||
[BlockProperties {
|
||||
placement: BlockPlacement::Below(
|
||||
buffer_snapshot.anchor_before(Point::new(1, 0)),
|
||||
),
|
||||
height: 1,
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| div().into_any()),
|
||||
priority: 0,
|
||||
}],
|
||||
cx,
|
||||
)
|
||||
});
|
||||
@@ -2777,7 +2766,6 @@ pub mod tests {
|
||||
fn init_test(cx: &mut App, f: impl Fn(&mut AllLanguageSettingsContent)) {
|
||||
let settings = SettingsStore::test(cx);
|
||||
cx.set_global(settings);
|
||||
workspace::init_settings(cx);
|
||||
language::init(cx);
|
||||
crate::init(cx);
|
||||
Project::init_settings(cx);
|
||||
|
||||
@@ -723,6 +723,7 @@ impl BlockMap {
|
||||
self.show_excerpt_controls
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn header_and_footer_blocks<'a, R, T>(
|
||||
show_excerpt_controls: bool,
|
||||
excerpt_footer_height: u32,
|
||||
@@ -1720,7 +1721,6 @@ impl BlockSnapshot {
|
||||
impl<'a> BlockChunks<'a> {
|
||||
/// Go to the next transform
|
||||
fn advance(&mut self) {
|
||||
self.input_chunk = Chunk::default();
|
||||
self.transforms.next(&());
|
||||
while let Some(transform) = self.transforms.item() {
|
||||
if transform
|
||||
@@ -1748,6 +1748,7 @@ impl<'a> BlockChunks<'a> {
|
||||
);
|
||||
self.input_chunks.seek(start_input_row..end_input_row);
|
||||
}
|
||||
self.input_chunk = Chunk::default();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1811,6 +1812,9 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
|
||||
let (mut prefix, suffix) = self.input_chunk.text.split_at(prefix_bytes);
|
||||
self.input_chunk.text = suffix;
|
||||
if self.output_row == transform_end {
|
||||
self.advance();
|
||||
}
|
||||
|
||||
if self.masked {
|
||||
// Not great for multibyte text because to keep cursor math correct we
|
||||
@@ -1820,16 +1824,10 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
prefix = &BULLETS[..bullet_len];
|
||||
}
|
||||
|
||||
let chunk = Chunk {
|
||||
Some(Chunk {
|
||||
text: prefix,
|
||||
..self.input_chunk.clone()
|
||||
};
|
||||
|
||||
if self.output_row == transform_end {
|
||||
self.advance();
|
||||
}
|
||||
|
||||
Some(chunk)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ impl WrapMap {
|
||||
|
||||
let text_system = cx.text_system().clone();
|
||||
let (font, font_size) = self.font_with_size.clone();
|
||||
let task = cx.background_spawn(async move {
|
||||
let task = cx.background_executor().spawn(async move {
|
||||
let mut line_wrapper = text_system.line_wrapper(font, font_size);
|
||||
let tab_snapshot = new_snapshot.tab_snapshot.clone();
|
||||
let range = TabPoint::zero()..tab_snapshot.max_point();
|
||||
@@ -255,7 +255,7 @@ impl WrapMap {
|
||||
let mut snapshot = self.snapshot.clone();
|
||||
let text_system = cx.text_system().clone();
|
||||
let (font, font_size) = self.font_with_size.clone();
|
||||
let update_task = cx.background_spawn(async move {
|
||||
let update_task = cx.background_executor().spawn(async move {
|
||||
let mut edits = Patch::default();
|
||||
let mut line_wrapper = text_system.line_wrapper(font, font_size);
|
||||
for (tab_snapshot, tab_edits) in pending_edits {
|
||||
|
||||
@@ -80,13 +80,13 @@ use code_context_menus::{
|
||||
use git::blame::GitBlame;
|
||||
use gpui::{
|
||||
div, impl_actions, point, prelude::*, pulsating_between, px, relative, size, Action, Animation,
|
||||
AnimationExt, AnyElement, App, AsyncWindowContext, AvailableSpace, Background, Bounds,
|
||||
ClipboardEntry, ClipboardItem, Context, DispatchPhase, ElementId, Entity, EntityInputHandler,
|
||||
EventEmitter, FocusHandle, FocusOutEvent, Focusable, FontId, FontWeight, Global,
|
||||
HighlightStyle, Hsla, InteractiveText, KeyContext, Modifiers, MouseButton, MouseDownEvent,
|
||||
PaintQuad, ParentElement, Pixels, Render, SharedString, Size, Styled, StyledText, Subscription,
|
||||
Task, TextStyle, TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle,
|
||||
WeakEntity, WeakFocusHandle, Window,
|
||||
AnimationExt, AnyElement, App, AsyncWindowContext, AvailableSpace, Bounds, ClipboardEntry,
|
||||
ClipboardItem, Context, DispatchPhase, ElementId, Entity, EntityInputHandler, EventEmitter,
|
||||
FocusHandle, FocusOutEvent, Focusable, FontId, FontWeight, Global, HighlightStyle, Hsla,
|
||||
InteractiveText, KeyContext, Modifiers, MouseButton, MouseDownEvent, PaintQuad, ParentElement,
|
||||
Pixels, Render, SharedString, Size, Styled, StyledText, Subscription, Task, TextStyle,
|
||||
TextStyleRefinement, UTF16Selection, UnderlineStyle, UniformListScrollHandle, WeakEntity,
|
||||
WeakFocusHandle, Window,
|
||||
};
|
||||
use highlight_matching_bracket::refresh_matching_bracket_highlights;
|
||||
use hover_popover::{hide_hover, HoverState};
|
||||
@@ -99,14 +99,13 @@ use itertools::Itertools;
|
||||
use language::{
|
||||
language_settings::{self, all_language_settings, language_settings, InlayHintSettings},
|
||||
markdown, point_from_lsp, AutoindentMode, BracketPair, Buffer, Capability, CharKind, CodeLabel,
|
||||
CursorShape, Diagnostic, DiskState, EditPredictionsMode, EditPreview, HighlightedText,
|
||||
IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject,
|
||||
TransactionId, TreeSitterOptions,
|
||||
CompletionDocumentation, CursorShape, Diagnostic, DiskState, EditPredictionsMode, EditPreview,
|
||||
HighlightedText, IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection,
|
||||
SelectionGoal, TextObject, TransactionId, TreeSitterOptions,
|
||||
};
|
||||
use language::{point_to_lsp, BufferRow, CharClassifier, Runnable, RunnableRange};
|
||||
use linked_editing_ranges::refresh_linked_ranges;
|
||||
use mouse_context_menu::MouseContextMenu;
|
||||
use persistence::DB;
|
||||
pub use proposed_changes_editor::{
|
||||
ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,
|
||||
};
|
||||
@@ -132,7 +131,7 @@ use multi_buffer::{
|
||||
ToOffsetUtf16,
|
||||
};
|
||||
use project::{
|
||||
lsp_store::{CompletionDocumentation, FormatTrigger, LspFormatTarget, OpenLspBufferHandle},
|
||||
lsp_store::{FormatTrigger, LspFormatTarget, OpenLspBufferHandle},
|
||||
project_settings::{GitGutterSetting, ProjectSettings},
|
||||
CodeAction, Completion, CompletionIntent, DocumentHighlight, InlayHint, Location, LocationLink,
|
||||
PrepareRenameResponse, Project, ProjectItem, ProjectTransaction, TaskSourceKind,
|
||||
@@ -172,14 +171,8 @@ use ui::{
|
||||
Tooltip,
|
||||
};
|
||||
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
|
||||
use workspace::{
|
||||
item::{ItemHandle, PreviewTabsSettings},
|
||||
ItemId, RestoreOnStartupBehavior,
|
||||
};
|
||||
use workspace::{
|
||||
notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt},
|
||||
WorkspaceSettings,
|
||||
};
|
||||
use workspace::item::{ItemHandle, PreviewTabsSettings};
|
||||
use workspace::notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt};
|
||||
use workspace::{
|
||||
searchable::SearchEvent, ItemNavHistory, SplitDirection, ViewId, Workspace, WorkspaceId,
|
||||
};
|
||||
@@ -206,14 +199,6 @@ pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration:
|
||||
pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction";
|
||||
pub(crate) const EDIT_PREDICTION_CONFLICT_KEY_CONTEXT: &str = "edit_prediction_conflict";
|
||||
|
||||
const COLUMNAR_SELECTION_MODIFIERS: Modifiers = Modifiers {
|
||||
alt: true,
|
||||
shift: true,
|
||||
control: false,
|
||||
platform: false,
|
||||
function: false,
|
||||
};
|
||||
|
||||
pub fn render_parsed_markdown(
|
||||
element_id: impl Into<ElementId>,
|
||||
parsed: &language::ParsedMarkdown,
|
||||
@@ -298,7 +283,6 @@ impl InlayId {
|
||||
enum DocumentHighlightRead {}
|
||||
enum DocumentHighlightWrite {}
|
||||
enum InputComposition {}
|
||||
enum SelectedTextHighlight {}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Navigated {
|
||||
@@ -697,7 +681,6 @@ pub struct Editor {
|
||||
next_completion_id: CompletionId,
|
||||
available_code_actions: Option<(Location, Rc<[AvailableCodeAction]>)>,
|
||||
code_actions_task: Option<Task<Result<()>>>,
|
||||
selection_highlight_task: Option<Task<()>>,
|
||||
document_highlights_task: Option<Task<()>>,
|
||||
linked_editing_range_task: Option<Task<Option<()>>>,
|
||||
linked_edit_ranges: linked_editing_ranges::LinkedEditingRanges,
|
||||
@@ -778,7 +761,6 @@ pub struct Editor {
|
||||
selection_mark_mode: bool,
|
||||
toggle_fold_multiple_buffers: Task<()>,
|
||||
_scroll_cursor_center_top_bottom_task: Task<()>,
|
||||
serialize_selections: Task<()>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||
@@ -1402,7 +1384,6 @@ impl Editor {
|
||||
code_action_providers,
|
||||
available_code_actions: Default::default(),
|
||||
code_actions_task: Default::default(),
|
||||
selection_highlight_task: Default::default(),
|
||||
document_highlights_task: Default::default(),
|
||||
linked_editing_range_task: Default::default(),
|
||||
pending_rename: Default::default(),
|
||||
@@ -1491,7 +1472,6 @@ impl Editor {
|
||||
_scroll_cursor_center_top_bottom_task: Task::ready(()),
|
||||
selection_mark_mode: false,
|
||||
toggle_fold_multiple_buffers: Task::ready(()),
|
||||
serialize_selections: Task::ready(()),
|
||||
text_style_refinement: None,
|
||||
load_diff_task: load_uncommitted_diff,
|
||||
};
|
||||
@@ -2185,7 +2165,6 @@ impl Editor {
|
||||
}
|
||||
self.refresh_code_actions(window, cx);
|
||||
self.refresh_document_highlights(cx);
|
||||
self.refresh_selected_text_highlights(window, cx);
|
||||
refresh_matching_bracket_highlights(self, window, cx);
|
||||
self.update_visible_inline_completion(window, cx);
|
||||
self.edit_prediction_requires_modifier_in_leading_space = true;
|
||||
@@ -2198,38 +2177,9 @@ impl Editor {
|
||||
self.blink_manager.update(cx, BlinkManager::pause_blinking);
|
||||
cx.emit(EditorEvent::SelectionsChanged { local });
|
||||
|
||||
let selections = &self.selections.disjoint;
|
||||
if selections.len() == 1 {
|
||||
if self.selections.disjoint_anchors().len() == 1 {
|
||||
cx.emit(SearchEvent::ActiveMatchChanged)
|
||||
}
|
||||
if local
|
||||
&& self.is_singleton(cx)
|
||||
&& WorkspaceSettings::get(None, cx).restore_on_startup != RestoreOnStartupBehavior::None
|
||||
{
|
||||
if let Some(workspace_id) = self.workspace.as_ref().and_then(|workspace| workspace.1) {
|
||||
let background_executor = cx.background_executor().clone();
|
||||
let editor_id = cx.entity().entity_id().as_u64() as ItemId;
|
||||
let snapshot = self.buffer().read(cx).snapshot(cx);
|
||||
let selections = selections.clone();
|
||||
self.serialize_selections = cx.background_spawn(async move {
|
||||
background_executor.timer(Duration::from_millis(100)).await;
|
||||
let selections = selections
|
||||
.iter()
|
||||
.map(|selection| {
|
||||
(
|
||||
selection.start.to_offset(&snapshot),
|
||||
selection.end.to_offset(&snapshot),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
DB.save_editor_selections(editor_id, workspace_id, selections)
|
||||
.await
|
||||
.with_context(|| format!("persisting editor selections for editor {editor_id}, workspace {workspace_id:?}"))
|
||||
.log_err();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
@@ -2243,7 +2193,7 @@ impl Editor {
|
||||
self.change_selections_inner(autoscroll, true, window, cx, change)
|
||||
}
|
||||
|
||||
fn change_selections_inner<R>(
|
||||
pub fn change_selections_inner<R>(
|
||||
&mut self,
|
||||
autoscroll: Option<Autoscroll>,
|
||||
request_completions: bool,
|
||||
@@ -4772,91 +4722,6 @@ impl Editor {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn refresh_selected_text_highlights(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
self.selection_highlight_task.take();
|
||||
if !EditorSettings::get_global(cx).selection_highlight {
|
||||
self.clear_background_highlights::<SelectedTextHighlight>(cx);
|
||||
return;
|
||||
}
|
||||
let debounce = EditorSettings::get_global(cx).selection_highlight_debounce;
|
||||
self.selection_highlight_task = Some(cx.spawn_in(window, |editor, mut cx| async move {
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(debounce))
|
||||
.await;
|
||||
let Some(Some(matches_task)) = editor
|
||||
.update_in(&mut cx, |editor, _, cx| {
|
||||
if editor.selections.count() != 1 || editor.selections.line_mode {
|
||||
editor.clear_background_highlights::<SelectedTextHighlight>(cx);
|
||||
return None;
|
||||
}
|
||||
let selection = editor.selections.newest::<Point>(cx);
|
||||
if selection.is_empty() || selection.start.row != selection.end.row {
|
||||
editor.clear_background_highlights::<SelectedTextHighlight>(cx);
|
||||
return None;
|
||||
}
|
||||
let buffer = editor.buffer().read(cx).snapshot(cx);
|
||||
Some(cx.background_spawn(async move {
|
||||
let mut ranges = Vec::new();
|
||||
let query = buffer.text_for_range(selection.range()).collect::<String>();
|
||||
for range in [buffer.anchor_before(0)..buffer.anchor_after(buffer.len())] {
|
||||
for (search_buffer, search_range, excerpt_id) in
|
||||
buffer.range_to_buffer_ranges(range)
|
||||
{
|
||||
ranges.extend(
|
||||
project::search::SearchQuery::text(
|
||||
query.clone(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
.search(search_buffer, Some(search_range.clone()))
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|match_range| {
|
||||
let start = search_buffer
|
||||
.anchor_after(search_range.start + match_range.start);
|
||||
let end = search_buffer
|
||||
.anchor_before(search_range.start + match_range.end);
|
||||
Anchor::range_in_buffer(
|
||||
excerpt_id,
|
||||
search_buffer.remote_id(),
|
||||
start..end,
|
||||
)
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
ranges
|
||||
}))
|
||||
})
|
||||
.log_err()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let matches = matches_task.await;
|
||||
editor
|
||||
.update_in(&mut cx, |editor, _, cx| {
|
||||
editor.clear_background_highlights::<SelectedTextHighlight>(cx);
|
||||
if !matches.is_empty() {
|
||||
editor.highlight_background::<SelectedTextHighlight>(
|
||||
&matches,
|
||||
|theme| theme.editor_document_highlight_bracket_background,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
})
|
||||
.log_err();
|
||||
}));
|
||||
}
|
||||
|
||||
pub fn refresh_inline_completion(
|
||||
&mut self,
|
||||
debounce: bool,
|
||||
@@ -5127,7 +4992,6 @@ impl Editor {
|
||||
.contains(&target.to_display_point(&position_map.snapshot).row())
|
||||
|| !self.edit_prediction_requires_modifier()
|
||||
{
|
||||
self.unfold_ranges(&[target..target], true, false, cx);
|
||||
// Note that this is also done in vim's handler of the Tab action.
|
||||
self.change_selections(
|
||||
Some(Autoscroll::newest()),
|
||||
@@ -5349,8 +5213,6 @@ impl Editor {
|
||||
self.update_edit_prediction_preview(&modifiers, window, cx);
|
||||
}
|
||||
|
||||
self.update_selection_mode(&modifiers, position_map, window, cx);
|
||||
|
||||
let mouse_position = window.mouse_position();
|
||||
if !position_map.text_hitbox.is_hovered(window) {
|
||||
return;
|
||||
@@ -5365,32 +5227,6 @@ impl Editor {
|
||||
)
|
||||
}
|
||||
|
||||
fn update_selection_mode(
|
||||
&mut self,
|
||||
modifiers: &Modifiers,
|
||||
position_map: &PositionMap,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if modifiers != &COLUMNAR_SELECTION_MODIFIERS || self.selections.pending.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mouse_position = window.mouse_position();
|
||||
let point_for_position = position_map.point_for_position(mouse_position);
|
||||
let position = point_for_position.previous_valid;
|
||||
|
||||
self.select(
|
||||
SelectPhase::BeginColumnar {
|
||||
position,
|
||||
reset: false,
|
||||
goal_column: point_for_position.exact_unclipped.column(),
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
|
||||
fn update_edit_prediction_preview(
|
||||
&mut self,
|
||||
modifiers: &Modifiers,
|
||||
@@ -5919,13 +5755,14 @@ impl Editor {
|
||||
editor_bg_color.blend(accent_color.opacity(0.1))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn render_edit_prediction_cursor_popover(
|
||||
&self,
|
||||
min_width: Pixels,
|
||||
max_width: Pixels,
|
||||
cursor_point: Point,
|
||||
style: &EditorStyle,
|
||||
accept_keystroke: Option<&gpui::Keystroke>,
|
||||
accept_keystroke: &gpui::Keystroke,
|
||||
_window: &Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> Option<AnyElement> {
|
||||
@@ -6004,7 +5841,7 @@ impl Editor {
|
||||
)
|
||||
.child(Label::new("Hold").size(LabelSize::Small))
|
||||
.child(h_flex().children(ui::render_modifiers(
|
||||
&accept_keystroke?.modifiers,
|
||||
&accept_keystroke.modifiers,
|
||||
PlatformStyle::platform(),
|
||||
Some(Color::Default),
|
||||
Some(IconSize::Small.rems().into()),
|
||||
@@ -6069,41 +5906,35 @@ impl Editor {
|
||||
.overflow_hidden()
|
||||
.child(completion),
|
||||
)
|
||||
.when_some(accept_keystroke, |el, accept_keystroke| {
|
||||
if !accept_keystroke.modifiers.modified() {
|
||||
return el;
|
||||
}
|
||||
|
||||
el.child(
|
||||
h_flex()
|
||||
.h_full()
|
||||
.border_l_1()
|
||||
.rounded_r_lg()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.bg(Self::edit_prediction_line_popover_bg_color(cx))
|
||||
.gap_1()
|
||||
.py_1()
|
||||
.px_2()
|
||||
.child(
|
||||
h_flex()
|
||||
.font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
|
||||
.when(is_platform_style_mac, |parent| parent.gap_1())
|
||||
.child(h_flex().children(ui::render_modifiers(
|
||||
&accept_keystroke.modifiers,
|
||||
PlatformStyle::platform(),
|
||||
Some(if !has_completion {
|
||||
Color::Muted
|
||||
} else {
|
||||
Color::Default
|
||||
}),
|
||||
None,
|
||||
false,
|
||||
))),
|
||||
)
|
||||
.child(Label::new("Preview").into_any_element())
|
||||
.opacity(if has_completion { 1.0 } else { 0.4 }),
|
||||
)
|
||||
})
|
||||
.child(
|
||||
h_flex()
|
||||
.h_full()
|
||||
.border_l_1()
|
||||
.rounded_r_lg()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.bg(Self::edit_prediction_line_popover_bg_color(cx))
|
||||
.gap_1()
|
||||
.py_1()
|
||||
.px_2()
|
||||
.child(
|
||||
h_flex()
|
||||
.font(theme::ThemeSettings::get_global(cx).buffer_font.clone())
|
||||
.when(is_platform_style_mac, |parent| parent.gap_1())
|
||||
.child(h_flex().children(ui::render_modifiers(
|
||||
&accept_keystroke.modifiers,
|
||||
PlatformStyle::platform(),
|
||||
Some(if !has_completion {
|
||||
Color::Muted
|
||||
} else {
|
||||
Color::Default
|
||||
}),
|
||||
None,
|
||||
false,
|
||||
))),
|
||||
)
|
||||
.child(Label::new("Preview").into_any_element())
|
||||
.opacity(if has_completion { 1.0 } else { 0.4 }),
|
||||
)
|
||||
.into_any(),
|
||||
)
|
||||
}
|
||||
@@ -6220,14 +6051,19 @@ impl Editor {
|
||||
}
|
||||
|
||||
fn render_context_menu_aside(
|
||||
&mut self,
|
||||
&self,
|
||||
style: &EditorStyle,
|
||||
max_size: Size<Pixels>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> Option<AnyElement> {
|
||||
self.context_menu.borrow_mut().as_mut().and_then(|menu| {
|
||||
self.context_menu.borrow().as_ref().and_then(|menu| {
|
||||
if menu.visible() {
|
||||
menu.render_aside(self, max_size, window, cx)
|
||||
menu.render_aside(
|
||||
style,
|
||||
max_size,
|
||||
self.workspace.as_ref().map(|(w, _)| w.clone()),
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -9189,32 +9025,21 @@ impl Editor {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let selections = self
|
||||
.selections
|
||||
.all::<Point>(cx)
|
||||
.into_iter()
|
||||
.map(|selection| selection.start..selection.end)
|
||||
.collect::<Vec<_>>();
|
||||
self.unfold_ranges(&selections, true, true, cx);
|
||||
|
||||
let mut to_unfold = Vec::new();
|
||||
let mut new_selection_ranges = Vec::new();
|
||||
{
|
||||
let selections = self.selections.all::<Point>(cx);
|
||||
let buffer = self.buffer.read(cx).read(cx);
|
||||
for selection in selections {
|
||||
for row in selection.start.row..selection.end.row {
|
||||
let cursor = Point::new(row, buffer.line_len(MultiBufferRow(row)));
|
||||
new_selection_ranges.push(cursor..cursor);
|
||||
}
|
||||
|
||||
let is_multiline_selection = selection.start.row != selection.end.row;
|
||||
// Don't insert last one if it's a multi-line selection ending at the start of a line,
|
||||
// so this action feels more ergonomic when paired with other selection operations
|
||||
let should_skip_last = is_multiline_selection && selection.end.column == 0;
|
||||
if !should_skip_last {
|
||||
new_selection_ranges.push(selection.end..selection.end);
|
||||
}
|
||||
new_selection_ranges.push(selection.end..selection.end);
|
||||
to_unfold.push(selection.start..selection.end);
|
||||
}
|
||||
}
|
||||
self.unfold_ranges(&to_unfold, true, true, cx);
|
||||
self.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
|
||||
s.select_ranges(new_selection_ranges);
|
||||
});
|
||||
@@ -10216,12 +10041,13 @@ impl Editor {
|
||||
return;
|
||||
}
|
||||
let new_rows =
|
||||
cx.background_spawn({
|
||||
let snapshot = display_snapshot.clone();
|
||||
async move {
|
||||
Self::fetch_runnable_ranges(&snapshot, Anchor::min()..Anchor::max())
|
||||
}
|
||||
})
|
||||
cx.background_executor()
|
||||
.spawn({
|
||||
let snapshot = display_snapshot.clone();
|
||||
async move {
|
||||
Self::fetch_runnable_ranges(&snapshot, Anchor::min()..Anchor::max())
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
let rows = Self::runnable_rows(project, display_snapshot, new_rows, cx.clone());
|
||||
@@ -10983,7 +10809,7 @@ impl Editor {
|
||||
HoverLink::InlayHint(lsp_location, server_id) => {
|
||||
let computation =
|
||||
self.compute_target_location(lsp_location, server_id, window, cx);
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let location = computation.await?;
|
||||
Ok(TargetTaskResult::Location(location))
|
||||
})
|
||||
@@ -13782,14 +13608,14 @@ impl Editor {
|
||||
&self,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> BTreeMap<DisplayRow, Background> {
|
||||
) -> BTreeMap<DisplayRow, Hsla> {
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let mut used_highlight_orders = HashMap::default();
|
||||
self.highlighted_rows
|
||||
.iter()
|
||||
.flat_map(|(_, highlighted_rows)| highlighted_rows.iter())
|
||||
.fold(
|
||||
BTreeMap::<DisplayRow, Background>::new(),
|
||||
BTreeMap::<DisplayRow, Hsla>::new(),
|
||||
|mut unique_rows, highlight| {
|
||||
let start = highlight.range.start.to_display_point(&snapshot);
|
||||
let end = highlight.range.end.to_display_point(&snapshot);
|
||||
@@ -13806,7 +13632,7 @@ impl Editor {
|
||||
used_highlight_orders.entry(row).or_insert(highlight.index);
|
||||
if highlight.index >= *used_index {
|
||||
*used_index = highlight.index;
|
||||
unique_rows.insert(DisplayRow(row), highlight.color.into());
|
||||
unique_rows.insert(DisplayRow(row), highlight.color);
|
||||
}
|
||||
}
|
||||
unique_rows
|
||||
@@ -14920,14 +14746,8 @@ impl Editor {
|
||||
if !self.hover_state.focused(window, cx) {
|
||||
hide_hover(self, cx);
|
||||
}
|
||||
if !self
|
||||
.context_menu
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.is_some_and(|context_menu| context_menu.focused(window, cx))
|
||||
{
|
||||
self.hide_context_menu(window, cx);
|
||||
}
|
||||
|
||||
self.hide_context_menu(window, cx);
|
||||
self.discard_inline_completion(false, cx);
|
||||
cx.emit(EditorEvent::Blurred);
|
||||
cx.notify();
|
||||
@@ -15054,33 +14874,6 @@ impl Editor {
|
||||
pub fn wait_for_diff_to_load(&self) -> Option<Shared<Task<()>>> {
|
||||
self.load_diff_task.clone()
|
||||
}
|
||||
|
||||
fn read_selections_from_db(
|
||||
&mut self,
|
||||
item_id: u64,
|
||||
workspace_id: WorkspaceId,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
if !self.is_singleton(cx)
|
||||
|| WorkspaceSettings::get(None, cx).restore_on_startup == RestoreOnStartupBehavior::None
|
||||
{
|
||||
return;
|
||||
}
|
||||
let Some(selections) = DB.get_editor_selections(item_id, workspace_id).log_err() else {
|
||||
return;
|
||||
};
|
||||
if selections.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let snapshot = self.buffer.read(cx).snapshot(cx);
|
||||
self.change_selections(None, window, cx, |s| {
|
||||
s.select_ranges(selections.into_iter().map(|(start, end)| {
|
||||
snapshot.clip_offset(start, Bias::Left)..snapshot.clip_offset(end, Bias::Right)
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn get_uncommitted_diff_for_buffer(
|
||||
@@ -15589,7 +15382,7 @@ fn snippet_completions(
|
||||
let scope = language.map(|language| language.default_scope());
|
||||
let executor = cx.background_executor().clone();
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let classifier = CharClassifier::new(scope).for_completion(true);
|
||||
let mut last_word = chars
|
||||
.chars()
|
||||
@@ -15676,7 +15469,7 @@ fn snippet_completions(
|
||||
documentation: snippet
|
||||
.description
|
||||
.clone()
|
||||
.map(|description| CompletionDocumentation::SingleLine(description.into())),
|
||||
.map(CompletionDocumentation::SingleLine),
|
||||
lsp_completion: lsp::CompletionItem {
|
||||
label: snippet.prefix.first().unwrap().clone(),
|
||||
kind: Some(CompletionItemKind::SNIPPET),
|
||||
@@ -15719,7 +15512,7 @@ impl CompletionProvider for Entity<Project> {
|
||||
self.update(cx, |project, cx| {
|
||||
let snippets = snippet_completions(project, buffer, buffer_position, cx);
|
||||
let project_completions = project.completions(buffer, buffer_position, options, cx);
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut completions = project_completions.await?;
|
||||
let snippets_completions = snippets.await?;
|
||||
completions.extend(snippets_completions);
|
||||
|
||||
@@ -9,8 +9,6 @@ pub struct EditorSettings {
|
||||
pub cursor_blink: bool,
|
||||
pub cursor_shape: Option<CursorShape>,
|
||||
pub current_line_highlight: CurrentLineHighlight,
|
||||
pub selection_highlight: bool,
|
||||
pub selection_highlight_debounce: u64,
|
||||
pub lsp_highlight_debounce: u64,
|
||||
pub hover_popover_enabled: bool,
|
||||
pub hover_popover_delay: u64,
|
||||
@@ -104,7 +102,6 @@ pub struct Toolbar {
|
||||
pub struct Scrollbar {
|
||||
pub show: ShowScrollbar,
|
||||
pub git_diff: bool,
|
||||
pub selected_text: bool,
|
||||
pub selected_symbol: bool,
|
||||
pub search_results: bool,
|
||||
pub diagnostics: ScrollbarDiagnostics,
|
||||
@@ -274,14 +271,6 @@ pub struct EditorSettingsContent {
|
||||
///
|
||||
/// Default: all
|
||||
pub current_line_highlight: Option<CurrentLineHighlight>,
|
||||
/// Whether to highlight all occurrences of the selected text in an editor.
|
||||
///
|
||||
/// Default: true
|
||||
pub selection_highlight: Option<bool>,
|
||||
/// The debounce delay before querying highlights based on the selected text.
|
||||
///
|
||||
/// Default: 75
|
||||
pub selection_highlight_debounce: Option<u64>,
|
||||
/// The debounce delay before querying highlights from the language
|
||||
/// server based on the current cursor location.
|
||||
///
|
||||
@@ -415,10 +404,6 @@ pub struct ScrollbarContent {
|
||||
///
|
||||
/// Default: true
|
||||
pub search_results: Option<bool>,
|
||||
/// Whether to show selected text occurrences in the scrollbar.
|
||||
///
|
||||
/// Default: true
|
||||
pub selected_text: Option<bool>,
|
||||
/// Whether to show selected symbol occurrences in the scrollbar.
|
||||
///
|
||||
/// Default: true
|
||||
|
||||
@@ -4874,76 +4874,13 @@ fn test_select_line(cx: &mut TestAppContext) {
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_split_selection_into_lines(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
#[track_caller]
|
||||
fn test(cx: &mut EditorTestContext, initial_state: &'static str, expected_state: &'static str) {
|
||||
cx.set_state(initial_state);
|
||||
cx.update_editor(|e, window, cx| {
|
||||
e.split_selection_into_lines(&SplitSelectionIntoLines, window, cx)
|
||||
});
|
||||
cx.assert_editor_state(expected_state);
|
||||
}
|
||||
|
||||
// Selection starts and ends at the middle of lines, left-to-right
|
||||
test(
|
||||
&mut cx,
|
||||
"aa\nb«ˇb\ncc\ndd\ne»e\nff",
|
||||
"aa\nbbˇ\nccˇ\nddˇ\neˇe\nff",
|
||||
);
|
||||
// Same thing, right-to-left
|
||||
test(
|
||||
&mut cx,
|
||||
"aa\nb«b\ncc\ndd\neˇ»e\nff",
|
||||
"aa\nbbˇ\nccˇ\nddˇ\neˇe\nff",
|
||||
);
|
||||
|
||||
// Whole buffer, left-to-right, last line *doesn't* end with newline
|
||||
test(
|
||||
&mut cx,
|
||||
"«ˇaa\nbb\ncc\ndd\nee\nff»",
|
||||
"aaˇ\nbbˇ\nccˇ\nddˇ\neeˇ\nffˇ",
|
||||
);
|
||||
// Same thing, right-to-left
|
||||
test(
|
||||
&mut cx,
|
||||
"«aa\nbb\ncc\ndd\nee\nffˇ»",
|
||||
"aaˇ\nbbˇ\nccˇ\nddˇ\neeˇ\nffˇ",
|
||||
);
|
||||
|
||||
// Whole buffer, left-to-right, last line ends with newline
|
||||
test(
|
||||
&mut cx,
|
||||
"«ˇaa\nbb\ncc\ndd\nee\nff\n»",
|
||||
"aaˇ\nbbˇ\nccˇ\nddˇ\neeˇ\nffˇ\n",
|
||||
);
|
||||
// Same thing, right-to-left
|
||||
test(
|
||||
&mut cx,
|
||||
"«aa\nbb\ncc\ndd\nee\nff\nˇ»",
|
||||
"aaˇ\nbbˇ\nccˇ\nddˇ\neeˇ\nffˇ\n",
|
||||
);
|
||||
|
||||
// Starts at the end of a line, ends at the start of another
|
||||
test(
|
||||
&mut cx,
|
||||
"aa\nbb«ˇ\ncc\ndd\nee\n»ff\n",
|
||||
"aa\nbbˇ\nccˇ\nddˇ\neeˇ\nff\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_split_selection_into_lines_interacting_with_creases(cx: &mut TestAppContext) {
|
||||
fn test_split_selection_into_lines(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let editor = cx.add_window(|window, cx| {
|
||||
let buffer = MultiBuffer::build_simple(&sample_text(9, 5, 'a'), cx);
|
||||
build_editor(buffer, window, cx)
|
||||
});
|
||||
|
||||
// setup
|
||||
_ = editor.update(cx, |editor, window, cx| {
|
||||
editor.fold_creases(
|
||||
vec![
|
||||
@@ -4955,13 +4892,6 @@ async fn test_split_selection_into_lines_interacting_with_creases(cx: &mut TestA
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
assert_eq!(
|
||||
editor.display_text(cx),
|
||||
"aa⋯bbb\nccc⋯eeee\nfffff\nggggg\n⋯i"
|
||||
);
|
||||
});
|
||||
|
||||
_ = editor.update(cx, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_display_ranges([
|
||||
DisplayPoint::new(DisplayRow(0), 0)..DisplayPoint::new(DisplayRow(0), 1),
|
||||
@@ -4970,15 +4900,28 @@ async fn test_split_selection_into_lines_interacting_with_creases(cx: &mut TestA
|
||||
DisplayPoint::new(DisplayRow(4), 4)..DisplayPoint::new(DisplayRow(4), 4),
|
||||
])
|
||||
});
|
||||
assert_eq!(
|
||||
editor.display_text(cx),
|
||||
"aa⋯bbb\nccc⋯eeee\nfffff\nggggg\n⋯i"
|
||||
);
|
||||
});
|
||||
|
||||
_ = editor.update(cx, |editor, window, cx| {
|
||||
editor.split_selection_into_lines(&SplitSelectionIntoLines, window, cx);
|
||||
assert_eq!(
|
||||
editor.display_text(cx),
|
||||
"aaaaa\nbbbbb\nccc⋯eeee\nfffff\nggggg\n⋯i"
|
||||
);
|
||||
assert_eq!(
|
||||
editor.selections.display_ranges(cx),
|
||||
[
|
||||
DisplayPoint::new(DisplayRow(0), 1)..DisplayPoint::new(DisplayRow(0), 1),
|
||||
DisplayPoint::new(DisplayRow(0), 2)..DisplayPoint::new(DisplayRow(0), 2),
|
||||
DisplayPoint::new(DisplayRow(2), 0)..DisplayPoint::new(DisplayRow(2), 0),
|
||||
DisplayPoint::new(DisplayRow(5), 4)..DisplayPoint::new(DisplayRow(5), 4)
|
||||
]
|
||||
);
|
||||
});
|
||||
EditorTestContext::for_editor(editor, cx)
|
||||
.await
|
||||
.assert_editor_state("aˇaˇaaa\nbbbbb\nˇccccc\nddddd\neeeee\nfffff\nggggg\nhhhhh\niiiiiˇ");
|
||||
|
||||
_ = editor.update(cx, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
@@ -5000,15 +4943,11 @@ async fn test_split_selection_into_lines_interacting_with_creases(cx: &mut TestA
|
||||
DisplayPoint::new(DisplayRow(3), 5)..DisplayPoint::new(DisplayRow(3), 5),
|
||||
DisplayPoint::new(DisplayRow(4), 5)..DisplayPoint::new(DisplayRow(4), 5),
|
||||
DisplayPoint::new(DisplayRow(5), 5)..DisplayPoint::new(DisplayRow(5), 5),
|
||||
DisplayPoint::new(DisplayRow(6), 5)..DisplayPoint::new(DisplayRow(6), 5)
|
||||
DisplayPoint::new(DisplayRow(6), 5)..DisplayPoint::new(DisplayRow(6), 5),
|
||||
DisplayPoint::new(DisplayRow(7), 0)..DisplayPoint::new(DisplayRow(7), 0)
|
||||
]
|
||||
);
|
||||
});
|
||||
EditorTestContext::for_editor(editor, cx)
|
||||
.await
|
||||
.assert_editor_state(
|
||||
"aaaaaˇ\nbbbbbˇ\ncccccˇ\ndddddˇ\neeeeeˇ\nfffffˇ\ngggggˇ\nhhhhh\niiiii",
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
@@ -5017,6 +4956,7 @@ async fn test_add_selection_above_below(cx: &mut TestAppContext) {
|
||||
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
|
||||
// let buffer = MultiBuffer::build_simple("abc\ndefghi\n\njk\nlmno\n", cx);
|
||||
cx.set_state(indoc!(
|
||||
r#"abc
|
||||
defˇghi
|
||||
@@ -5301,39 +5241,24 @@ async fn test_select_all_matches(cx: &mut gpui::TestAppContext) {
|
||||
|
||||
// Test caret-only selections
|
||||
cx.set_state("abc\nˇabc abc\ndefabc\nabc");
|
||||
|
||||
cx.update_editor(|e, window, cx| e.select_all_matches(&SelectAllMatches, window, cx))
|
||||
.unwrap();
|
||||
cx.assert_editor_state("«abcˇ»\n«abcˇ» «abcˇ»\ndefabc\n«abcˇ»");
|
||||
|
||||
// Test left-to-right selections
|
||||
cx.set_state("abc\n«abcˇ»\nabc");
|
||||
|
||||
cx.update_editor(|e, window, cx| e.select_all_matches(&SelectAllMatches, window, cx))
|
||||
.unwrap();
|
||||
cx.assert_editor_state("«abcˇ»\n«abcˇ»\n«abcˇ»");
|
||||
|
||||
// Test right-to-left selections
|
||||
cx.set_state("abc\n«ˇabc»\nabc");
|
||||
|
||||
cx.update_editor(|e, window, cx| e.select_all_matches(&SelectAllMatches, window, cx))
|
||||
.unwrap();
|
||||
cx.assert_editor_state("«ˇabc»\n«ˇabc»\n«ˇabc»");
|
||||
|
||||
// Test selecting whitespace with caret selection
|
||||
cx.set_state("abc\nˇ abc\nabc");
|
||||
cx.update_editor(|e, window, cx| e.select_all_matches(&SelectAllMatches, window, cx))
|
||||
.unwrap();
|
||||
cx.assert_editor_state("abc\n« ˇ»abc\nabc");
|
||||
|
||||
// Test selecting whitespace with left-to-right selection
|
||||
cx.set_state("abc\n«ˇ »abc\nabc");
|
||||
cx.update_editor(|e, window, cx| e.select_all_matches(&SelectAllMatches, window, cx))
|
||||
.unwrap();
|
||||
cx.assert_editor_state("abc\n«ˇ »abc\nabc");
|
||||
|
||||
// Test no matches with right-to-left selection
|
||||
cx.set_state("abc\n« ˇ»abc\nabc");
|
||||
cx.update_editor(|e, window, cx| e.select_all_matches(&SelectAllMatches, window, cx))
|
||||
.unwrap();
|
||||
cx.assert_editor_state("abc\n« ˇ»abc\nabc");
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
@@ -6283,7 +6208,7 @@ async fn test_autoclose_with_embedded_language(cx: &mut gpui::TestAppContext) {
|
||||
autoclose_before: "})]>".into(),
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_html::LANGUAGE.into()),
|
||||
Some(tree_sitter_html::language()),
|
||||
)
|
||||
.with_injection_query(
|
||||
r#"
|
||||
@@ -9685,7 +9610,7 @@ async fn test_toggle_block_comment(cx: &mut gpui::TestAppContext) {
|
||||
block_comment: Some(("<!-- ".into(), " -->".into())),
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_html::LANGUAGE.into()),
|
||||
Some(tree_sitter_html::language()),
|
||||
)
|
||||
.with_injection_query(
|
||||
r#"
|
||||
|
||||
@@ -20,10 +20,9 @@ use crate::{
|
||||
EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts, FocusedBlock, GoToHunk,
|
||||
GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor, InlineCompletion,
|
||||
JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, RevertSelectedHunks, RowExt,
|
||||
RowRangeExt, SelectPhase, SelectedTextHighlight, Selection, SoftWrap, StickyHeaderExcerpt,
|
||||
ToPoint, ToggleFold, ToggleStagedSelectedDiffHunks, COLUMNAR_SELECTION_MODIFIERS,
|
||||
CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT, GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN,
|
||||
MULTI_BUFFER_EXCERPT_HEADER_HEIGHT,
|
||||
RowRangeExt, SelectPhase, Selection, SoftWrap, StickyHeaderExcerpt, ToPoint, ToggleFold,
|
||||
ToggleStagedSelectedDiffHunks, CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT,
|
||||
GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT,
|
||||
};
|
||||
use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus};
|
||||
use client::ParticipantIndex;
|
||||
@@ -32,7 +31,7 @@ use file_icons::FileIcons;
|
||||
use git::{blame::BlameEntry, Oid};
|
||||
use gpui::{
|
||||
anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, pattern_slash,
|
||||
point, px, quad, relative, size, svg, transparent_black, Action, AnyElement, App,
|
||||
point, px, quad, relative, size, solid_color, svg, transparent_black, Action, AnyElement, App,
|
||||
AvailableSpace, Axis, Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners,
|
||||
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable, FontId,
|
||||
GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, Keystroke, Length,
|
||||
@@ -80,16 +79,19 @@ use workspace::{item::Item, notifications::NotifyTaskExt, Workspace};
|
||||
|
||||
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 7.;
|
||||
|
||||
/// Note that for a "modified" MultiBufferDiffHunk, there are two DisplayDiffHunks,
|
||||
/// one for the deleted portion and one for the added portion.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum DisplayDiffHunk {
|
||||
Folded {
|
||||
display_row: DisplayRow,
|
||||
},
|
||||
Unfolded {
|
||||
diff_base_byte_range: Range<usize>,
|
||||
display_row_range: Range<DisplayRow>,
|
||||
multi_buffer_range: Range<Anchor>,
|
||||
status: DiffHunkStatus,
|
||||
expanded: bool,
|
||||
is_primary: bool,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -104,7 +106,7 @@ struct SelectionLayout {
|
||||
}
|
||||
|
||||
impl SelectionLayout {
|
||||
fn new<T: ToPoint + ToDisplayPoint + Clone>(
|
||||
fn new<T: multi_buffer::ToPoint + ToDisplayPoint + Clone>(
|
||||
selection: Selection<T>,
|
||||
line_mode: bool,
|
||||
cursor_shape: CursorShape,
|
||||
@@ -515,7 +517,6 @@ impl EditorElement {
|
||||
if editor.hover_state.focused(window, cx) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.handle_modifiers_changed(event.modifiers, &position_map, window, cx);
|
||||
})
|
||||
}
|
||||
@@ -595,7 +596,7 @@ impl EditorElement {
|
||||
|
||||
let point_for_position = position_map.point_for_position(event.position);
|
||||
let position = point_for_position.previous_valid;
|
||||
if modifiers == COLUMNAR_SELECTION_MODIFIERS {
|
||||
if modifiers.shift && modifiers.alt {
|
||||
editor.select(
|
||||
SelectPhase::BeginColumnar {
|
||||
position,
|
||||
@@ -931,6 +932,7 @@ impl EditorElement {
|
||||
cx.notify()
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_selections(
|
||||
&self,
|
||||
start_anchor: Anchor,
|
||||
@@ -1102,6 +1104,7 @@ impl EditorElement {
|
||||
cursors
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_visible_cursors(
|
||||
&self,
|
||||
snapshot: &EditorSnapshot,
|
||||
@@ -1293,9 +1296,6 @@ impl EditorElement {
|
||||
// Buffer Search Results
|
||||
(is_singleton && scrollbar_settings.search_results && editor.has_background_highlights::<BufferSearchHighlights>())
|
||||
||
|
||||
// Selected Text Occurrences
|
||||
(is_singleton && scrollbar_settings.selected_text && editor.has_background_highlights::<SelectedTextHighlight>())
|
||||
||
|
||||
// Selected Symbol Occurrences
|
||||
(is_singleton && scrollbar_settings.selected_symbol && (editor.has_background_highlights::<DocumentHighlightRead>() || editor.has_background_highlights::<DocumentHighlightWrite>()))
|
||||
||
|
||||
@@ -1451,6 +1451,7 @@ impl EditorElement {
|
||||
axis_pair(horizontal_scrollbar, vertical_scrollbar)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn prepaint_crease_toggles(
|
||||
&self,
|
||||
crease_toggles: &mut [Option<AnyElement>],
|
||||
@@ -1485,6 +1486,7 @@ impl EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn prepaint_crease_trailers(
|
||||
&self,
|
||||
trailers: Vec<Option<AnyElement>>,
|
||||
@@ -1557,30 +1559,100 @@ impl EditorElement {
|
||||
let hunk_end_point = Point::new(hunk.row_range.end.0, 0);
|
||||
|
||||
let hunk_display_start = snapshot.point_to_display_point(hunk_start_point, Bias::Left);
|
||||
let hunk_added_start_at =
|
||||
Anchor::in_buffer(hunk.excerpt_id, hunk.buffer_id, hunk.buffer_range.start);
|
||||
let hunk_deleted_to_added_break = snapshot.point_to_display_point(
|
||||
hunk_added_start_at.to_point(&snapshot.buffer_snapshot),
|
||||
Bias::Right,
|
||||
);
|
||||
|
||||
let hunk_display_end = snapshot.point_to_display_point(hunk_end_point, Bias::Right);
|
||||
|
||||
let display_hunk = if hunk_display_start.column() != 0 {
|
||||
DisplayDiffHunk::Folded {
|
||||
display_row: hunk_display_start.row(),
|
||||
}
|
||||
if hunk_display_start.column() != 0 {
|
||||
display_hunks.push((
|
||||
DisplayDiffHunk::Folded {
|
||||
display_row: hunk_display_start.row(),
|
||||
},
|
||||
None,
|
||||
));
|
||||
} else {
|
||||
let mut end_row = hunk_display_end.row();
|
||||
if hunk_display_end.column() > 0 {
|
||||
end_row.0 += 1;
|
||||
}
|
||||
DisplayDiffHunk::Unfolded {
|
||||
status: hunk.status(),
|
||||
diff_base_byte_range: hunk.diff_base_byte_range,
|
||||
display_row_range: hunk_display_start.row()..end_row,
|
||||
multi_buffer_range: Anchor::range_in_buffer(
|
||||
hunk.excerpt_id,
|
||||
hunk.buffer_id,
|
||||
hunk.buffer_range,
|
||||
),
|
||||
let deleted_count = snapshot
|
||||
.buffer_snapshot
|
||||
.row_infos(hunk.row_range.start)
|
||||
.take(hunk.row_range.end.0 as usize - hunk.row_range.start.0 as usize)
|
||||
.take_while(|row_info| {
|
||||
matches!(row_info.diff_status, Some(DiffHunkStatus::Removed(_)))
|
||||
})
|
||||
.count();
|
||||
let has_added = snapshot
|
||||
.buffer_snapshot
|
||||
.row_infos(hunk.row_range.start)
|
||||
.take(hunk.row_range.end.0 as usize - hunk.row_range.start.0 as usize)
|
||||
.any(|row_info| matches!(row_info.diff_status, Some(DiffHunkStatus::Added(_))));
|
||||
let expanded = deleted_count > 0 || has_added;
|
||||
if deleted_count > 0 && has_added {
|
||||
display_hunks.push((
|
||||
DisplayDiffHunk::Unfolded {
|
||||
status: DiffHunkStatus::Removed(hunk.secondary_status),
|
||||
display_row_range: hunk_display_start.row()
|
||||
..hunk_display_start.row() + DisplayRow(deleted_count as u32),
|
||||
multi_buffer_range: Anchor::range_in_buffer(
|
||||
hunk.excerpt_id,
|
||||
hunk.buffer_id,
|
||||
hunk.buffer_range.clone(),
|
||||
),
|
||||
expanded,
|
||||
is_primary: true,
|
||||
},
|
||||
None,
|
||||
));
|
||||
display_hunks.push((
|
||||
DisplayDiffHunk::Unfolded {
|
||||
status: DiffHunkStatus::Added(hunk.secondary_status),
|
||||
display_row_range: hunk_display_start.row()
|
||||
+ DisplayRow(deleted_count as u32)
|
||||
..end_row,
|
||||
multi_buffer_range: Anchor::range_in_buffer(
|
||||
hunk.excerpt_id,
|
||||
hunk.buffer_id,
|
||||
hunk.buffer_range,
|
||||
),
|
||||
expanded,
|
||||
is_primary: false,
|
||||
},
|
||||
None,
|
||||
));
|
||||
} else {
|
||||
let status = if expanded && matches!(hunk.status(), DiffHunkStatus::Modified(_))
|
||||
{
|
||||
if hunk_display_start.row() < hunk_deleted_to_added_break.row() {
|
||||
DiffHunkStatus::Removed(hunk.secondary_status)
|
||||
} else {
|
||||
DiffHunkStatus::Added(hunk.secondary_status)
|
||||
}
|
||||
} else {
|
||||
hunk.status()
|
||||
};
|
||||
display_hunks.push((
|
||||
DisplayDiffHunk::Unfolded {
|
||||
status,
|
||||
display_row_range: hunk_display_start.row()..end_row,
|
||||
multi_buffer_range: Anchor::range_in_buffer(
|
||||
hunk.excerpt_id,
|
||||
hunk.buffer_id,
|
||||
hunk.buffer_range,
|
||||
),
|
||||
expanded,
|
||||
is_primary: true,
|
||||
},
|
||||
None,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
display_hunks.push((display_hunk, None));
|
||||
}
|
||||
|
||||
let git_gutter_setting = ProjectSettings::get_global(cx)
|
||||
@@ -1600,6 +1672,7 @@ impl EditorElement {
|
||||
display_hunks
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_inline_blame(
|
||||
&self,
|
||||
display_row: DisplayRow,
|
||||
@@ -1686,6 +1759,7 @@ impl EditorElement {
|
||||
Some(element)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_blame_entries(
|
||||
&self,
|
||||
buffer_rows: &[RowInfo],
|
||||
@@ -1754,6 +1828,7 @@ impl EditorElement {
|
||||
Some(shaped_lines)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_indent_guides(
|
||||
&self,
|
||||
content_origin: gpui::Point<Pixels>,
|
||||
@@ -1871,6 +1946,7 @@ impl EditorElement {
|
||||
(offset_y, length)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_run_indicators(
|
||||
&self,
|
||||
line_height: Pixels,
|
||||
@@ -1914,7 +1990,8 @@ impl EditorElement {
|
||||
if tasks.offset.0 < offset_range_start || tasks.offset.0 >= offset_range_end {
|
||||
return None;
|
||||
}
|
||||
let multibuffer_point = tasks.offset.0.to_point(&snapshot.buffer_snapshot);
|
||||
let multibuffer_point =
|
||||
multi_buffer::ToPoint::to_point(&tasks.offset.0, &snapshot.buffer_snapshot);
|
||||
let multibuffer_row = MultiBufferRow(multibuffer_point.row);
|
||||
let buffer_folded = snapshot
|
||||
.buffer_snapshot
|
||||
@@ -1963,6 +2040,7 @@ impl EditorElement {
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_code_actions_indicator(
|
||||
&self,
|
||||
line_height: Pixels,
|
||||
@@ -2061,6 +2139,7 @@ impl EditorElement {
|
||||
relative_rows
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_line_numbers(
|
||||
&self,
|
||||
gutter_hitbox: Option<&Hitbox>,
|
||||
@@ -2273,6 +2352,7 @@ impl EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn prepaint_lines(
|
||||
&self,
|
||||
start_row: DisplayRow,
|
||||
@@ -2299,6 +2379,7 @@ impl EditorElement {
|
||||
line_elements
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn render_block(
|
||||
&self,
|
||||
block: &Block,
|
||||
@@ -2760,6 +2841,7 @@ impl EditorElement {
|
||||
}))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn render_blocks(
|
||||
&self,
|
||||
rows: Range<DisplayRow>,
|
||||
@@ -2944,6 +3026,7 @@ impl EditorElement {
|
||||
|
||||
/// Returns true if any of the blocks changed size since the previous frame. This will trigger
|
||||
/// a restart of rendering for the editor based on the new sizes.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_blocks(
|
||||
&self,
|
||||
blocks: &mut Vec<BlockLayout>,
|
||||
@@ -2987,6 +3070,7 @@ impl EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_sticky_buffer_header(
|
||||
&self,
|
||||
StickyHeaderExcerpt {
|
||||
@@ -3061,6 +3145,7 @@ impl EditorElement {
|
||||
header
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_cursor_popovers(
|
||||
&self,
|
||||
line_height: Pixels,
|
||||
@@ -3170,7 +3255,7 @@ impl EditorElement {
|
||||
max_width,
|
||||
cursor_point,
|
||||
style,
|
||||
accept_binding.keystroke(),
|
||||
accept_binding.keystroke()?,
|
||||
window,
|
||||
cx,
|
||||
)?;
|
||||
@@ -3249,6 +3334,7 @@ impl EditorElement {
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_gutter_menu(
|
||||
&self,
|
||||
line_height: Pixels,
|
||||
@@ -3301,6 +3387,7 @@ impl EditorElement {
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_popovers_above_or_below_line(
|
||||
&self,
|
||||
target_position: gpui::Point<Pixels>,
|
||||
@@ -3405,6 +3492,7 @@ impl EditorElement {
|
||||
Some((laid_out_popovers, y_flipped))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_context_menu_aside(
|
||||
&self,
|
||||
y_flipped: bool,
|
||||
@@ -3426,11 +3514,9 @@ impl EditorElement {
|
||||
available_within_viewport.right - px(1.),
|
||||
MENU_ASIDE_MAX_WIDTH,
|
||||
);
|
||||
let Some(mut aside) = self.render_context_menu_aside(
|
||||
size(max_width, max_height - POPOVER_Y_PADDING),
|
||||
window,
|
||||
cx,
|
||||
) else {
|
||||
let Some(mut aside) =
|
||||
self.render_context_menu_aside(size(max_width, max_height - POPOVER_Y_PADDING), cx)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
aside.layout_as_root(AvailableSpace::min_size(), window, cx);
|
||||
@@ -3452,7 +3538,7 @@ impl EditorElement {
|
||||
),
|
||||
) - POPOVER_Y_PADDING,
|
||||
);
|
||||
let Some(mut aside) = self.render_context_menu_aside(max_size, window, cx) else {
|
||||
let Some(mut aside) = self.render_context_menu_aside(max_size, cx) else {
|
||||
return;
|
||||
};
|
||||
let actual_size = aside.layout_as_root(AvailableSpace::min_size(), window, cx);
|
||||
@@ -3493,7 +3579,7 @@ impl EditorElement {
|
||||
|
||||
// Skip drawing if it doesn't fit anywhere.
|
||||
if let Some((aside, position)) = positioned_aside {
|
||||
window.defer_draw(aside, position, 2);
|
||||
window.defer_draw(aside, position, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3514,18 +3600,19 @@ impl EditorElement {
|
||||
fn render_context_menu_aside(
|
||||
&self,
|
||||
max_size: Size<Pixels>,
|
||||
window: &mut Window,
|
||||
|
||||
cx: &mut App,
|
||||
) -> Option<AnyElement> {
|
||||
if max_size.width < px(100.) || max_size.height < px(12.) {
|
||||
None
|
||||
} else {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.render_context_menu_aside(max_size, window, cx)
|
||||
editor.render_context_menu_aside(&self.style, max_size, cx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_edit_prediction_popover(
|
||||
&self,
|
||||
text_bounds: &Bounds<Pixels>,
|
||||
@@ -3982,6 +4069,7 @@ impl EditorElement {
|
||||
Some(element)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_hover_popovers(
|
||||
&self,
|
||||
snapshot: &EditorSnapshot,
|
||||
@@ -4098,6 +4186,7 @@ impl EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_diff_hunk_controls(
|
||||
&self,
|
||||
row_range: Range<DisplayRow>,
|
||||
@@ -4121,14 +4210,29 @@ impl EditorElement {
|
||||
newest_cursor_position,
|
||||
];
|
||||
|
||||
for (hunk, _) in display_hunks {
|
||||
let mut display_hunks = display_hunks.iter().peekable();
|
||||
while let Some((hunk, _)) = display_hunks.next() {
|
||||
if let DisplayDiffHunk::Unfolded {
|
||||
display_row_range,
|
||||
multi_buffer_range,
|
||||
status,
|
||||
is_primary: true,
|
||||
..
|
||||
} = &hunk
|
||||
{
|
||||
let mut display_row_range = display_row_range.clone();
|
||||
if let Some((
|
||||
DisplayDiffHunk::Unfolded {
|
||||
display_row_range: secondary_display_row_range,
|
||||
is_primary: false,
|
||||
..
|
||||
},
|
||||
_,
|
||||
)) = display_hunks.peek()
|
||||
{
|
||||
display_row_range.end = secondary_display_row_range.end;
|
||||
}
|
||||
|
||||
if display_row_range.start < row_range.start
|
||||
|| display_row_range.start >= row_range.end
|
||||
{
|
||||
@@ -4178,6 +4282,7 @@ impl EditorElement {
|
||||
controls
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn layout_signature_help(
|
||||
&self,
|
||||
hitbox: &Hitbox,
|
||||
@@ -4326,7 +4431,7 @@ impl EditorElement {
|
||||
window.paint_quad(fill(Bounds { origin, size }, color));
|
||||
};
|
||||
|
||||
let mut current_paint: Option<(gpui::Background, Range<DisplayRow>)> = None;
|
||||
let mut current_paint: Option<(Hsla, Range<DisplayRow>)> = None;
|
||||
for (&new_row, &new_background) in &layout.highlighted_rows {
|
||||
match &mut current_paint {
|
||||
Some((current_background, current_range)) => {
|
||||
@@ -4524,11 +4629,17 @@ impl EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
fn paint_diff_hunks(layout: &mut EditorLayout, window: &mut Window, cx: &mut App) {
|
||||
fn paint_diff_hunk_gutter_indicators(
|
||||
layout: &mut EditorLayout,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
if layout.display_hunks.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let corners = Corners::all(px(0.));
|
||||
|
||||
let line_height = layout.position_map.line_height;
|
||||
window.paint_layer(layout.gutter_hitbox.bounds, |window| {
|
||||
for (hunk, hitbox) in &layout.display_hunks {
|
||||
@@ -4542,36 +4653,41 @@ impl EditorElement {
|
||||
);
|
||||
Some((
|
||||
hunk_bounds,
|
||||
cx.theme().status().modified,
|
||||
Corners::all(px(0.)),
|
||||
cx.theme().colors().version_control_modified.opacity(0.7),
|
||||
corners,
|
||||
&DiffHunkSecondaryStatus::None,
|
||||
false,
|
||||
))
|
||||
}
|
||||
DisplayDiffHunk::Unfolded {
|
||||
status,
|
||||
display_row_range,
|
||||
expanded,
|
||||
..
|
||||
} => hitbox.as_ref().map(|hunk_hitbox| match status {
|
||||
DiffHunkStatus::Added(secondary_status) => (
|
||||
hunk_hitbox.bounds,
|
||||
cx.theme().status().created,
|
||||
Corners::all(px(0.)),
|
||||
cx.theme().colors().version_control_added.opacity(0.7),
|
||||
corners,
|
||||
secondary_status,
|
||||
*expanded,
|
||||
),
|
||||
DiffHunkStatus::Modified(secondary_status) => (
|
||||
hunk_hitbox.bounds,
|
||||
cx.theme().status().modified,
|
||||
Corners::all(px(0.)),
|
||||
cx.theme().colors().version_control_modified.opacity(0.7),
|
||||
corners,
|
||||
secondary_status,
|
||||
*expanded,
|
||||
),
|
||||
DiffHunkStatus::Removed(secondary_status)
|
||||
if !display_row_range.is_empty() =>
|
||||
{
|
||||
(
|
||||
hunk_hitbox.bounds,
|
||||
cx.theme().status().deleted,
|
||||
Corners::all(px(0.)),
|
||||
cx.theme().colors().version_control_deleted.opacity(0.7),
|
||||
corners,
|
||||
secondary_status,
|
||||
*expanded,
|
||||
)
|
||||
}
|
||||
DiffHunkStatus::Removed(secondary_status) => (
|
||||
@@ -4582,23 +4698,33 @@ impl EditorElement {
|
||||
),
|
||||
size(hunk_hitbox.size.width * px(2.), hunk_hitbox.size.height),
|
||||
),
|
||||
cx.theme().status().deleted,
|
||||
cx.theme().colors().version_control_deleted.opacity(0.7),
|
||||
Corners::all(1. * line_height),
|
||||
secondary_status,
|
||||
*expanded,
|
||||
),
|
||||
}),
|
||||
};
|
||||
|
||||
if let Some((hunk_bounds, mut background_color, corner_radii, secondary_status)) =
|
||||
hunk_to_paint
|
||||
if let Some((
|
||||
hunk_bounds,
|
||||
background_color,
|
||||
corner_radii,
|
||||
secondary_status,
|
||||
expanded,
|
||||
)) = hunk_to_paint
|
||||
{
|
||||
if *secondary_status != DiffHunkSecondaryStatus::None {
|
||||
background_color.a *= 0.6;
|
||||
}
|
||||
let background =
|
||||
if *secondary_status != DiffHunkSecondaryStatus::None && expanded {
|
||||
pattern_slash(background_color, line_height.0 / 2.5)
|
||||
} else {
|
||||
solid_color(background_color)
|
||||
};
|
||||
|
||||
window.paint_quad(quad(
|
||||
hunk_bounds,
|
||||
corner_radii,
|
||||
background_color,
|
||||
background,
|
||||
Edges::default(),
|
||||
transparent_black(),
|
||||
));
|
||||
@@ -4726,7 +4852,7 @@ impl EditorElement {
|
||||
)
|
||||
});
|
||||
if show_git_gutter {
|
||||
Self::paint_diff_hunks(layout, window, cx)
|
||||
Self::paint_diff_hunk_gutter_indicators(layout, window, cx)
|
||||
}
|
||||
|
||||
let highlight_width = 0.275 * layout.position_map.line_height;
|
||||
@@ -5266,7 +5392,8 @@ impl EditorElement {
|
||||
Some(cx.spawn_in(window, |editor, mut cx| async move {
|
||||
let scrollbar_size = scrollbar_layout.hitbox.size;
|
||||
let scrollbar_markers = cx
|
||||
.background_spawn(async move {
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
let max_point = snapshot.display_snapshot.buffer_snapshot.max_point();
|
||||
let mut marker_quads = Vec::new();
|
||||
if scrollbar_settings.git_diff {
|
||||
@@ -5284,9 +5411,15 @@ impl EditorElement {
|
||||
end_display_row.0 -= 1;
|
||||
}
|
||||
let color = match &hunk.status() {
|
||||
DiffHunkStatus::Added(_) => theme.status().created,
|
||||
DiffHunkStatus::Modified(_) => theme.status().modified,
|
||||
DiffHunkStatus::Removed(_) => theme.status().deleted,
|
||||
DiffHunkStatus::Added(_) => {
|
||||
theme.colors().version_control_added
|
||||
}
|
||||
DiffHunkStatus::Modified(_) => {
|
||||
theme.colors().version_control_modified
|
||||
}
|
||||
DiffHunkStatus::Removed(_) => {
|
||||
theme.colors().version_control_deleted
|
||||
}
|
||||
};
|
||||
ColoredRange {
|
||||
start: start_display_row,
|
||||
@@ -5306,14 +5439,11 @@ impl EditorElement {
|
||||
{
|
||||
let is_search_highlights = *background_highlight_id
|
||||
== TypeId::of::<BufferSearchHighlights>();
|
||||
let is_text_highlights = *background_highlight_id
|
||||
== TypeId::of::<SelectedTextHighlight>();
|
||||
let is_symbol_occurrences = *background_highlight_id
|
||||
== TypeId::of::<DocumentHighlightRead>()
|
||||
|| *background_highlight_id
|
||||
== TypeId::of::<DocumentHighlightWrite>();
|
||||
if (is_search_highlights && scrollbar_settings.search_results)
|
||||
|| (is_text_highlights && scrollbar_settings.selected_text)
|
||||
|| (is_symbol_occurrences && scrollbar_settings.selected_symbol)
|
||||
{
|
||||
let mut color = theme.status().info;
|
||||
@@ -5416,6 +5546,7 @@ impl EditorElement {
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn paint_highlighted_range(
|
||||
&self,
|
||||
range: Range<DisplayPoint>,
|
||||
@@ -5830,6 +5961,7 @@ impl AcceptEditPredictionBinding {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn prepaint_gutter_button(
|
||||
button: IconButton,
|
||||
row: DisplayRow,
|
||||
@@ -6069,6 +6201,7 @@ impl fmt::Debug for LineFragment {
|
||||
}
|
||||
|
||||
impl LineWithInvisibles {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn from_chunks<'a>(
|
||||
chunks: impl Iterator<Item = HighlightedChunk<'a>>,
|
||||
editor_style: &EditorStyle,
|
||||
@@ -6273,6 +6406,7 @@ impl LineWithInvisibles {
|
||||
layouts
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn prepaint(
|
||||
&mut self,
|
||||
line_height: Pixels,
|
||||
@@ -6307,6 +6441,7 @@ impl LineWithInvisibles {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw(
|
||||
&self,
|
||||
layout: &EditorLayout,
|
||||
@@ -6350,6 +6485,7 @@ impl LineWithInvisibles {
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_invisibles(
|
||||
&self,
|
||||
selection_ranges: &[Range<DisplayPoint>],
|
||||
@@ -6864,39 +7000,17 @@ impl Element for EditorElement {
|
||||
)
|
||||
};
|
||||
|
||||
let (mut highlighted_rows, distinguish_unstaged_hunks) =
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
(
|
||||
editor.highlighted_display_rows(window, cx),
|
||||
editor.distinguish_unstaged_diff_hunks,
|
||||
)
|
||||
});
|
||||
let mut highlighted_rows = self
|
||||
.editor
|
||||
.update(cx, |editor, cx| editor.highlighted_display_rows(window, cx));
|
||||
|
||||
for (ix, row_info) in row_infos.iter().enumerate() {
|
||||
let background = match row_info.diff_status {
|
||||
Some(DiffHunkStatus::Added(secondary_status)) => {
|
||||
let color = style.status.created_background;
|
||||
match secondary_status {
|
||||
DiffHunkSecondaryStatus::HasSecondaryHunk
|
||||
| DiffHunkSecondaryStatus::OverlapsWithSecondaryHunk
|
||||
if distinguish_unstaged_hunks =>
|
||||
{
|
||||
pattern_slash(color, line_height.0 / 4.0)
|
||||
}
|
||||
_ => color.into(),
|
||||
}
|
||||
Some(DiffHunkStatus::Added(_)) => {
|
||||
cx.theme().colors().version_control_added_background
|
||||
}
|
||||
Some(DiffHunkStatus::Removed(secondary_status)) => {
|
||||
let color = style.status.deleted_background;
|
||||
match secondary_status {
|
||||
DiffHunkSecondaryStatus::HasSecondaryHunk
|
||||
| DiffHunkSecondaryStatus::OverlapsWithSecondaryHunk
|
||||
if distinguish_unstaged_hunks =>
|
||||
{
|
||||
pattern_slash(color, line_height.0 / 4.0)
|
||||
}
|
||||
_ => color.into(),
|
||||
}
|
||||
Some(DiffHunkStatus::Removed(_)) => {
|
||||
cx.theme().colors().version_control_deleted_background
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
@@ -7679,6 +7793,7 @@ struct ScrollbarRangeData {
|
||||
}
|
||||
|
||||
impl ScrollbarRangeData {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
scrollbar_bounds: Bounds<Pixels>,
|
||||
letter_size: Size<Pixels>,
|
||||
@@ -7743,7 +7858,7 @@ pub struct EditorLayout {
|
||||
indent_guides: Option<Vec<IndentGuideLayout>>,
|
||||
visible_display_row_range: Range<DisplayRow>,
|
||||
active_rows: BTreeMap<DisplayRow, bool>,
|
||||
highlighted_rows: BTreeMap<DisplayRow, gpui::Background>,
|
||||
highlighted_rows: BTreeMap<DisplayRow, Hsla>,
|
||||
line_elements: SmallVec<[AnyElement; 1]>,
|
||||
line_numbers: Arc<HashMap<MultiBufferRow, LineNumberLayout>>,
|
||||
display_hunks: Vec<(DisplayDiffHunk, Option<Hitbox>)>,
|
||||
|
||||
@@ -4,7 +4,7 @@ use git::{
|
||||
blame::{Blame, BlameEntry},
|
||||
parse_git_remote_url, GitHostingProvider, GitHostingProviderRegistry, Oid,
|
||||
};
|
||||
use gpui::{App, AppContext as _, Context, Entity, Subscription, Task};
|
||||
use gpui::{App, Context, Entity, Subscription, Task};
|
||||
use http_client::HttpClient;
|
||||
use language::{markdown, Bias, Buffer, BufferSnapshot, Edit, LanguageRegistry, ParsedMarkdown};
|
||||
use multi_buffer::RowInfo;
|
||||
@@ -360,7 +360,8 @@ impl GitBlame {
|
||||
|
||||
self.task = cx.spawn(|this, mut cx| async move {
|
||||
let result = cx
|
||||
.background_spawn({
|
||||
.background_executor()
|
||||
.spawn({
|
||||
let snapshot = snapshot.clone();
|
||||
async move {
|
||||
let Some(Blame {
|
||||
@@ -548,7 +549,7 @@ async fn parse_markdown(text: &str, language_registry: &Arc<LanguageRegistry>) -
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use gpui::Context;
|
||||
use gpui::{AppContext as _, Context};
|
||||
use language::{Point, Rope};
|
||||
use project::FakeFs;
|
||||
use rand::prelude::*;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
display_map::{invisibles::is_invisible, InlayOffset, ToDisplayPoint},
|
||||
hover_links::{InlayHighlight, RangeInEditor},
|
||||
scroll::{Autoscroll, ScrollAmount},
|
||||
scroll::ScrollAmount,
|
||||
Anchor, AnchorRangeExt, DisplayPoint, DisplayRow, Editor, EditorSettings, EditorSnapshot,
|
||||
Hover,
|
||||
};
|
||||
@@ -18,14 +18,12 @@ use markdown::{Markdown, MarkdownStyle};
|
||||
use multi_buffer::ToOffset;
|
||||
use project::{HoverBlock, HoverBlockKind, InlayHintLabelPart};
|
||||
use settings::Settings;
|
||||
use std::rc::Rc;
|
||||
use std::{borrow::Cow, cell::RefCell};
|
||||
use std::{ops::Range, sync::Arc, time::Duration};
|
||||
use std::{path::PathBuf, rc::Rc};
|
||||
use theme::ThemeSettings;
|
||||
use ui::{prelude::*, theme_is_transparent, Scrollbar, ScrollbarState};
|
||||
use url::Url;
|
||||
use util::TryFutureExt;
|
||||
use workspace::Workspace;
|
||||
pub const HOVER_REQUEST_DELAY_MILLIS: u64 = 200;
|
||||
|
||||
pub const MIN_POPOVER_CHARACTER_WIDTH: f32 = 20.;
|
||||
@@ -358,15 +356,7 @@ fn show_hover(
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
Markdown::new_text(
|
||||
SharedString::new(text),
|
||||
markdown_style.clone(),
|
||||
None,
|
||||
None,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.open_url(open_markdown_url)
|
||||
Markdown::new_text(text, markdown_style.clone(), None, None, window, cx)
|
||||
})
|
||||
.ok();
|
||||
|
||||
@@ -568,122 +558,69 @@ async fn parse_blocks(
|
||||
|
||||
let rendered_block = cx
|
||||
.new_window_entity(|window, cx| {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let ui_font_family = settings.ui_font.family.clone();
|
||||
let ui_font_fallbacks = settings.ui_font.fallbacks.clone();
|
||||
let buffer_font_family = settings.buffer_font.family.clone();
|
||||
let buffer_font_fallbacks = settings.buffer_font.fallbacks.clone();
|
||||
|
||||
let mut base_text_style = window.text_style();
|
||||
base_text_style.refine(&TextStyleRefinement {
|
||||
font_family: Some(ui_font_family.clone()),
|
||||
font_fallbacks: ui_font_fallbacks,
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let markdown_style = MarkdownStyle {
|
||||
base_text_style,
|
||||
code_block: StyleRefinement::default().my(rems(1.)).font_buffer(cx),
|
||||
inline_code: TextStyleRefinement {
|
||||
background_color: Some(cx.theme().colors().background),
|
||||
font_family: Some(buffer_font_family),
|
||||
font_fallbacks: buffer_font_fallbacks,
|
||||
..Default::default()
|
||||
},
|
||||
rule_color: cx.theme().colors().border,
|
||||
block_quote_border_color: Color::Muted.color(cx),
|
||||
block_quote: TextStyleRefinement {
|
||||
color: Some(Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
},
|
||||
link: TextStyleRefinement {
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: { cx.theme().players().local().selection },
|
||||
|
||||
heading: StyleRefinement::default()
|
||||
.font_weight(FontWeight::BOLD)
|
||||
.text_base()
|
||||
.mt(rems(1.))
|
||||
.mb_0(),
|
||||
};
|
||||
|
||||
Markdown::new(
|
||||
combined_text.into(),
|
||||
hover_markdown_style(window, cx),
|
||||
combined_text,
|
||||
markdown_style.clone(),
|
||||
Some(language_registry.clone()),
|
||||
fallback_language_name,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.copy_code_block_buttons(false)
|
||||
.open_url(open_markdown_url)
|
||||
})
|
||||
.ok();
|
||||
|
||||
rendered_block
|
||||
}
|
||||
|
||||
pub fn hover_markdown_style(window: &Window, cx: &App) -> MarkdownStyle {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let ui_font_family = settings.ui_font.family.clone();
|
||||
let ui_font_fallbacks = settings.ui_font.fallbacks.clone();
|
||||
let buffer_font_family = settings.buffer_font.family.clone();
|
||||
let buffer_font_fallbacks = settings.buffer_font.fallbacks.clone();
|
||||
|
||||
let mut base_text_style = window.text_style();
|
||||
base_text_style.refine(&TextStyleRefinement {
|
||||
font_family: Some(ui_font_family.clone()),
|
||||
font_fallbacks: ui_font_fallbacks,
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
..Default::default()
|
||||
});
|
||||
MarkdownStyle {
|
||||
base_text_style,
|
||||
code_block: StyleRefinement::default().my(rems(1.)).font_buffer(cx),
|
||||
inline_code: TextStyleRefinement {
|
||||
background_color: Some(cx.theme().colors().background),
|
||||
font_family: Some(buffer_font_family),
|
||||
font_fallbacks: buffer_font_fallbacks,
|
||||
..Default::default()
|
||||
},
|
||||
rule_color: cx.theme().colors().border,
|
||||
block_quote_border_color: Color::Muted.color(cx),
|
||||
block_quote: TextStyleRefinement {
|
||||
color: Some(Color::Muted.color(cx)),
|
||||
..Default::default()
|
||||
},
|
||||
link: TextStyleRefinement {
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
underline: Some(gpui::UnderlineStyle {
|
||||
thickness: px(1.),
|
||||
color: Some(cx.theme().colors().editor_foreground),
|
||||
wavy: false,
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
syntax: cx.theme().syntax().clone(),
|
||||
selection_background_color: { cx.theme().players().local().selection },
|
||||
|
||||
heading: StyleRefinement::default()
|
||||
.font_weight(FontWeight::BOLD)
|
||||
.text_base()
|
||||
.mt(rems(1.))
|
||||
.mb_0(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open_markdown_url(link: SharedString, window: &mut Window, cx: &mut App) {
|
||||
if let Ok(uri) = Url::parse(&link) {
|
||||
if uri.scheme() == "file" {
|
||||
if let Some(workspace) = window.root::<Workspace>().flatten() {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let task =
|
||||
workspace.open_abs_path(PathBuf::from(uri.path()), false, window, cx);
|
||||
|
||||
cx.spawn_in(window, |_, mut cx| async move {
|
||||
let item = task.await?;
|
||||
// Ruby LSP uses URLs with #L1,1-4,4
|
||||
// we'll just take the first number and assume it's a line number
|
||||
let Some(fragment) = uri.fragment() else {
|
||||
return anyhow::Ok(());
|
||||
};
|
||||
let mut accum = 0u32;
|
||||
for c in fragment.chars() {
|
||||
if c >= '0' && c <= '9' && accum < u32::MAX / 2 {
|
||||
accum *= 10;
|
||||
accum += c as u32 - '0' as u32;
|
||||
} else if accum > 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if accum == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
let Some(editor) = cx.update(|_, cx| item.act_as::<Editor>(cx))? else {
|
||||
return Ok(());
|
||||
};
|
||||
editor.update_in(&mut cx, |editor, window, cx| {
|
||||
editor.change_selections(
|
||||
Some(Autoscroll::fit()),
|
||||
window,
|
||||
cx,
|
||||
|selections| {
|
||||
selections.select_ranges([text::Point::new(accum - 1, 0)
|
||||
..text::Point::new(accum - 1, 0)]);
|
||||
},
|
||||
);
|
||||
})
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
cx.open_url(&link);
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct HoverState {
|
||||
pub info_popovers: Vec<InfoPopover>,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use collections::{HashMap, HashSet};
|
||||
use git::diff::DiffHunkStatus;
|
||||
use gpui::{
|
||||
Action, AppContext as _, Corner, CursorStyle, Focusable as _, Hsla, Model, MouseButton,
|
||||
Action, AppContext, Corner, CursorStyle, Focusable as _, Hsla, Model, MouseButton,
|
||||
Subscription, Task,
|
||||
};
|
||||
use language::{Buffer, BufferId, Point};
|
||||
@@ -372,7 +372,7 @@ impl Editor {
|
||||
|
||||
self.diff_map
|
||||
.hunk_update_tasks
|
||||
.insert(None, cx.background_spawn(new_toggle_task));
|
||||
.insert(None, cx.background_executor().spawn(new_toggle_task));
|
||||
}
|
||||
|
||||
pub(super) fn expand_diff_hunk(
|
||||
@@ -1089,9 +1089,10 @@ impl Editor {
|
||||
.ok();
|
||||
});
|
||||
|
||||
diff_map
|
||||
.hunk_update_tasks
|
||||
.insert(Some(buffer_id), cx.background_spawn(new_sync_task));
|
||||
diff_map.hunk_update_tasks.insert(
|
||||
Some(buffer_id),
|
||||
cx.background_executor().spawn(new_sync_task),
|
||||
);
|
||||
}
|
||||
|
||||
fn go_to_subsequent_hunk(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{ops::Range, time::Duration};
|
||||
|
||||
use collections::HashSet;
|
||||
use gpui::{App, AppContext as _, Context, Task, Window};
|
||||
use gpui::{App, Context, Task, Window};
|
||||
use language::language_settings::language_settings;
|
||||
use multi_buffer::{IndentGuide, MultiBufferRow};
|
||||
use text::{LineIndent, Point};
|
||||
@@ -102,7 +102,9 @@ impl Editor {
|
||||
|
||||
let snapshot = snapshot.clone();
|
||||
|
||||
let task = cx.background_spawn(resolve_indented_range(snapshot, cursor_row));
|
||||
let task = cx
|
||||
.background_executor()
|
||||
.spawn(resolve_indented_range(snapshot, cursor_row));
|
||||
|
||||
// Try to resolve the indent in a short amount of time, otherwise move it to a background task.
|
||||
match cx
|
||||
@@ -113,7 +115,7 @@ impl Editor {
|
||||
Err(future) => {
|
||||
state.pending_refresh =
|
||||
Some(cx.spawn_in(window, |editor, mut cx| async move {
|
||||
let result = cx.background_spawn(future).await;
|
||||
let result = cx.background_executor().spawn(future).await;
|
||||
editor
|
||||
.update(&mut cx, |editor, _| {
|
||||
editor.active_indent_guides_state.active_indent_range = result;
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
use anyhow::Context as _;
|
||||
use clock::Global;
|
||||
use futures::future;
|
||||
use gpui::{AppContext as _, AsyncApp, Context, Entity, Task, Window};
|
||||
use gpui::{AsyncApp, Context, Entity, Task, Window};
|
||||
use language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
|
||||
use parking_lot::RwLock;
|
||||
use project::{InlayHint, ResolveState};
|
||||
@@ -996,17 +996,19 @@ fn fetch_and_update_hints(
|
||||
|
||||
let background_task_buffer_snapshot = buffer_snapshot.clone();
|
||||
let background_fetch_range = fetch_range.clone();
|
||||
let new_update = cx.background_spawn(async move {
|
||||
calculate_hint_updates(
|
||||
query.excerpt_id,
|
||||
invalidate,
|
||||
background_fetch_range,
|
||||
new_hints,
|
||||
&background_task_buffer_snapshot,
|
||||
cached_excerpt_hints,
|
||||
&visible_hints,
|
||||
)
|
||||
})
|
||||
let new_update = cx
|
||||
.background_executor()
|
||||
.spawn(async move {
|
||||
calculate_hint_updates(
|
||||
query.excerpt_id,
|
||||
invalidate,
|
||||
background_fetch_range,
|
||||
new_hints,
|
||||
&background_task_buffer_snapshot,
|
||||
cached_excerpt_hints,
|
||||
&visible_hints,
|
||||
)
|
||||
})
|
||||
.await;
|
||||
if let Some(new_update) = new_update {
|
||||
log::debug!(
|
||||
|
||||
@@ -706,10 +706,6 @@ impl Item for Editor {
|
||||
self.buffer.read(cx).is_singleton()
|
||||
}
|
||||
|
||||
fn can_save_as(&self, cx: &App) -> bool {
|
||||
self.buffer.read(cx).is_singleton()
|
||||
}
|
||||
|
||||
fn clone_on_split(
|
||||
&self,
|
||||
_workspace_id: Option<WorkspaceId>,
|
||||
@@ -1073,16 +1069,12 @@ impl SerializableItem for Editor {
|
||||
buffer.set_language(Some(language), cx);
|
||||
}
|
||||
buffer.set_text(contents, cx);
|
||||
if let Some(entry) = buffer.peek_undo_stack() {
|
||||
buffer.forget_transaction(entry.transaction_id());
|
||||
}
|
||||
})?;
|
||||
|
||||
cx.update(|window, cx| {
|
||||
cx.new(|cx| {
|
||||
let mut editor = Editor::for_buffer(buffer, Some(project), window, cx);
|
||||
|
||||
editor.read_selections_from_db(item_id, workspace_id, window, cx);
|
||||
editor.read_scroll_position_from_db(item_id, workspace_id, window, cx);
|
||||
editor
|
||||
})
|
||||
@@ -1130,9 +1122,6 @@ impl SerializableItem for Editor {
|
||||
);
|
||||
}
|
||||
buffer.set_text(buffer_text, cx);
|
||||
if let Some(entry) = buffer.peek_undo_stack() {
|
||||
buffer.forget_transaction(entry.transaction_id());
|
||||
}
|
||||
})?;
|
||||
}
|
||||
|
||||
@@ -1141,12 +1130,6 @@ impl SerializableItem for Editor {
|
||||
let mut editor =
|
||||
Editor::for_buffer(buffer, Some(project), window, cx);
|
||||
|
||||
editor.read_selections_from_db(
|
||||
item_id,
|
||||
workspace_id,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
editor.read_scroll_position_from_db(
|
||||
item_id,
|
||||
workspace_id,
|
||||
@@ -1165,7 +1148,6 @@ impl SerializableItem for Editor {
|
||||
window.spawn(cx, |mut cx| async move {
|
||||
let editor = open_by_abs_path?.await?.downcast::<Editor>().with_context(|| format!("Failed to downcast to Editor after opening abs path {abs_path:?}"))?;
|
||||
editor.update_in(&mut cx, |editor, window, cx| {
|
||||
editor.read_selections_from_db(item_id, workspace_id, window, cx);
|
||||
editor.read_scroll_position_from_db(item_id, workspace_id, window, cx);
|
||||
})?;
|
||||
Ok(editor)
|
||||
@@ -1225,27 +1207,28 @@ impl SerializableItem for Editor {
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
|
||||
Some(cx.spawn_in(window, |_this, cx| async move {
|
||||
cx.background_spawn(async move {
|
||||
let (contents, language) = if serialize_dirty_buffers && is_dirty {
|
||||
let contents = snapshot.text();
|
||||
let language = snapshot.language().map(|lang| lang.name().to_string());
|
||||
(Some(contents), language)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let (contents, language) = if serialize_dirty_buffers && is_dirty {
|
||||
let contents = snapshot.text();
|
||||
let language = snapshot.language().map(|lang| lang.name().to_string());
|
||||
(Some(contents), language)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let editor = SerializedEditor {
|
||||
abs_path,
|
||||
contents,
|
||||
language,
|
||||
mtime,
|
||||
};
|
||||
DB.save_serialized_editor(item_id, workspace_id, editor)
|
||||
.await
|
||||
.context("failed to save serialized editor")
|
||||
})
|
||||
.await
|
||||
.context("failed to save contents of buffer")?;
|
||||
let editor = SerializedEditor {
|
||||
abs_path,
|
||||
contents,
|
||||
language,
|
||||
mtime,
|
||||
};
|
||||
DB.save_serialized_editor(item_id, workspace_id, editor)
|
||||
.await
|
||||
.context("failed to save serialized editor")
|
||||
})
|
||||
.await
|
||||
.context("failed to save contents of buffer")?;
|
||||
|
||||
Ok(())
|
||||
}))
|
||||
@@ -1539,7 +1522,7 @@ impl SearchableItem for Editor {
|
||||
ranges.iter().cloned().collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
cx.background_spawn(async move {
|
||||
cx.background_executor().spawn(async move {
|
||||
let mut ranges = Vec::new();
|
||||
|
||||
let search_within_ranges = if search_within_ranges.is_empty() {
|
||||
|
||||
@@ -154,6 +154,11 @@ pub fn deploy_context_menu(
|
||||
|
||||
let focus = window.focused(cx);
|
||||
let has_reveal_target = editor.target_file(cx).is_some();
|
||||
let reveal_in_finder_label = if cfg!(target_os = "macos") {
|
||||
"Reveal in Finder"
|
||||
} else {
|
||||
"Reveal in File Manager"
|
||||
};
|
||||
let has_selections = editor
|
||||
.selections
|
||||
.all::<PointUtf16>(cx)
|
||||
@@ -191,22 +196,14 @@ pub fn deploy_context_menu(
|
||||
.action("Paste", Box::new(Paste))
|
||||
.separator()
|
||||
.map(|builder| {
|
||||
let reveal_in_finder_label = if cfg!(target_os = "macos") {
|
||||
"Reveal in Finder"
|
||||
} else {
|
||||
"Reveal in File Manager"
|
||||
};
|
||||
const OPEN_IN_TERMINAL_LABEL: &str = "Open in Terminal";
|
||||
if has_reveal_target {
|
||||
builder
|
||||
.action(reveal_in_finder_label, Box::new(RevealInFileManager))
|
||||
.action(OPEN_IN_TERMINAL_LABEL, Box::new(OpenInTerminal))
|
||||
builder.action(reveal_in_finder_label, Box::new(RevealInFileManager))
|
||||
} else {
|
||||
builder
|
||||
.disabled_action(reveal_in_finder_label, Box::new(RevealInFileManager))
|
||||
.disabled_action(OPEN_IN_TERMINAL_LABEL, Box::new(OpenInTerminal))
|
||||
}
|
||||
})
|
||||
.action("Open in Terminal", Box::new(OpenInTerminal))
|
||||
.map(|builder| {
|
||||
const COPY_PERMALINK_LABEL: &str = "Copy Permalink";
|
||||
if has_git_repo {
|
||||
|
||||
@@ -1184,7 +1184,6 @@ mod tests {
|
||||
fn init_test(cx: &mut gpui::App) {
|
||||
let settings_store = SettingsStore::test(cx);
|
||||
cx.set_global(settings_store);
|
||||
workspace::init_settings(cx);
|
||||
theme::init(theme::LoadThemes::JustBase, cx);
|
||||
language::init(cx);
|
||||
crate::init(cx);
|
||||
|
||||
@@ -2,7 +2,6 @@ use anyhow::Result;
|
||||
use db::sqlez::bindable::{Bind, Column, StaticColumnCount};
|
||||
use db::sqlez::statement::Statement;
|
||||
use fs::MTime;
|
||||
use itertools::Itertools as _;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use db::sqlez_macros::sql;
|
||||
@@ -135,26 +134,9 @@ define_connection!(
|
||||
ALTER TABLE editors ADD COLUMN mtime_seconds INTEGER DEFAULT NULL;
|
||||
ALTER TABLE editors ADD COLUMN mtime_nanos INTEGER DEFAULT NULL;
|
||||
),
|
||||
sql! (
|
||||
CREATE TABLE editor_selections (
|
||||
item_id INTEGER NOT NULL,
|
||||
editor_id INTEGER NOT NULL,
|
||||
workspace_id INTEGER NOT NULL,
|
||||
start INTEGER NOT NULL,
|
||||
end INTEGER NOT NULL,
|
||||
PRIMARY KEY(item_id),
|
||||
FOREIGN KEY(editor_id, workspace_id) REFERENCES editors(item_id, workspace_id)
|
||||
ON DELETE CASCADE
|
||||
) STRICT;
|
||||
),
|
||||
];
|
||||
);
|
||||
|
||||
// https://www.sqlite.org/limits.html
|
||||
// > <..> the maximum value of a host parameter number is SQLITE_MAX_VARIABLE_NUMBER,
|
||||
// > which defaults to <..> 32766 for SQLite versions after 3.32.0.
|
||||
const MAX_QUERY_PLACEHOLDERS: usize = 32000;
|
||||
|
||||
impl EditorDb {
|
||||
query! {
|
||||
pub fn get_serialized_editor(item_id: ItemId, workspace_id: WorkspaceId) -> Result<Option<SerializedEditor>> {
|
||||
@@ -206,68 +188,6 @@ impl EditorDb {
|
||||
}
|
||||
}
|
||||
|
||||
query! {
|
||||
pub fn get_editor_selections(
|
||||
editor_id: ItemId,
|
||||
workspace_id: WorkspaceId
|
||||
) -> Result<Vec<(usize, usize)>> {
|
||||
SELECT start, end
|
||||
FROM editor_selections
|
||||
WHERE editor_id = ?1 AND workspace_id = ?2
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn save_editor_selections(
|
||||
&self,
|
||||
editor_id: ItemId,
|
||||
workspace_id: WorkspaceId,
|
||||
selections: Vec<(usize, usize)>,
|
||||
) -> Result<()> {
|
||||
let mut first_selection;
|
||||
let mut last_selection = 0_usize;
|
||||
for (count, placeholders) in std::iter::once("(?1, ?2, ?, ?)")
|
||||
.cycle()
|
||||
.take(selections.len())
|
||||
.chunks(MAX_QUERY_PLACEHOLDERS / 4)
|
||||
.into_iter()
|
||||
.map(|chunk| {
|
||||
let mut count = 0;
|
||||
let placeholders = chunk
|
||||
.inspect(|_| {
|
||||
count += 1;
|
||||
})
|
||||
.join(", ");
|
||||
(count, placeholders)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
first_selection = last_selection;
|
||||
last_selection = last_selection + count;
|
||||
let query = format!(
|
||||
r#"
|
||||
DELETE FROM editor_selections WHERE editor_id = ?1 AND workspace_id = ?2;
|
||||
|
||||
INSERT OR IGNORE INTO editor_selections (editor_id, workspace_id, start, end)
|
||||
VALUES {placeholders};
|
||||
"#
|
||||
);
|
||||
|
||||
let selections = selections[first_selection..last_selection].to_vec();
|
||||
self.write(move |conn| {
|
||||
let mut statement = Statement::prepare(conn, query)?;
|
||||
statement.bind(&editor_id, 1)?;
|
||||
let mut next_index = statement.bind(&workspace_id, 2)?;
|
||||
for (start, end) in selections {
|
||||
next_index = statement.bind(&start, next_index)?;
|
||||
next_index = statement.bind(&end, next_index)?;
|
||||
}
|
||||
statement.exec()
|
||||
})
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_unloaded_items(
|
||||
&self,
|
||||
workspace: WorkspaceId,
|
||||
|
||||
@@ -224,6 +224,7 @@ impl ScrollManager {
|
||||
self.anchor.scroll_position(snapshot)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn set_scroll_position(
|
||||
&mut self,
|
||||
scroll_position: gpui::Point<f32>,
|
||||
@@ -298,6 +299,7 @@ impl ScrollManager {
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn set_anchor(
|
||||
&mut self,
|
||||
anchor: ScrollAnchor,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::Editor;
|
||||
|
||||
use gpui::{App, AppContext as _, Task as AsyncTask, Window};
|
||||
use gpui::{App, Task as AsyncTask, Window};
|
||||
use project::Location;
|
||||
use task::{TaskContext, TaskVariables, VariableName};
|
||||
use text::{ToOffset, ToPoint};
|
||||
@@ -88,6 +88,7 @@ pub fn task_context(
|
||||
};
|
||||
editor.update(cx, |editor, cx| {
|
||||
let context_task = task_context_with_editor(editor, window, cx);
|
||||
cx.background_spawn(async move { context_task.await.unwrap_or_default() })
|
||||
cx.background_executor()
|
||||
.spawn(async move { context_task.await.unwrap_or_default() })
|
||||
})
|
||||
}
|
||||
|
||||
@@ -215,8 +215,6 @@ impl EditorLspTestContext {
|
||||
("[" @open "]" @close)
|
||||
("{" @open "}" @close)
|
||||
("<" @open ">" @close)
|
||||
("'" @open "'" @close)
|
||||
("`" @open "`" @close)
|
||||
("\"" @open "\"" @close)"#})),
|
||||
indents: Some(Cow::from(indoc! {r#"
|
||||
[
|
||||
@@ -254,7 +252,7 @@ impl EditorLspTestContext {
|
||||
word_characters: ['-'].into_iter().collect(),
|
||||
..Default::default()
|
||||
},
|
||||
Some(tree_sitter_html::LANGUAGE.into()),
|
||||
Some(tree_sitter_html::language()),
|
||||
)
|
||||
.with_queries(LanguageQueries {
|
||||
brackets: Some(Cow::from(indoc! {r#"
|
||||
|
||||
@@ -399,6 +399,7 @@ async fn run_evaluation(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn run_eval_project(
|
||||
evaluation_project: EvaluationProject,
|
||||
user_store: &Entity<UserStore>,
|
||||
|
||||
@@ -168,7 +168,7 @@ impl ExtensionBuilder {
|
||||
let wasm_bytes = fs::read(&wasm_path)
|
||||
.with_context(|| format!("failed to read output module `{}`", wasm_path.display()))?;
|
||||
|
||||
let mut encoder = ComponentEncoder::default()
|
||||
let encoder = ComponentEncoder::default()
|
||||
.module(&wasm_bytes)?
|
||||
.adapter("wasi_snapshot_preview1", &adapter_bytes)
|
||||
.context("failed to load adapter module")?
|
||||
|
||||
@@ -96,8 +96,6 @@ impl ExtensionHostProxy {
|
||||
}
|
||||
|
||||
pub trait ExtensionThemeProxy: Send + Sync + 'static {
|
||||
fn set_extensions_loaded(&self);
|
||||
|
||||
fn list_theme_names(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<Vec<String>>>;
|
||||
|
||||
fn remove_user_themes(&self, themes: Vec<SharedString>);
|
||||
@@ -125,14 +123,6 @@ pub trait ExtensionThemeProxy: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
impl ExtensionThemeProxy for ExtensionHostProxy {
|
||||
fn set_extensions_loaded(&self) {
|
||||
let Some(proxy) = self.theme_proxy.read().clone() else {
|
||||
return;
|
||||
};
|
||||
|
||||
proxy.set_extensions_loaded()
|
||||
}
|
||||
|
||||
fn list_theme_names(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<Vec<String>>> {
|
||||
let Some(proxy) = self.theme_proxy.read().clone() else {
|
||||
return Task::ready(Ok(Vec::new()));
|
||||
|
||||
@@ -191,7 +191,7 @@ static mut EXTENSION: Option<Box<dyn Extension>> = None;
|
||||
pub static ZED_API_VERSION: [u8; 6] = *include_bytes!(concat!(env!("OUT_DIR"), "/version_bytes"));
|
||||
|
||||
mod wit {
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
#![allow(clippy::too_many_arguments, clippy::missing_safety_doc)]
|
||||
|
||||
wit_bindgen::generate!({
|
||||
skip: ["init-extension"],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user