Compare commits
76 Commits
update-edi
...
macos-chec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d3890e595 | ||
|
|
b5d85b638a | ||
|
|
91c99baaf2 | ||
|
|
3b5dad8a9d | ||
|
|
bcba0b92ed | ||
|
|
8b088b3985 | ||
|
|
58491807a4 | ||
|
|
ba2c1821af | ||
|
|
c7df2d787b | ||
|
|
2400fb4d9e | ||
|
|
74d1a652f6 | ||
|
|
bd41be2caf | ||
|
|
4ff1173047 | ||
|
|
394bb8f4e6 | ||
|
|
56f13ddc50 | ||
|
|
79e3faffb2 | ||
|
|
e0fc767c11 | ||
|
|
14289b5a6e | ||
|
|
1b38b9f61d | ||
|
|
bf21d9183e | ||
|
|
e60123bbdc | ||
|
|
f2776099ab | ||
|
|
a01d2dd798 | ||
|
|
88fe54ea02 | ||
|
|
64b2a499fa | ||
|
|
5825413eb8 | ||
|
|
86b8852e97 | ||
|
|
1fd099bb38 | ||
|
|
082347c5c2 | ||
|
|
2377f53444 | ||
|
|
df02745a1f | ||
|
|
e6749b5955 | ||
|
|
5f6311171f | ||
|
|
58b0a6c4af | ||
|
|
216a5e2998 | ||
|
|
f9432518e5 | ||
|
|
be83074243 | ||
|
|
bd105a5fc7 | ||
|
|
c049df2a2e | ||
|
|
3040ef416a | ||
|
|
e37acdeeb8 | ||
|
|
1d26a27afa | ||
|
|
294dea10e8 | ||
|
|
fc85ca0101 | ||
|
|
de020af6ef | ||
|
|
610158b2f0 | ||
|
|
20460239a0 | ||
|
|
7ee492746d | ||
|
|
5c5caf1ffe | ||
|
|
39c9b1f170 | ||
|
|
4aae0e2f6c | ||
|
|
744579ede9 | ||
|
|
592e8fbffc | ||
|
|
a618830aea | ||
|
|
8d839fca06 | ||
|
|
79ee01eb14 | ||
|
|
3b91de8003 | ||
|
|
2f734cbd5e | ||
|
|
5ac82161fa | ||
|
|
e133d3b31e | ||
|
|
9094f53211 | ||
|
|
5d26ce14d7 | ||
|
|
28c667a3c7 | ||
|
|
c38deb1430 | ||
|
|
8af54c589b | ||
|
|
8b85d26981 | ||
|
|
8c202b3b09 | ||
|
|
a6a8d79d86 | ||
|
|
74e8164cd7 | ||
|
|
16ffddf48d | ||
|
|
2f741c8686 | ||
|
|
8c780ba287 | ||
|
|
de0d9d678e | ||
|
|
2db5eed840 | ||
|
|
cf176dab20 | ||
|
|
c3afeda80b |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -482,6 +482,6 @@ jobs:
|
||||
- bundle
|
||||
steps:
|
||||
- name: gh release
|
||||
run: gh release edit $GITHUB_REF_NAME --draft=false
|
||||
run: gh release edit $GITHUB_REF_NAME --draft=true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
33
.github/workflows/issue_response.yml
vendored
Normal file
33
.github/workflows/issue_response.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Issue Response
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 12 * * 2"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
issue-response:
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "script/issue_response/pnpm-lock.yaml"
|
||||
|
||||
- run: pnpm install --dir script/issue_response
|
||||
|
||||
- name: Run Issue Response
|
||||
run: pnpm run --dir script/issue_response start
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SLACK_ISSUE_RESPONSE_WEBHOOK_URL: ${{ secrets.SLACK_ISSUE_RESPONSE_WEBHOOK_URL }}
|
||||
@@ -37,6 +37,16 @@ We plan to set aside time each week to pair program with contributors on promisi
|
||||
- Pair with us and watch us code to learn the codebase
|
||||
- Low effort PRs, such as those that just re-arrange syntax, won't be merged without a compelling justification
|
||||
|
||||
## File icons
|
||||
|
||||
Zed's default icon theme consists of icons that are hand-designed to fit together in a cohesive manner.
|
||||
|
||||
We do not accept PRs for file icons that are just an off-the-shelf SVG taken from somewhere else.
|
||||
|
||||
### Adding new icons to the Zed icon theme
|
||||
|
||||
If you would like to add a new icon to the Zed icon theme, [open a Discussion](https://github.com/zed-industries/zed/discussions/new?category=ux-and-design) and we can work with you on getting an icon designed and added to Zed.
|
||||
|
||||
## Bird's-eye view of Zed
|
||||
|
||||
Zed is made up of several smaller crates - let's go over those you're most likely to interact with:
|
||||
|
||||
388
Cargo.lock
generated
388
Cargo.lock
generated
@@ -69,7 +69,7 @@ dependencies = [
|
||||
"const-random",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -342,20 +342,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ashpd"
|
||||
version = "0.10.2"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3"
|
||||
checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
|
||||
dependencies = [
|
||||
"async-fs",
|
||||
"async-net",
|
||||
"enumflags2",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.0",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"url",
|
||||
"zbus 5.1.1",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -757,7 +757,7 @@ dependencies = [
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand 2.3.0",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"slab",
|
||||
]
|
||||
|
||||
@@ -769,7 +769,7 @@ checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"blocking",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -783,7 +783,7 @@ dependencies = [
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"blocking",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
@@ -797,7 +797,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-io",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"parking",
|
||||
"polling",
|
||||
"rustix",
|
||||
@@ -837,7 +837,7 @@ checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
|
||||
dependencies = [
|
||||
"async-io",
|
||||
"blocking",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -863,7 +863,7 @@ dependencies = [
|
||||
"blocking",
|
||||
"cfg-if",
|
||||
"event-listener 5.3.1",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"rustix",
|
||||
"tracing",
|
||||
]
|
||||
@@ -924,7 +924,7 @@ dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"gloo-timers",
|
||||
"kv-log-macro",
|
||||
"log",
|
||||
@@ -1005,7 +1005,7 @@ source = "git+https://github.com/zed-industries/async-tls?rev=1e759a4b5e370f87dc
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"rustls-pemfile 2.2.0",
|
||||
"webpki-roots",
|
||||
]
|
||||
@@ -1056,7 +1056,7 @@ checksum = "00b9f7252833d5ed4b00aa9604b563529dd5e11de9c23615de2dcdf91eb87b52"
|
||||
dependencies = [
|
||||
"async-compression",
|
||||
"crc32fast",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"pin-project",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
@@ -1274,9 +1274,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-kinesis"
|
||||
version = "1.60.0"
|
||||
version = "1.61.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b8052335b6ba19b08ba2b363c7505f8ed34074ac23fa14a652ff6a0a02a4c06"
|
||||
checksum = "89f2163d8704e8fdcd51ec6c2e0441c418471e422ee9690451b17a1c46344e1a"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-runtime",
|
||||
@@ -1296,9 +1296,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-s3"
|
||||
version = "1.73.0"
|
||||
version = "1.76.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3978e0a211bdc5cddecfd91fb468665a662a27fbdaef39ddf36a2a18fef12cb4"
|
||||
checksum = "66e83401ad7287ad15244d557e35502c2a94105ca5b41d656c391f1a4fc04ca2"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-runtime",
|
||||
@@ -1397,9 +1397,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sigv4"
|
||||
version = "1.2.8"
|
||||
version = "1.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bc5bbd1e4a2648fd8c5982af03935972c24a2f9846b396de661d351ee3ce837"
|
||||
checksum = "9bfe75fad52793ce6dec0dc3d4b1f388f038b5eb866c8d4d7f3a8e21b5ea5051"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-smithy-eventstream",
|
||||
@@ -1973,7 +1973,7 @@ dependencies = [
|
||||
"async-channel 2.3.1",
|
||||
"async-task",
|
||||
"futures-io",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"piper",
|
||||
]
|
||||
|
||||
@@ -2537,9 +2537,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.28"
|
||||
version = "4.5.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff"
|
||||
checksum = "8acebd8ad879283633b343856142139f2da2317c96b05b4dd6181c61e2480184"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -2547,9 +2547,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.27"
|
||||
version = "4.5.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
|
||||
checksum = "f6ba32cbda51c7e1dfd49acc1457ba1a7dec5b64fe360e828acb13ca8dc9c2f9"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -2792,9 +2792,9 @@ dependencies = [
|
||||
"jsonwebtoken",
|
||||
"language",
|
||||
"language_model",
|
||||
"livekit_api",
|
||||
"livekit_client",
|
||||
"livekit_client_macos",
|
||||
"livekit_server",
|
||||
"log",
|
||||
"lsp",
|
||||
"menu",
|
||||
@@ -3611,13 +3611,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.2.9"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
]
|
||||
checksum = "bba74424191d99c617a172ef126d429f62fe54aba1002c4d36e49403ce4b00a2"
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
@@ -4062,7 +4058,6 @@ dependencies = [
|
||||
"http_client",
|
||||
"indoc",
|
||||
"inline_completion",
|
||||
"inventory",
|
||||
"itertools 0.14.0",
|
||||
"language",
|
||||
"linkify",
|
||||
@@ -4709,11 +4704,8 @@ dependencies = [
|
||||
name = "file_icons"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"collections",
|
||||
"gpui",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"settings",
|
||||
"theme",
|
||||
"util",
|
||||
@@ -4721,9 +4713,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "filedescriptor"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e"
|
||||
checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"thiserror 1.0.69",
|
||||
@@ -5125,9 +5117,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "2.5.0"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1"
|
||||
checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532"
|
||||
dependencies = [
|
||||
"fastrand 2.3.0",
|
||||
"futures-core",
|
||||
@@ -5371,6 +5363,7 @@ dependencies = [
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"settings",
|
||||
"strum",
|
||||
"theme",
|
||||
"time",
|
||||
"ui",
|
||||
@@ -6018,7 +6011,7 @@ dependencies = [
|
||||
"futures 0.3.31",
|
||||
"http 1.2.0",
|
||||
"log",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"rustls-platform-verifier",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -6119,7 +6112,7 @@ dependencies = [
|
||||
"http 1.2.0",
|
||||
"hyper 1.5.1",
|
||||
"hyper-util",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
@@ -6780,11 +6773,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jsonwebtoken"
|
||||
version = "9.3.0"
|
||||
version = "9.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f"
|
||||
checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"base64 0.22.1",
|
||||
"js-sys",
|
||||
"pem",
|
||||
"ring",
|
||||
@@ -6966,6 +6959,7 @@ dependencies = [
|
||||
"image",
|
||||
"lmstudio",
|
||||
"log",
|
||||
"mistral",
|
||||
"ollama",
|
||||
"open_ai",
|
||||
"parking_lot",
|
||||
@@ -7013,6 +7007,7 @@ dependencies = [
|
||||
"language_model",
|
||||
"lmstudio",
|
||||
"menu",
|
||||
"mistral",
|
||||
"ollama",
|
||||
"open_ai",
|
||||
"project",
|
||||
@@ -7409,6 +7404,21 @@ dependencies = [
|
||||
"futures 0.3.31",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "livekit_api"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"jsonwebtoken",
|
||||
"log",
|
||||
"prost 0.9.0",
|
||||
"prost-build 0.9.0",
|
||||
"prost-types 0.9.0",
|
||||
"reqwest 0.12.8",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "livekit_client"
|
||||
version = "0.1.0"
|
||||
@@ -7425,7 +7435,7 @@ dependencies = [
|
||||
"http_client",
|
||||
"image",
|
||||
"livekit",
|
||||
"livekit_server",
|
||||
"livekit_api",
|
||||
"log",
|
||||
"media",
|
||||
"nanoid",
|
||||
@@ -7450,7 +7460,7 @@ dependencies = [
|
||||
"core-foundation 0.9.4",
|
||||
"futures 0.3.31",
|
||||
"gpui",
|
||||
"livekit_server",
|
||||
"livekit_api",
|
||||
"log",
|
||||
"media",
|
||||
"nanoid",
|
||||
@@ -7462,21 +7472,6 @@ dependencies = [
|
||||
"simplelog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "livekit_server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"jsonwebtoken",
|
||||
"log",
|
||||
"prost 0.9.0",
|
||||
"prost-build 0.9.0",
|
||||
"prost-types 0.9.0",
|
||||
"reqwest 0.12.8",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lmdb-master-sys"
|
||||
version = "0.2.4"
|
||||
@@ -7974,6 +7969,19 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mistral"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures 0.3.31",
|
||||
"http_client",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "msvc_spectre_libs"
|
||||
version = "0.1.2"
|
||||
@@ -8744,34 +8752,37 @@ checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
||||
|
||||
[[package]]
|
||||
name = "oo7"
|
||||
version = "0.3.3"
|
||||
source = "git+https://github.com/zed-industries/oo7?branch=avoid-crypto-panic#9d5d5fcd7e4e0add9b420ffb58f67661b0b37568"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d939e731a8ef5d7809bedad43a7b4220d05093d5c76f7ee9c5289092bcb7bba4"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"ashpd",
|
||||
"async-fs",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-net",
|
||||
"blocking",
|
||||
"cbc",
|
||||
"cipher",
|
||||
"digest",
|
||||
"endi",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
"futures-util",
|
||||
"getrandom 0.3.1",
|
||||
"hkdf",
|
||||
"hmac",
|
||||
"md-5",
|
||||
"num",
|
||||
"num-bigint-dig",
|
||||
"pbkdf2 0.12.2",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.0",
|
||||
"serde",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"zbus 4.4.0",
|
||||
"zbus",
|
||||
"zbus_macros",
|
||||
"zeroize",
|
||||
"zvariant 4.2.0",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8985,6 +8996,7 @@ dependencies = [
|
||||
"util",
|
||||
"workspace",
|
||||
"worktree",
|
||||
"zed_actions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9969,7 +9981,7 @@ version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10180,6 +10192,7 @@ dependencies = [
|
||||
"util",
|
||||
"workspace",
|
||||
"worktree",
|
||||
"zed_actions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10479,7 +10492,7 @@ dependencies = [
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"socket2",
|
||||
"thiserror 2.0.6",
|
||||
"tokio",
|
||||
@@ -10497,7 +10510,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.6",
|
||||
@@ -10517,7 +10530,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10559,6 +10572,17 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.0",
|
||||
"zerocopy 0.8.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
@@ -10579,6 +10603,16 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
@@ -10597,6 +10631,16 @@ dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
|
||||
dependencies = [
|
||||
"getrandom 0.3.1",
|
||||
"zerocopy 0.8.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
@@ -10869,6 +10913,7 @@ dependencies = [
|
||||
"prost 0.9.0",
|
||||
"release_channel",
|
||||
"rpc",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shlex",
|
||||
@@ -11059,7 +11104,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-pemfile 2.2.0",
|
||||
"rustls-pki-types",
|
||||
@@ -11433,9 +11478,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.22"
|
||||
version = "0.23.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7"
|
||||
checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
@@ -11509,7 +11554,7 @@ dependencies = [
|
||||
"jni",
|
||||
"log",
|
||||
"once_cell",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"rustls-platform-verifier-android",
|
||||
"rustls-webpki 0.102.8",
|
||||
@@ -12353,7 +12398,7 @@ dependencies = [
|
||||
"async-net",
|
||||
"async-process",
|
||||
"blocking",
|
||||
"futures-lite 2.5.0",
|
||||
"futures-lite 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -12543,7 +12588,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"rust_decimal",
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"rustls-pemfile 2.2.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -13794,7 +13839,7 @@ version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
|
||||
dependencies = [
|
||||
"rustls 0.23.22",
|
||||
"rustls 0.23.23",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -14133,9 +14178,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-elixir"
|
||||
version = "0.3.3"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23d7310aea06158653d18959123a64262bfbf122b7437899dea0c338654a51d3"
|
||||
checksum = "e45d444647b4fd53d8fd32474c1b8bedc1baa22669ce3a78d083e365fa9a2d3f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter-language",
|
||||
@@ -14638,11 +14683,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.12.1"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
|
||||
checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0"
|
||||
dependencies = [
|
||||
"getrandom 0.2.15",
|
||||
"getrandom 0.3.1",
|
||||
"serde",
|
||||
"sha1_smol",
|
||||
]
|
||||
@@ -15488,12 +15533,12 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"client",
|
||||
"copilot",
|
||||
"db",
|
||||
"editor",
|
||||
"fuzzy",
|
||||
"gpui",
|
||||
"install_cli",
|
||||
"language",
|
||||
"picker",
|
||||
"project",
|
||||
"schemars",
|
||||
@@ -16249,6 +16294,7 @@ dependencies = [
|
||||
"ui",
|
||||
"util",
|
||||
"uuid",
|
||||
"zed_actions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -16501,9 +16547,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "4.4.0"
|
||||
version = "5.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
|
||||
checksum = "59c333f648ea1b647bc95dc1d34807c8e25ed7a6feff3394034dc4776054b236"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
@@ -16518,45 +16564,7 @@ dependencies = [
|
||||
"enumflags2",
|
||||
"event-listener 5.3.1",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"nix",
|
||||
"ordered-stream",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"sha1",
|
||||
"static_assertions",
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"windows-sys 0.52.0",
|
||||
"xdg-home",
|
||||
"zbus_macros 4.4.0",
|
||||
"zbus_names 3.0.0",
|
||||
"zvariant 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "5.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1162094dc63b1629fcc44150bcceeaa80798cd28bcbe7fa987b65a034c258608"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
"async-fs",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-process",
|
||||
"async-recursion 1.1.1",
|
||||
"async-task",
|
||||
"async-trait",
|
||||
"blocking",
|
||||
"enumflags2",
|
||||
"event-listener 5.3.1",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"futures-lite 2.6.0",
|
||||
"hex",
|
||||
"nix",
|
||||
"ordered-stream",
|
||||
@@ -16566,50 +16574,26 @@ dependencies = [
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"windows-sys 0.59.0",
|
||||
"winnow 0.6.20",
|
||||
"winnow 0.7.1",
|
||||
"xdg-home",
|
||||
"zbus_macros 5.1.1",
|
||||
"zbus_names 4.1.0",
|
||||
"zvariant 5.1.0",
|
||||
"zbus_macros",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "4.4.0"
|
||||
version = "5.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
|
||||
checksum = "f325ad10eb0d0a3eb060203494c3b7ec3162a01a59db75d2deee100339709fc0"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
"zvariant_utils 2.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "5.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cd2dcdce3e2727f7d74b7e33b5a89539b3cc31049562137faf7ae4eb86cd16d"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
"zbus_names 4.1.0",
|
||||
"zvariant 5.1.0",
|
||||
"zvariant_utils 3.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_names"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"zvariant 4.2.0",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -16621,7 +16605,7 @@ dependencies = [
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"winnow 0.6.20",
|
||||
"zvariant 5.1.0",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -16665,7 +16649,6 @@ dependencies = [
|
||||
"feature_flags",
|
||||
"feedback",
|
||||
"file_finder",
|
||||
"file_icons",
|
||||
"fs",
|
||||
"futures 0.3.31",
|
||||
"git",
|
||||
@@ -16945,7 +16928,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
"zerocopy-derive 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79386d31a42a4996e3336b0919ddb90f81112af416270cff95b5f5af22b839c2"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.8.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -16959,6 +16951,17 @@ dependencies = [
|
||||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76331675d372f91bf8d17e13afbd5fe639200b73d01f0fc748bb059f9cca2db7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerofrom"
|
||||
version = "0.1.5"
|
||||
@@ -17176,80 +17179,43 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "4.2.0"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
|
||||
dependencies = [
|
||||
"endi",
|
||||
"enumflags2",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"zvariant_derive 4.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1200ee6ac32f1e5a312e455a949a4794855515d34f9909f4a3e082d14e1a56f"
|
||||
checksum = "b2df9ee044893fcffbdc25de30546edef3e32341466811ca18421e3cd6c5a3ac"
|
||||
dependencies = [
|
||||
"endi",
|
||||
"enumflags2",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"url",
|
||||
"winnow 0.6.20",
|
||||
"zvariant_derive 5.1.0",
|
||||
"zvariant_utils 3.0.2",
|
||||
"winnow 0.7.1",
|
||||
"zvariant_derive",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "4.2.0"
|
||||
version = "5.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
|
||||
checksum = "74170caa85b8b84cc4935f2d56a57c7a15ea6185ccdd7eadb57e6edd90f94b2f"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
"zvariant_utils 2.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "687e3b97fae6c9104fbbd36c73d27d149abf04fb874e2efbd84838763daa8916"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
"zvariant_utils 3.0.2",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_utils"
|
||||
version = "2.1.0"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.90",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_utils"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20d1d011a38f12360e5fcccceeff5e2c42a8eb7f27f0dcba97a0862ede05c9c6"
|
||||
checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"syn 2.0.90",
|
||||
"winnow 0.6.20",
|
||||
"winnow 0.7.1",
|
||||
]
|
||||
|
||||
11
Cargo.toml
11
Cargo.toml
@@ -74,9 +74,9 @@ members = [
|
||||
"crates/language_selector",
|
||||
"crates/language_tools",
|
||||
"crates/languages",
|
||||
"crates/livekit_api",
|
||||
"crates/livekit_client",
|
||||
"crates/livekit_client_macos",
|
||||
"crates/livekit_server",
|
||||
"crates/lmstudio",
|
||||
"crates/lsp",
|
||||
"crates/markdown",
|
||||
@@ -84,6 +84,7 @@ members = [
|
||||
"crates/media",
|
||||
"crates/menu",
|
||||
"crates/migrator",
|
||||
"crates/mistral",
|
||||
"crates/multi_buffer",
|
||||
"crates/node_runtime",
|
||||
"crates/notifications",
|
||||
@@ -273,9 +274,9 @@ language_models = { path = "crates/language_models" }
|
||||
language_selector = { path = "crates/language_selector" }
|
||||
language_tools = { path = "crates/language_tools" }
|
||||
languages = { path = "crates/languages" }
|
||||
livekit_api = { path = "crates/livekit_api" }
|
||||
livekit_client = { path = "crates/livekit_client" }
|
||||
livekit_client_macos = { path = "crates/livekit_client_macos" }
|
||||
livekit_server = { path = "crates/livekit_server" }
|
||||
lmstudio = { path = "crates/lmstudio" }
|
||||
lsp = { path = "crates/lsp" }
|
||||
markdown = { path = "crates/markdown" }
|
||||
@@ -283,6 +284,7 @@ markdown_preview = { path = "crates/markdown_preview" }
|
||||
media = { path = "crates/media" }
|
||||
menu = { path = "crates/menu" }
|
||||
migrator = { path = "crates/migrator" }
|
||||
mistral = { path = "crates/mistral" }
|
||||
multi_buffer = { path = "crates/multi_buffer" }
|
||||
node_runtime = { path = "crates/node_runtime" }
|
||||
notifications = { path = "crates/notifications" }
|
||||
@@ -367,7 +369,7 @@ alacritty_terminal = { git = "https://github.com/alacritty/alacritty.git", rev =
|
||||
any_vec = "0.14"
|
||||
anyhow = "1.0.86"
|
||||
arrayvec = { version = "0.7.4", features = ["serde"] }
|
||||
ashpd = { version = "0.10", default-features = false, features = ["async-std"] }
|
||||
ashpd = { version = "0.11", default-features = false, features = ["async-std"] }
|
||||
async-compat = "0.2.1"
|
||||
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
|
||||
async-dispatcher = "0.1"
|
||||
@@ -396,7 +398,7 @@ cocoa-foundation = "0.2.0"
|
||||
convert_case = "0.7.0"
|
||||
core-foundation = "0.9.3"
|
||||
core-foundation-sys = "0.8.6"
|
||||
ctor = "0.2.6"
|
||||
ctor = "0.3.0"
|
||||
dashmap = "6.0"
|
||||
derive_more = "0.99.17"
|
||||
dirs = "4.0"
|
||||
@@ -442,6 +444,7 @@ nanoid = "0.4"
|
||||
nbformat = { version = "0.10.0" }
|
||||
nix = "0.29"
|
||||
num-format = "0.4.4"
|
||||
once_cell = "1.20"
|
||||
ordered-float = "2.1.1"
|
||||
palette = { version = "0.7.5", default-features = false, features = ["std"] }
|
||||
parking_lot = "0.12.1"
|
||||
|
||||
1
assets/icons/ai_mistral.svg
Normal file
1
assets/icons/ai_mistral.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Mistral</title><g><path d="M15 6v4h-2V6h2zm4-4v4h-2V2h2zM3 2H1h2zM1 2h2v20H1V2zm8 12h2v4H9v-4zm8 0h2v8h-2v-8z"></path><path d="M19 2h4v4h-4V2zM3 2h4v4H3V2z" opacity=".4"></path><path d="M15 10V6h8v4h-8zM3 10V6h8v4H3z" opacity=".5"></path><path d="M3 14v-4h20v4z" opacity=".6"></path><path d="M11 14h4v4h-4v-4zm8 0h4v4h-4v-4zM3 14h4v4H3v-4z" opacity=".7"></path><path d="M19 18h4v4h-4v-4zM3 18h4v4H3v-4z" opacity=".8"></path></g></svg>
|
||||
|
After Width: | Height: | Size: 598 B |
@@ -1,252 +0,0 @@
|
||||
{
|
||||
"stems": {
|
||||
"Dockerfile": "docker",
|
||||
"Podfile": "ruby",
|
||||
"Procfile": "heroku"
|
||||
},
|
||||
"suffixes": {
|
||||
"Emakefile": "erlang",
|
||||
"aac": "audio",
|
||||
"accdb": "storage",
|
||||
"app.src": "erlang",
|
||||
"astro": "astro",
|
||||
"avi": "video",
|
||||
"avif": "image",
|
||||
"bak": "backup",
|
||||
"bash": "terminal",
|
||||
"bash_aliases": "terminal",
|
||||
"bash_logout": "terminal",
|
||||
"bash_profile": "terminal",
|
||||
"bashrc": "terminal",
|
||||
"bicep": "bicep",
|
||||
"bmp": "image",
|
||||
"c": "c",
|
||||
"c++": "cpp",
|
||||
"cc": "cpp",
|
||||
"cjs": "javascript",
|
||||
"cjsx": "react",
|
||||
"coffee": "coffeescript",
|
||||
"conf": "settings",
|
||||
"cpp": "cpp",
|
||||
"cs": "csharp",
|
||||
"css": "css",
|
||||
"csv": "storage",
|
||||
"cxx": "cpp",
|
||||
"cts": "typescript",
|
||||
"ctsx": "react",
|
||||
"cue": "cue",
|
||||
"dart": "dart",
|
||||
"dat": "storage",
|
||||
"db": "storage",
|
||||
"dbf": "storage",
|
||||
"diff": "diff",
|
||||
"dll": "storage",
|
||||
"doc": "document",
|
||||
"docx": "document",
|
||||
"eex": "elixir",
|
||||
"elm": "elm",
|
||||
"erl": "erlang",
|
||||
"escript": "erlang",
|
||||
"eslint.config.cjs": "eslint",
|
||||
"eslint.config.cts": "eslint",
|
||||
"eslint.config.js": "eslint",
|
||||
"eslint.config.mjs": "eslint",
|
||||
"eslint.config.mts": "eslint",
|
||||
"eslint.config.ts": "eslint",
|
||||
"eslintrc": "eslint",
|
||||
"eslintrc.js": "eslint",
|
||||
"eslintrc.json": "eslint",
|
||||
"ex": "elixir",
|
||||
"exs": "elixir",
|
||||
"fish": "terminal",
|
||||
"flac": "audio",
|
||||
"fmp": "storage",
|
||||
"fp7": "storage",
|
||||
"frm": "storage",
|
||||
"fs": "fsharp",
|
||||
"gdb": "storage",
|
||||
"gif": "image",
|
||||
"gitattributes": "vcs",
|
||||
"gitignore": "vcs",
|
||||
"gitkeep": "vcs",
|
||||
"gitlab-ci.yml": "gitlab",
|
||||
"gitmodules": "vcs",
|
||||
"TAG_EDITMSG": "vcs",
|
||||
"MERGE_MSG": "vcs",
|
||||
"COMMIT_EDITMSG": "vcs",
|
||||
"NOTES_EDITMSG": "vcs",
|
||||
"EDIT_DESCRIPTION": "vcs",
|
||||
"gleam": "gleam",
|
||||
"go": "go",
|
||||
"gql": "graphql",
|
||||
"graphql": "graphql",
|
||||
"graphqls": "graphql",
|
||||
"h": "c",
|
||||
"handlebars": "code",
|
||||
"hbs": "template",
|
||||
"hcl": "hcl",
|
||||
"heex": "elixir",
|
||||
"heic": "image",
|
||||
"heif": "image",
|
||||
"hh": "cpp",
|
||||
"hpp": "cpp",
|
||||
"hrl": "erlang",
|
||||
"hs": "haskell",
|
||||
"htm": "html",
|
||||
"html": "html",
|
||||
"hxx": "cpp",
|
||||
"ib": "storage",
|
||||
"ico": "image",
|
||||
"ini": "settings",
|
||||
"inl": "cpp",
|
||||
"j2k": "image",
|
||||
"java": "java",
|
||||
"jfif": "image",
|
||||
"jl": "julia",
|
||||
"jp2": "image",
|
||||
"jpeg": "image",
|
||||
"jpg": "image",
|
||||
"js": "javascript",
|
||||
"json": "json",
|
||||
"jsonc": "storage",
|
||||
"jsx": "react",
|
||||
"jxl": "image",
|
||||
"kt": "kotlin",
|
||||
"ldf": "storage",
|
||||
"lock": "lock",
|
||||
"lockb": "bun",
|
||||
"log": "log",
|
||||
"lua": "lua",
|
||||
"luau": "luau",
|
||||
"m4a": "audio",
|
||||
"m4v": "video",
|
||||
"markdown": "markdown",
|
||||
"md": "markdown",
|
||||
"mdb": "storage",
|
||||
"mdf": "storage",
|
||||
"mdx": "document",
|
||||
"metadata": "code",
|
||||
"metal": "metal",
|
||||
"mjs": "javascript",
|
||||
"mjsx": "react",
|
||||
"mka": "audio",
|
||||
"mkv": "video",
|
||||
"ml": "ocaml",
|
||||
"mli": "ocaml",
|
||||
"mod": "go",
|
||||
"mov": "video",
|
||||
"mp3": "audio",
|
||||
"mp4": "video",
|
||||
"mts": "typescript",
|
||||
"mtsx": "react",
|
||||
"myd": "storage",
|
||||
"myi": "storage",
|
||||
"nim": "nim",
|
||||
"nix": "nix",
|
||||
"nu": "terminal",
|
||||
"odp": "document",
|
||||
"ods": "document",
|
||||
"odt": "document",
|
||||
"ogg": "audio",
|
||||
"opus": "audio",
|
||||
"otf": "font",
|
||||
"pcss": "css",
|
||||
"pdb": "storage",
|
||||
"pdf": "document",
|
||||
"php": "php",
|
||||
"plist": "template",
|
||||
"png": "image",
|
||||
"postcss": "css",
|
||||
"ppt": "document",
|
||||
"pptx": "document",
|
||||
"prettier.config.cjs": "prettier",
|
||||
"prettier.config.js": "prettier",
|
||||
"prettier.config.mjs": "prettier",
|
||||
"prettierignore": "prettier",
|
||||
"prettierrc": "prettier",
|
||||
"prettierrc.cjs": "prettier",
|
||||
"prettierrc.js": "prettier",
|
||||
"prettierrc.json": "prettier",
|
||||
"prettierrc.json5": "prettier",
|
||||
"prettierrc.mjs": "prettier",
|
||||
"prettierrc.toml": "prettier",
|
||||
"prettierrc.yaml": "prettier",
|
||||
"prettierrc.yml": "prettier",
|
||||
"prisma": "prisma",
|
||||
"profile": "terminal",
|
||||
"ps1": "terminal",
|
||||
"psd": "image",
|
||||
"py": "python",
|
||||
"qoi": "image",
|
||||
"r": "r",
|
||||
"rb": "ruby",
|
||||
"rebar.config": "erlang",
|
||||
"rkt": "code",
|
||||
"roc": "roc",
|
||||
"rs": "rust",
|
||||
"rtf": "document",
|
||||
"sass": "sass",
|
||||
"sav": "storage",
|
||||
"sc": "scala",
|
||||
"scala": "scala",
|
||||
"scm": "code",
|
||||
"scss": "sass",
|
||||
"sdf": "storage",
|
||||
"sh": "terminal",
|
||||
"sol": "solidity",
|
||||
"sql": "storage",
|
||||
"sqlite": "storage",
|
||||
"stylelint.config.cjs": "stylelint",
|
||||
"stylelint.config.js": "stylelint",
|
||||
"stylelint.config.mjs": "stylelint",
|
||||
"stylelintignore": "stylelint",
|
||||
"stylelintrc": "stylelint",
|
||||
"stylelintrc.cjs": "stylelint",
|
||||
"stylelintrc.js": "stylelint",
|
||||
"stylelintrc.json": "stylelint",
|
||||
"stylelintrc.mjs": "stylelint",
|
||||
"stylelintrc.yaml": "stylelint",
|
||||
"stylelintrc.yml": "stylelint",
|
||||
"svelte": "svelte",
|
||||
"svg": "image",
|
||||
"swift": "swift",
|
||||
"tcl": "tcl",
|
||||
"tf": "terraform",
|
||||
"tfvars": "terraform",
|
||||
"tiff": "image",
|
||||
"toml": "toml",
|
||||
"ts": "typescript",
|
||||
"tsv": "storage",
|
||||
"tsx": "react",
|
||||
"ttf": "font",
|
||||
"txt": "document",
|
||||
"v": "v",
|
||||
"vsh": "v",
|
||||
"vv": "v",
|
||||
"vue": "vue",
|
||||
"wav": "audio",
|
||||
"webm": "video",
|
||||
"webp": "image",
|
||||
"wma": "audio",
|
||||
"wmv": "video",
|
||||
"woff": "font",
|
||||
"woff2": "font",
|
||||
"work": "go",
|
||||
"wv": "audio",
|
||||
"xls": "document",
|
||||
"xlsx": "document",
|
||||
"xml": "template",
|
||||
"xrl": "erlang",
|
||||
"yaml": "settings",
|
||||
"yml": "settings",
|
||||
"yrl": "erlang",
|
||||
"zig": "zig",
|
||||
"zlogin": "terminal",
|
||||
"zsh": "terminal",
|
||||
"zsh_aliases": "terminal",
|
||||
"zsh_histfile": "terminal",
|
||||
"zsh_profile": "terminal",
|
||||
"zshenv": "terminal",
|
||||
"zshrc": "terminal"
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,10 @@
|
||||
"shift-escape": "workspace::ToggleZoom",
|
||||
"open": "workspace::Open",
|
||||
"ctrl-o": "workspace::Open",
|
||||
"ctrl-=": "zed::IncreaseBufferFontSize",
|
||||
"ctrl-+": "zed::IncreaseBufferFontSize",
|
||||
"ctrl--": "zed::DecreaseBufferFontSize",
|
||||
"ctrl-0": "zed::ResetBufferFontSize",
|
||||
"ctrl-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"ctrl-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"ctrl--": ["zed::DecreaseBufferFontSize", { "persist": false }],
|
||||
"ctrl-0": ["zed::ResetBufferFontSize", { "persist": false }],
|
||||
"ctrl-,": "zed::OpenSettings",
|
||||
"ctrl-q": "zed::Quit",
|
||||
"f11": "zed::ToggleFullScreen",
|
||||
@@ -510,13 +510,14 @@
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
"alt-tab": "editor::AcceptEditPrediction",
|
||||
"alt-l": "editor::AcceptEditPrediction"
|
||||
"alt-l": "editor::AcceptEditPrediction",
|
||||
"tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && edit_prediction && !edit_prediction_requires_modifier",
|
||||
"context": "Editor && edit_prediction_conflict",
|
||||
"bindings": {
|
||||
"tab": "editor::AcceptEditPrediction",
|
||||
"alt-tab": "editor::AcceptEditPrediction",
|
||||
"alt-l": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
@@ -649,8 +650,8 @@
|
||||
"right": "outline_panel::ExpandSelectedEntry",
|
||||
"alt-copy": "outline_panel::CopyPath",
|
||||
"ctrl-alt-c": "outline_panel::CopyPath",
|
||||
"alt-shift-copy": "outline_panel::CopyRelativePath",
|
||||
"alt-ctrl-shift-c": "outline_panel::CopyRelativePath",
|
||||
"alt-shift-copy": "workspace::CopyRelativePath",
|
||||
"alt-ctrl-shift-c": "workspace::CopyRelativePath",
|
||||
"alt-ctrl-r": "outline_panel::RevealInFileManager",
|
||||
"space": "outline_panel::Open",
|
||||
"shift-down": "menu::SelectNext",
|
||||
@@ -678,8 +679,8 @@
|
||||
"ctrl-v": "project_panel::Paste",
|
||||
"alt-copy": "project_panel::CopyPath",
|
||||
"ctrl-alt-c": "project_panel::CopyPath",
|
||||
"alt-shift-copy": "project_panel::CopyRelativePath",
|
||||
"alt-ctrl-shift-c": "project_panel::CopyRelativePath",
|
||||
"alt-shift-copy": "workspace::CopyRelativePath",
|
||||
"alt-ctrl-shift-c": "workspace::CopyRelativePath",
|
||||
"enter": "project_panel::Rename",
|
||||
"f2": "project_panel::Rename",
|
||||
"backspace": ["project_panel::Trash", { "skip_prompt": false }],
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
"cmd-shift-w": "workspace::CloseWindow",
|
||||
"shift-escape": "workspace::ToggleZoom",
|
||||
"cmd-o": "workspace::Open",
|
||||
"cmd-=": "zed::IncreaseBufferFontSize",
|
||||
"cmd-+": "zed::IncreaseBufferFontSize",
|
||||
"cmd--": "zed::DecreaseBufferFontSize",
|
||||
"cmd-0": "zed::ResetBufferFontSize",
|
||||
"cmd-=": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"cmd-+": ["zed::IncreaseBufferFontSize", { "persist": false }],
|
||||
"cmd--": ["zed::DecreaseBufferFontSize", { "persist": false }],
|
||||
"cmd-0": ["zed::ResetBufferFontSize", { "persist": false }],
|
||||
"cmd-,": "zed::OpenSettings",
|
||||
"cmd-q": "zed::Quit",
|
||||
"cmd-h": "zed::Hide",
|
||||
@@ -583,14 +583,15 @@
|
||||
{
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
"alt-tab": "editor::AcceptEditPrediction"
|
||||
"alt-tab": "editor::AcceptEditPrediction",
|
||||
"tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && edit_prediction && !edit_prediction_requires_modifier",
|
||||
"context": "Editor && edit_prediction_conflict",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"tab": "editor::AcceptEditPrediction"
|
||||
"alt-tab": "editor::AcceptEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -669,8 +670,8 @@
|
||||
"escape": "menu::Cancel",
|
||||
"left": "outline_panel::CollapseSelectedEntry",
|
||||
"right": "outline_panel::ExpandSelectedEntry",
|
||||
"cmd-alt-c": "outline_panel::CopyPath",
|
||||
"alt-cmd-shift-c": "outline_panel::CopyRelativePath",
|
||||
"cmd-alt-c": "workspace::CopyPath",
|
||||
"alt-cmd-shift-c": "workspace::CopyRelativePath",
|
||||
"alt-cmd-r": "outline_panel::RevealInFileManager",
|
||||
"space": "outline_panel::Open",
|
||||
"shift-down": "menu::SelectNext",
|
||||
@@ -691,8 +692,8 @@
|
||||
"cmd-x": "project_panel::Cut",
|
||||
"cmd-c": "project_panel::Copy",
|
||||
"cmd-v": "project_panel::Paste",
|
||||
"cmd-alt-c": "project_panel::CopyPath",
|
||||
"alt-cmd-shift-c": "project_panel::CopyRelativePath",
|
||||
"cmd-alt-c": "workspace::CopyPath",
|
||||
"alt-cmd-shift-c": "workspace::CopyRelativePath",
|
||||
"enter": "project_panel::Rename",
|
||||
"f2": "project_panel::Rename",
|
||||
"backspace": ["project_panel::Trash", { "skip_prompt": false }],
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"ctrl->": "zed::IncreaseBufferFontSize",
|
||||
"ctrl-<": "zed::DecreaseBufferFontSize",
|
||||
"ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-shift-j": "editor::JoinLines",
|
||||
"ctrl-d": "editor::DuplicateSelection",
|
||||
"ctrl-y": "editor::DeleteLine",
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
{
|
||||
"context": "Editor",
|
||||
"bindings": {
|
||||
"ctrl->": "zed::IncreaseBufferFontSize",
|
||||
"ctrl-<": "zed::DecreaseBufferFontSize",
|
||||
"ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
|
||||
"ctrl-shift-j": "editor::JoinLines",
|
||||
"cmd-d": "editor::DuplicateSelection",
|
||||
"cmd-backspace": "editor::DeleteLine",
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
"[ [": "vim::PreviousSectionStart",
|
||||
"[ ]": "vim::PreviousSectionEnd",
|
||||
"] m": "vim::NextMethodStart",
|
||||
"] M": "vim::NextMethodEnd",
|
||||
"] shift-m": "vim::NextMethodEnd",
|
||||
"[ m": "vim::PreviousMethodStart",
|
||||
"[ M": "vim::PreviousMethodEnd",
|
||||
"[ shift-m": "vim::PreviousMethodEnd",
|
||||
"[ *": "vim::PreviousComment",
|
||||
"[ /": "vim::PreviousComment",
|
||||
"] *": "vim::NextComment",
|
||||
@@ -696,7 +696,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && edit_prediction && !edit_prediction_requires_modifier",
|
||||
"context": "Editor && edit_prediction",
|
||||
"bindings": {
|
||||
// This is identical to the binding in the base keymap, but the vim bindings above to
|
||||
// "vim::Tab" shadow it, so it needs to be bound again.
|
||||
@@ -704,7 +704,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "os != macos && Editor && edit_prediction",
|
||||
"context": "os != macos && Editor && edit_prediction_conflict",
|
||||
"bindings": {
|
||||
// alt-l is provided as an alternative to tab/alt-tab. and will be displayed in the UI. This
|
||||
// is because alt-tab may not be available, as it is often used for window switching on Linux
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
"**/*.key",
|
||||
"**/*.cert",
|
||||
"**/*.crt",
|
||||
"**/.dev.vars",
|
||||
"**/secrets.yml"
|
||||
],
|
||||
// When to show edit predictions previews in buffer.
|
||||
@@ -1192,6 +1193,9 @@
|
||||
},
|
||||
"deepseek": {
|
||||
"api_url": "https://api.deepseek.com"
|
||||
},
|
||||
"mistral": {
|
||||
"api_url": "https://api.mistral.ai/v1"
|
||||
}
|
||||
},
|
||||
// Zed's Prettier integration settings.
|
||||
|
||||
@@ -1,549 +1,3 @@
|
||||
## [Andromeda](https://github.com/EliverLara/Andromeda)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 <eliverlara@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Cave Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Cave Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Dune Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Dune Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Estuary Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Estuary Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Forest Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Forest Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Heath Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Heath Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Lakeside Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Lakeside Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Plateau Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Plateau Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Savanna Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Savanna Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Seaside Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Seaside Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Sulphurpool Dark](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Atelier Sulphurpool Light](https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Ayu Dark](https://github.com/dempfi/ayu)
|
||||
|
||||
The MIT License (MIT)
|
||||
@@ -827,187 +281,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Rosé Pine](https://github.com/edunfelt/base16-rose-pine-scheme)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021 Emilia Dunfelt
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Rosé Pine Dawn](https://github.com/edunfelt/base16-rose-pine-scheme)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021 Emilia Dunfelt
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Rosé Pine Moon](https://github.com/edunfelt/base16-rose-pine-scheme)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021 Emilia Dunfelt
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Sandcastle](https://github.com/gessig/base16-sandcastle-scheme)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 George Essig
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Solarized Dark](https://github.com/altercation/solarized)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011 Ethan Schoonover
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Solarized Light](https://github.com/altercation/solarized)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011 Ethan Schoonover
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
## [Summercamp](https://github.com/zoefiri/base16-sc)
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Zoe FiriH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
********************************************************************************
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 <eliverlara@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,378 +0,0 @@
|
||||
{
|
||||
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
|
||||
"name": "Andromeda",
|
||||
"author": "Zed Industries",
|
||||
"themes": [
|
||||
{
|
||||
"name": "Andromeda",
|
||||
"appearance": "dark",
|
||||
"style": {
|
||||
"border": "#2b2f38ff",
|
||||
"border.variant": "#252931ff",
|
||||
"border.focused": "#183934ff",
|
||||
"border.selected": "#183934ff",
|
||||
"border.transparent": "#00000000",
|
||||
"border.disabled": "#292d37ff",
|
||||
"elevated_surface.background": "#21242bff",
|
||||
"surface.background": "#21242bff",
|
||||
"background": "#262933ff",
|
||||
"element.background": "#21242bff",
|
||||
"element.hover": "#252931ff",
|
||||
"element.active": "#2a2f39ff",
|
||||
"element.selected": "#2a2f39ff",
|
||||
"element.disabled": "#21242bff",
|
||||
"drop_target.background": "#aca8ae80",
|
||||
"ghost_element.background": "#00000000",
|
||||
"ghost_element.hover": "#252931ff",
|
||||
"ghost_element.active": "#2a2f39ff",
|
||||
"ghost_element.selected": "#2a2f39ff",
|
||||
"ghost_element.disabled": "#21242bff",
|
||||
"text": "#f7f7f8ff",
|
||||
"text.muted": "#aca8aeff",
|
||||
"text.placeholder": "#6b6b73ff",
|
||||
"text.disabled": "#6b6b73ff",
|
||||
"text.accent": "#10a793ff",
|
||||
"icon": "#f7f7f8ff",
|
||||
"icon.muted": "#aca8aeff",
|
||||
"icon.disabled": "#6b6b73ff",
|
||||
"icon.placeholder": "#aca8aeff",
|
||||
"icon.accent": "#10a793ff",
|
||||
"status_bar.background": "#262933ff",
|
||||
"title_bar.background": "#262933ff",
|
||||
"title_bar.inactive_background": "#21242bff",
|
||||
"toolbar.background": "#1e2025ff",
|
||||
"tab_bar.background": "#21242bff",
|
||||
"tab.inactive_background": "#21242bff",
|
||||
"tab.active_background": "#1e2025ff",
|
||||
"search.match_background": "#11a79366",
|
||||
"panel.background": "#21242bff",
|
||||
"panel.focused_border": "#10a793ff",
|
||||
"pane.focused_border": null,
|
||||
"scrollbar.thumb.background": "#f7f7f84c",
|
||||
"scrollbar.thumb.hover_background": "#252931ff",
|
||||
"scrollbar.thumb.border": "#252931ff",
|
||||
"scrollbar.track.background": "#00000000",
|
||||
"scrollbar.track.border": "#21232aff",
|
||||
"editor.foreground": "#f7f7f8ff",
|
||||
"editor.background": "#1e2025ff",
|
||||
"editor.gutter.background": "#1e2025ff",
|
||||
"editor.subheader.background": "#21242bff",
|
||||
"editor.active_line.background": "#21242bbf",
|
||||
"editor.highlighted_line.background": "#21242bff",
|
||||
"editor.line_number": "#565960",
|
||||
"editor.active_line_number": "#f8f8f9",
|
||||
"editor.hover_line_number": "#cbcdd0",
|
||||
"editor.invisible": "#64646dff",
|
||||
"editor.wrap_guide": "#f7f7f80d",
|
||||
"editor.active_wrap_guide": "#f7f7f81a",
|
||||
"editor.document_highlight.read_background": "#10a7931a",
|
||||
"editor.document_highlight.write_background": "#64646d66",
|
||||
"terminal.background": "#1e2025ff",
|
||||
"terminal.foreground": "#f7f7f8ff",
|
||||
"terminal.bright_foreground": "#f7f7f8ff",
|
||||
"terminal.dim_foreground": "#1e2025ff",
|
||||
"terminal.ansi.black": "#1e2025ff",
|
||||
"terminal.ansi.bright_black": "#40434cff",
|
||||
"terminal.ansi.dim_black": "#f7f7f8ff",
|
||||
"terminal.ansi.red": "#f82871ff",
|
||||
"terminal.ansi.bright_red": "#8e0f3aff",
|
||||
"terminal.ansi.dim_red": "#ffa3b5ff",
|
||||
"terminal.ansi.green": "#96df71ff",
|
||||
"terminal.ansi.bright_green": "#457c38ff",
|
||||
"terminal.ansi.dim_green": "#cef0b9ff",
|
||||
"terminal.ansi.yellow": "#fee56cff",
|
||||
"terminal.ansi.bright_yellow": "#958334ff",
|
||||
"terminal.ansi.dim_yellow": "#fef1b7ff",
|
||||
"terminal.ansi.blue": "#10a793ff",
|
||||
"terminal.ansi.bright_blue": "#1a5148ff",
|
||||
"terminal.ansi.dim_blue": "#9cd4c7ff",
|
||||
"terminal.ansi.magenta": "#c74cecff",
|
||||
"terminal.ansi.bright_magenta": "#682681ff",
|
||||
"terminal.ansi.dim_magenta": "#e7abf7ff",
|
||||
"terminal.ansi.cyan": "#08e7c5ff",
|
||||
"terminal.ansi.bright_cyan": "#008169ff",
|
||||
"terminal.ansi.dim_cyan": "#a9f4e1ff",
|
||||
"terminal.ansi.white": "#f7f7f8ff",
|
||||
"terminal.ansi.bright_white": "#f7f7f8ff",
|
||||
"terminal.ansi.dim_white": "#87858cff",
|
||||
"link_text.hover": "#10a793ff",
|
||||
"conflict": "#fee56cff",
|
||||
"conflict.background": "#5c5014ff",
|
||||
"conflict.border": "#796b26ff",
|
||||
"created": "#96df71ff",
|
||||
"created.background": "#184618ff",
|
||||
"created.border": "#306129ff",
|
||||
"deleted": "#f82871ff",
|
||||
"deleted.background": "#54051bff",
|
||||
"deleted.border": "#72092aff",
|
||||
"error": "#f82871ff",
|
||||
"error.background": "#54051bff",
|
||||
"error.border": "#72092aff",
|
||||
"hidden": "#6b6b73ff",
|
||||
"hidden.background": "#262933ff",
|
||||
"hidden.border": "#292d37ff",
|
||||
"hint": "#618399ff",
|
||||
"hint.background": "#12231fff",
|
||||
"hint.border": "#183934ff",
|
||||
"ignored": "#6b6b73ff",
|
||||
"ignored.background": "#262933ff",
|
||||
"ignored.border": "#2b2f38ff",
|
||||
"info": "#10a793ff",
|
||||
"info.background": "#12231fff",
|
||||
"info.border": "#183934ff",
|
||||
"modified": "#fee56cff",
|
||||
"modified.background": "#5c5014ff",
|
||||
"modified.border": "#796b26ff",
|
||||
"predictive": "#315f70ff",
|
||||
"predictive.background": "#184618ff",
|
||||
"predictive.border": "#306129ff",
|
||||
"renamed": "#10a793ff",
|
||||
"renamed.background": "#12231fff",
|
||||
"renamed.border": "#183934ff",
|
||||
"success": "#96df71ff",
|
||||
"success.background": "#184618ff",
|
||||
"success.border": "#306129ff",
|
||||
"unreachable": "#aca8aeff",
|
||||
"unreachable.background": "#262933ff",
|
||||
"unreachable.border": "#2b2f38ff",
|
||||
"warning": "#fee56cff",
|
||||
"warning.background": "#5c5014ff",
|
||||
"warning.border": "#796b26ff",
|
||||
"players": [
|
||||
{
|
||||
"cursor": "#10a793ff",
|
||||
"background": "#10a793ff",
|
||||
"selection": "#10a7933d"
|
||||
},
|
||||
{
|
||||
"cursor": "#c74cecff",
|
||||
"background": "#c74cecff",
|
||||
"selection": "#c74cec3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#f29c14ff",
|
||||
"background": "#f29c14ff",
|
||||
"selection": "#f29c143d"
|
||||
},
|
||||
{
|
||||
"cursor": "#893ea6ff",
|
||||
"background": "#893ea6ff",
|
||||
"selection": "#893ea63d"
|
||||
},
|
||||
{
|
||||
"cursor": "#08e7c5ff",
|
||||
"background": "#08e7c5ff",
|
||||
"selection": "#08e7c53d"
|
||||
},
|
||||
{
|
||||
"cursor": "#f82871ff",
|
||||
"background": "#f82871ff",
|
||||
"selection": "#f828713d"
|
||||
},
|
||||
{
|
||||
"cursor": "#fee56cff",
|
||||
"background": "#fee56cff",
|
||||
"selection": "#fee56c3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#96df71ff",
|
||||
"background": "#96df71ff",
|
||||
"selection": "#96df713d"
|
||||
}
|
||||
],
|
||||
"syntax": {
|
||||
"attribute": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"boolean": {
|
||||
"color": "#96df71ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment": {
|
||||
"color": "#afabb1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "#afabb1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constant": {
|
||||
"color": "#96df71ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constructor": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"embedded": {
|
||||
"color": "#f7f7f8ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"enum": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"function": {
|
||||
"color": "#fee56cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"hint": {
|
||||
"color": "#618399ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"keyword": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"label": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"link_text": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "#96df71ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"number": {
|
||||
"color": "#96df71ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"operator": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"predictive": {
|
||||
"color": "#315f70ff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"preproc": {
|
||||
"color": "#f7f7f8ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"primary": {
|
||||
"color": "#f7f7f8ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"property": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation": {
|
||||
"color": "#d8d5dbff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.bracket": {
|
||||
"color": "#d8d5dbff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.delimiter": {
|
||||
"color": "#d8d5dbff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
"color": "#d8d5dbff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.special": {
|
||||
"color": "#d8d5dbff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "#afabb1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special.symbol": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"tag": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "#f29c14ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"title": {
|
||||
"color": "#f7f7f8ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"type": {
|
||||
"color": "#08e7c5ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#f7f7f8ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variant": {
|
||||
"color": "#10a793ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023 Bram de Haan, http://atelierbramdehaan.nl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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",
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2021 Emilia Dunfelt
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 George Essig
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,378 +0,0 @@
|
||||
{
|
||||
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
|
||||
"name": "Sandcastle",
|
||||
"author": "Zed Industries",
|
||||
"themes": [
|
||||
{
|
||||
"name": "Sandcastle",
|
||||
"appearance": "dark",
|
||||
"style": {
|
||||
"border": "#3d4350ff",
|
||||
"border.variant": "#313741ff",
|
||||
"border.focused": "#223131ff",
|
||||
"border.selected": "#223131ff",
|
||||
"border.transparent": "#00000000",
|
||||
"border.disabled": "#393f4aff",
|
||||
"elevated_surface.background": "#2b3038ff",
|
||||
"surface.background": "#2b3038ff",
|
||||
"background": "#333944ff",
|
||||
"element.background": "#2b3038ff",
|
||||
"element.hover": "#313741ff",
|
||||
"element.active": "#3d4350ff",
|
||||
"element.selected": "#3d4350ff",
|
||||
"element.disabled": "#2b3038ff",
|
||||
"drop_target.background": "#a6978280",
|
||||
"ghost_element.background": "#00000000",
|
||||
"ghost_element.hover": "#313741ff",
|
||||
"ghost_element.active": "#3d4350ff",
|
||||
"ghost_element.selected": "#3d4350ff",
|
||||
"ghost_element.disabled": "#2b3038ff",
|
||||
"text": "#fdf4c1ff",
|
||||
"text.muted": "#a69782ff",
|
||||
"text.placeholder": "#827568ff",
|
||||
"text.disabled": "#827568ff",
|
||||
"text.accent": "#518b8bff",
|
||||
"icon": "#fdf4c1ff",
|
||||
"icon.muted": "#a69782ff",
|
||||
"icon.disabled": "#827568ff",
|
||||
"icon.placeholder": "#a69782ff",
|
||||
"icon.accent": "#518b8bff",
|
||||
"status_bar.background": "#333944ff",
|
||||
"title_bar.background": "#333944ff",
|
||||
"title_bar.inactive_background": "#2b3038ff",
|
||||
"toolbar.background": "#282c33ff",
|
||||
"tab_bar.background": "#2b3038ff",
|
||||
"tab.inactive_background": "#2b3038ff",
|
||||
"tab.active_background": "#282c33ff",
|
||||
"search.match_background": "#528b8b66",
|
||||
"panel.background": "#2b3038ff",
|
||||
"panel.focused_border": "#518b8bff",
|
||||
"pane.focused_border": null,
|
||||
"scrollbar.thumb.background": "#fdf4c14c",
|
||||
"scrollbar.thumb.hover_background": "#313741ff",
|
||||
"scrollbar.thumb.border": "#313741ff",
|
||||
"scrollbar.track.background": "#00000000",
|
||||
"scrollbar.track.border": "#2a2f38ff",
|
||||
"editor.foreground": "#fdf4c1ff",
|
||||
"editor.background": "#282c33ff",
|
||||
"editor.gutter.background": "#282c33ff",
|
||||
"editor.subheader.background": "#2b3038ff",
|
||||
"editor.active_line.background": "#2b3038bf",
|
||||
"editor.highlighted_line.background": "#2b3038ff",
|
||||
"editor.line_number": "#6b6b61",
|
||||
"editor.active_line_number": "#dbdbd7",
|
||||
"editor.hover_line_number": "#b6b6af",
|
||||
"editor.invisible": "#7c6f64ff",
|
||||
"editor.wrap_guide": "#fdf4c10d",
|
||||
"editor.active_wrap_guide": "#fdf4c11a",
|
||||
"editor.document_highlight.read_background": "#518b8b1a",
|
||||
"editor.document_highlight.write_background": "#7c6f6466",
|
||||
"terminal.background": "#282c33ff",
|
||||
"terminal.foreground": "#fdf4c1ff",
|
||||
"terminal.bright_foreground": "#fdf4c1ff",
|
||||
"terminal.dim_foreground": "#282c33ff",
|
||||
"terminal.ansi.black": "#282c33ff",
|
||||
"terminal.ansi.bright_black": "#5e5753ff",
|
||||
"terminal.ansi.dim_black": "#fdf4c1ff",
|
||||
"terminal.ansi.red": "#b3627aff",
|
||||
"terminal.ansi.bright_red": "#57333dff",
|
||||
"terminal.ansi.dim_red": "#dcb0bbff",
|
||||
"terminal.ansi.green": "#83a598ff",
|
||||
"terminal.ansi.bright_green": "#414f4aff",
|
||||
"terminal.ansi.dim_green": "#c0d2cbff",
|
||||
"terminal.ansi.yellow": "#a07d3aff",
|
||||
"terminal.ansi.bright_yellow": "#4e3f22ff",
|
||||
"terminal.ansi.dim_yellow": "#d3bd9aff",
|
||||
"terminal.ansi.blue": "#518b8bff",
|
||||
"terminal.ansi.bright_blue": "#2c4444ff",
|
||||
"terminal.ansi.dim_blue": "#a8c4c4ff",
|
||||
"terminal.ansi.magenta": "#a87222ff",
|
||||
"terminal.ansi.bright_magenta": "#523918ff",
|
||||
"terminal.ansi.dim_magenta": "#dab78eff",
|
||||
"terminal.ansi.cyan": "#83a598ff",
|
||||
"terminal.ansi.bright_cyan": "#414f4aff",
|
||||
"terminal.ansi.dim_cyan": "#c0d2cbff",
|
||||
"terminal.ansi.white": "#fdf4c1ff",
|
||||
"terminal.ansi.bright_white": "#fdf4c1ff",
|
||||
"terminal.ansi.dim_white": "#958776ff",
|
||||
"link_text.hover": "#518b8bff",
|
||||
"conflict": "#a07d3aff",
|
||||
"conflict.background": "#231d12ff",
|
||||
"conflict.border": "#392e19ff",
|
||||
"created": "#83a598ff",
|
||||
"created.background": "#1e2321ff",
|
||||
"created.border": "#303a36ff",
|
||||
"deleted": "#b3627aff",
|
||||
"deleted.background": "#26191cff",
|
||||
"deleted.border": "#3e272dff",
|
||||
"error": "#b3627aff",
|
||||
"error.background": "#26191cff",
|
||||
"error.border": "#3e272dff",
|
||||
"hidden": "#827568ff",
|
||||
"hidden.background": "#333944ff",
|
||||
"hidden.border": "#393f4aff",
|
||||
"hint": "#727d68ff",
|
||||
"hint.background": "#171e1eff",
|
||||
"hint.border": "#223131ff",
|
||||
"ignored": "#827568ff",
|
||||
"ignored.background": "#333944ff",
|
||||
"ignored.border": "#3d4350ff",
|
||||
"info": "#518b8bff",
|
||||
"info.background": "#171e1eff",
|
||||
"info.border": "#223131ff",
|
||||
"modified": "#a07d3aff",
|
||||
"modified.background": "#231d12ff",
|
||||
"modified.border": "#392e19ff",
|
||||
"predictive": "#5c6152ff",
|
||||
"predictive.background": "#1e2321ff",
|
||||
"predictive.border": "#303a36ff",
|
||||
"renamed": "#518b8bff",
|
||||
"renamed.background": "#171e1eff",
|
||||
"renamed.border": "#223131ff",
|
||||
"success": "#83a598ff",
|
||||
"success.background": "#1e2321ff",
|
||||
"success.border": "#303a36ff",
|
||||
"unreachable": "#a69782ff",
|
||||
"unreachable.background": "#333944ff",
|
||||
"unreachable.border": "#3d4350ff",
|
||||
"warning": "#a07d3aff",
|
||||
"warning.background": "#231d12ff",
|
||||
"warning.border": "#392e19ff",
|
||||
"players": [
|
||||
{
|
||||
"cursor": "#518b8bff",
|
||||
"background": "#518b8bff",
|
||||
"selection": "#518b8b3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#a87222ff",
|
||||
"background": "#a87222ff",
|
||||
"selection": "#a872223d"
|
||||
},
|
||||
{
|
||||
"cursor": "#a07d3aff",
|
||||
"background": "#a07d3aff",
|
||||
"selection": "#a07d3a3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#d75f5fff",
|
||||
"background": "#d75f5fff",
|
||||
"selection": "#d75f5f3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#83a598ff",
|
||||
"background": "#83a598ff",
|
||||
"selection": "#83a5983d"
|
||||
},
|
||||
{
|
||||
"cursor": "#b3627aff",
|
||||
"background": "#b3627aff",
|
||||
"selection": "#b3627a3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#a07d3aff",
|
||||
"background": "#a07d3aff",
|
||||
"selection": "#a07d3a3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#83a598ff",
|
||||
"background": "#83a598ff",
|
||||
"selection": "#83a5983d"
|
||||
}
|
||||
],
|
||||
"syntax": {
|
||||
"attribute": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"boolean": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment": {
|
||||
"color": "#a89984ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "#a89984ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constant": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constructor": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"embedded": {
|
||||
"color": "#fdf4c1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"enum": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"function": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"hint": {
|
||||
"color": "#727d68ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"keyword": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"label": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"link_text": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"number": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"operator": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"predictive": {
|
||||
"color": "#5c6152ff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"preproc": {
|
||||
"color": "#fdf4c1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"primary": {
|
||||
"color": "#fdf4c1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"property": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation": {
|
||||
"color": "#d5c5a1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.bracket": {
|
||||
"color": "#d5c5a1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.delimiter": {
|
||||
"color": "#d5c5a1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
"color": "#d5c5a1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.special": {
|
||||
"color": "#d5c5a1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "#a89984ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special.symbol": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"tag": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "#a07d3aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"title": {
|
||||
"color": "#fdf4c1ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"type": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#fdf4c1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variant": {
|
||||
"color": "#518b8bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011 Ethan Schoonover
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,749 +0,0 @@
|
||||
{
|
||||
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
|
||||
"name": "Solarized",
|
||||
"author": "Zed Industries",
|
||||
"themes": [
|
||||
{
|
||||
"name": "Solarized Dark",
|
||||
"appearance": "dark",
|
||||
"style": {
|
||||
"border": "#2b4e58ff",
|
||||
"border.variant": "#053541ff",
|
||||
"border.focused": "#1b3149ff",
|
||||
"border.selected": "#1b3149ff",
|
||||
"border.transparent": "#00000000",
|
||||
"border.disabled": "#19424dff",
|
||||
"elevated_surface.background": "#04313bff",
|
||||
"surface.background": "#04313bff",
|
||||
"background": "#073743ff",
|
||||
"element.background": "#04313bff",
|
||||
"element.hover": "#053541ff",
|
||||
"element.active": "#294d58ff",
|
||||
"element.selected": "#294d58ff",
|
||||
"element.disabled": "#04313bff",
|
||||
"drop_target.background": "#93a1a180",
|
||||
"ghost_element.background": "#00000000",
|
||||
"ghost_element.hover": "#053541ff",
|
||||
"ghost_element.active": "#294d58ff",
|
||||
"ghost_element.selected": "#294d58ff",
|
||||
"ghost_element.disabled": "#04313bff",
|
||||
"text": "#fdf6e3ff",
|
||||
"text.muted": "#93a1a1ff",
|
||||
"text.placeholder": "#6f8389ff",
|
||||
"text.disabled": "#6f8389ff",
|
||||
"text.accent": "#278ad1ff",
|
||||
"icon": "#fdf6e3ff",
|
||||
"icon.muted": "#93a1a1ff",
|
||||
"icon.disabled": "#6f8389ff",
|
||||
"icon.placeholder": "#93a1a1ff",
|
||||
"icon.accent": "#278ad1ff",
|
||||
"status_bar.background": "#073743ff",
|
||||
"title_bar.background": "#073743ff",
|
||||
"title_bar.inactive_background": "#04313bff",
|
||||
"toolbar.background": "#002a35ff",
|
||||
"tab_bar.background": "#04313bff",
|
||||
"tab.inactive_background": "#04313bff",
|
||||
"tab.active_background": "#002a35ff",
|
||||
"search.match_background": "#288bd166",
|
||||
"panel.background": "#04313bff",
|
||||
"panel.focused_border": "#278ad1ff",
|
||||
"pane.focused_border": null,
|
||||
"scrollbar.thumb.background": "#fdf6e34c",
|
||||
"scrollbar.thumb.hover_background": "#053541ff",
|
||||
"scrollbar.thumb.border": "#053541ff",
|
||||
"scrollbar.track.background": "#00000000",
|
||||
"scrollbar.track.border": "#022f3bff",
|
||||
"editor.foreground": "#fdf6e3ff",
|
||||
"editor.background": "#002a35ff",
|
||||
"editor.gutter.background": "#002a35ff",
|
||||
"editor.subheader.background": "#04313bff",
|
||||
"editor.active_line.background": "#04313bbf",
|
||||
"editor.highlighted_line.background": "#04313bff",
|
||||
"editor.line_number": "#5a6d6f",
|
||||
"editor.active_line_number": "#e3e8e8",
|
||||
"editor.hover_line_number": "#abb9ba",
|
||||
"editor.invisible": "#6c8287ff",
|
||||
"editor.wrap_guide": "#fdf6e30d",
|
||||
"editor.active_wrap_guide": "#fdf6e31a",
|
||||
"editor.document_highlight.read_background": "#278ad11a",
|
||||
"editor.document_highlight.write_background": "#6c828766",
|
||||
"terminal.background": "#002a35ff",
|
||||
"terminal.foreground": "#fdf6e3ff",
|
||||
"terminal.bright_foreground": "#fdf6e3ff",
|
||||
"terminal.dim_foreground": "#002a35ff",
|
||||
"terminal.ansi.black": "#002a35ff",
|
||||
"terminal.ansi.bright_black": "#5c7279ff",
|
||||
"terminal.ansi.dim_black": "#fdf6e3ff",
|
||||
"terminal.ansi.red": "#dc3330ff",
|
||||
"terminal.ansi.bright_red": "#7d181cff",
|
||||
"terminal.ansi.dim_red": "#faa091ff",
|
||||
"terminal.ansi.green": "#849903ff",
|
||||
"terminal.ansi.bright_green": "#434a10ff",
|
||||
"terminal.ansi.dim_green": "#c6cb8bff",
|
||||
"terminal.ansi.yellow": "#b58902ff",
|
||||
"terminal.ansi.bright_yellow": "#5d430fff",
|
||||
"terminal.ansi.dim_yellow": "#e0c189ff",
|
||||
"terminal.ansi.blue": "#278ad1ff",
|
||||
"terminal.ansi.bright_blue": "#214365ff",
|
||||
"terminal.ansi.dim_blue": "#a5c3e9ff",
|
||||
"terminal.ansi.magenta": "#d33781ff",
|
||||
"terminal.ansi.bright_magenta": "#6f1f3fff",
|
||||
"terminal.ansi.dim_magenta": "#f0a2beff",
|
||||
"terminal.ansi.cyan": "#2ba198ff",
|
||||
"terminal.ansi.bright_cyan": "#204e4aff",
|
||||
"terminal.ansi.dim_cyan": "#9fd0cbff",
|
||||
"terminal.ansi.white": "#fdf6e3ff",
|
||||
"terminal.ansi.bright_white": "#fdf6e3ff",
|
||||
"terminal.ansi.dim_white": "#7b8e91ff",
|
||||
"link_text.hover": "#278ad1ff",
|
||||
"conflict": "#b58902ff",
|
||||
"conflict.background": "#2e1d0cff",
|
||||
"conflict.border": "#47300fff",
|
||||
"created": "#849903ff",
|
||||
"created.background": "#1e210cff",
|
||||
"created.border": "#313510ff",
|
||||
"deleted": "#dc3330ff",
|
||||
"deleted.background": "#4a080eff",
|
||||
"deleted.border": "#641015ff",
|
||||
"error": "#dc3330ff",
|
||||
"error.background": "#4a080eff",
|
||||
"error.border": "#641015ff",
|
||||
"hidden": "#6f8389ff",
|
||||
"hidden.background": "#073743ff",
|
||||
"hidden.border": "#19424dff",
|
||||
"hint": "#4f8297ff",
|
||||
"hint.background": "#141f2cff",
|
||||
"hint.border": "#1b3149ff",
|
||||
"ignored": "#6f8389ff",
|
||||
"ignored.background": "#073743ff",
|
||||
"ignored.border": "#2b4e58ff",
|
||||
"info": "#278ad1ff",
|
||||
"info.background": "#141f2cff",
|
||||
"info.border": "#1b3149ff",
|
||||
"modified": "#b58902ff",
|
||||
"modified.background": "#2e1d0cff",
|
||||
"modified.border": "#47300fff",
|
||||
"predictive": "#3f718bff",
|
||||
"predictive.background": "#1e210cff",
|
||||
"predictive.border": "#313510ff",
|
||||
"renamed": "#278ad1ff",
|
||||
"renamed.background": "#141f2cff",
|
||||
"renamed.border": "#1b3149ff",
|
||||
"success": "#849903ff",
|
||||
"success.background": "#1e210cff",
|
||||
"success.border": "#313510ff",
|
||||
"unreachable": "#93a1a1ff",
|
||||
"unreachable.background": "#073743ff",
|
||||
"unreachable.border": "#2b4e58ff",
|
||||
"warning": "#b58902ff",
|
||||
"warning.background": "#2e1d0cff",
|
||||
"warning.border": "#47300fff",
|
||||
"players": [
|
||||
{
|
||||
"cursor": "#278ad1ff",
|
||||
"background": "#278ad1ff",
|
||||
"selection": "#278ad13d"
|
||||
},
|
||||
{
|
||||
"cursor": "#d33781ff",
|
||||
"background": "#d33781ff",
|
||||
"selection": "#d337813d"
|
||||
},
|
||||
{
|
||||
"cursor": "#cb4b16ff",
|
||||
"background": "#cb4b16ff",
|
||||
"selection": "#cb4b163d"
|
||||
},
|
||||
{
|
||||
"cursor": "#6c71c4ff",
|
||||
"background": "#6c71c4ff",
|
||||
"selection": "#6c71c43d"
|
||||
},
|
||||
{
|
||||
"cursor": "#2ba198ff",
|
||||
"background": "#2ba198ff",
|
||||
"selection": "#2ba1983d"
|
||||
},
|
||||
{
|
||||
"cursor": "#dc3330ff",
|
||||
"background": "#dc3330ff",
|
||||
"selection": "#dc33303d"
|
||||
},
|
||||
{
|
||||
"cursor": "#b58902ff",
|
||||
"background": "#b58902ff",
|
||||
"selection": "#b589023d"
|
||||
},
|
||||
{
|
||||
"cursor": "#849903ff",
|
||||
"background": "#849903ff",
|
||||
"selection": "#8499033d"
|
||||
}
|
||||
],
|
||||
"syntax": {
|
||||
"attribute": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"boolean": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment": {
|
||||
"color": "#99a5a4ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "#99a5a4ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constant": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constructor": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"embedded": {
|
||||
"color": "#fdf6e3ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"enum": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"function": {
|
||||
"color": "#b58902ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"hint": {
|
||||
"color": "#4f8297ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"keyword": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"label": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"link_text": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"number": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"operator": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"predictive": {
|
||||
"color": "#3f718bff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"preproc": {
|
||||
"color": "#fdf6e3ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"primary": {
|
||||
"color": "#fdf6e3ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"property": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation": {
|
||||
"color": "#efe9d6ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.bracket": {
|
||||
"color": "#efe9d6ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.delimiter": {
|
||||
"color": "#efe9d6ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
"color": "#efe9d6ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.special": {
|
||||
"color": "#efe9d6ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "#99a5a4ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special.symbol": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"tag": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"title": {
|
||||
"color": "#fdf6e3ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"type": {
|
||||
"color": "#2ba198ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#fdf6e3ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variant": {
|
||||
"color": "#278ad1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Solarized Light",
|
||||
"appearance": "light",
|
||||
"style": {
|
||||
"border": "#9faaa8ff",
|
||||
"border.variant": "#dcdacbff",
|
||||
"border.focused": "#bfd3efff",
|
||||
"border.selected": "#bfd3efff",
|
||||
"border.transparent": "#00000000",
|
||||
"border.disabled": "#b6bcb5ff",
|
||||
"elevated_surface.background": "#f3eddaff",
|
||||
"surface.background": "#f3eddaff",
|
||||
"background": "#cfd0c4ff",
|
||||
"element.background": "#f3eddaff",
|
||||
"element.hover": "#dcdacbff",
|
||||
"element.active": "#a2aca9ff",
|
||||
"element.selected": "#a2aca9ff",
|
||||
"element.disabled": "#f3eddaff",
|
||||
"drop_target.background": "#34555e80",
|
||||
"ghost_element.background": "#00000000",
|
||||
"ghost_element.hover": "#dcdacbff",
|
||||
"ghost_element.active": "#a2aca9ff",
|
||||
"ghost_element.selected": "#a2aca9ff",
|
||||
"ghost_element.disabled": "#f3eddaff",
|
||||
"text": "#002a35ff",
|
||||
"text.muted": "#34555eff",
|
||||
"text.placeholder": "#6a7f86ff",
|
||||
"text.disabled": "#6a7f86ff",
|
||||
"text.accent": "#288bd1ff",
|
||||
"icon": "#002a35ff",
|
||||
"icon.muted": "#34555eff",
|
||||
"icon.disabled": "#6a7f86ff",
|
||||
"icon.placeholder": "#34555eff",
|
||||
"icon.accent": "#288bd1ff",
|
||||
"status_bar.background": "#cfd0c4ff",
|
||||
"title_bar.background": "#cfd0c4ff",
|
||||
"title_bar.inactive_background": "#f3eddaff",
|
||||
"toolbar.background": "#fdf6e3ff",
|
||||
"tab_bar.background": "#f3eddaff",
|
||||
"tab.inactive_background": "#f3eddaff",
|
||||
"tab.active_background": "#fdf6e3ff",
|
||||
"search.match_background": "#298bd166",
|
||||
"panel.background": "#f3eddaff",
|
||||
"panel.focused_border": "#288bd1ff",
|
||||
"pane.focused_border": null,
|
||||
"scrollbar.thumb.background": "#002a354c",
|
||||
"scrollbar.thumb.hover_background": "#dcdacbff",
|
||||
"scrollbar.thumb.border": "#dcdacbff",
|
||||
"scrollbar.track.background": "#00000000",
|
||||
"scrollbar.track.border": "#f5eedbff",
|
||||
"editor.foreground": "#002a35ff",
|
||||
"editor.background": "#fdf6e3ff",
|
||||
"editor.gutter.background": "#fdf6e3ff",
|
||||
"editor.subheader.background": "#f3eddaff",
|
||||
"editor.active_line.background": "#f3eddabf",
|
||||
"editor.highlighted_line.background": "#f3eddaff",
|
||||
"editor.line_number": "#a8ad9f",
|
||||
"editor.active_line_number": "#272923",
|
||||
"editor.hover_line_number": "#42453b",
|
||||
"editor.invisible": "#6c8287ff",
|
||||
"editor.wrap_guide": "#002a350d",
|
||||
"editor.active_wrap_guide": "#002a351a",
|
||||
"editor.document_highlight.read_background": "#288bd11a",
|
||||
"editor.document_highlight.write_background": "#6c828766",
|
||||
"terminal.background": "#fdf6e3ff",
|
||||
"terminal.foreground": "#002a35ff",
|
||||
"terminal.bright_foreground": "#002a35ff",
|
||||
"terminal.dim_foreground": "#fdf6e3ff",
|
||||
"terminal.ansi.black": "#fdf6e3ff",
|
||||
"terminal.ansi.bright_black": "#7b8e91ff",
|
||||
"terminal.ansi.dim_black": "#002a35ff",
|
||||
"terminal.ansi.red": "#dc3330ff",
|
||||
"terminal.ansi.bright_red": "#faa091ff",
|
||||
"terminal.ansi.dim_red": "#7d181cff",
|
||||
"terminal.ansi.green": "#849903ff",
|
||||
"terminal.ansi.bright_green": "#c6cb8bff",
|
||||
"terminal.ansi.dim_green": "#434a10ff",
|
||||
"terminal.ansi.yellow": "#b58903ff",
|
||||
"terminal.ansi.bright_yellow": "#e0c189ff",
|
||||
"terminal.ansi.dim_yellow": "#5d430fff",
|
||||
"terminal.ansi.blue": "#288bd1ff",
|
||||
"terminal.ansi.bright_blue": "#a5c3e9ff",
|
||||
"terminal.ansi.dim_blue": "#214365ff",
|
||||
"terminal.ansi.magenta": "#d33781ff",
|
||||
"terminal.ansi.bright_magenta": "#f0a2beff",
|
||||
"terminal.ansi.dim_magenta": "#6f1f3fff",
|
||||
"terminal.ansi.cyan": "#2ba198ff",
|
||||
"terminal.ansi.bright_cyan": "#9fd0cbff",
|
||||
"terminal.ansi.dim_cyan": "#204e4aff",
|
||||
"terminal.ansi.white": "#002a35ff",
|
||||
"terminal.ansi.bright_white": "#002a35ff",
|
||||
"terminal.ansi.dim_white": "#5c7279ff",
|
||||
"link_text.hover": "#288bd1ff",
|
||||
"conflict": "#b58903ff",
|
||||
"conflict.background": "#f5e6d0ff",
|
||||
"conflict.border": "#ebd3aaff",
|
||||
"created": "#849903ff",
|
||||
"created.background": "#e9ead0ff",
|
||||
"created.border": "#d6d9abff",
|
||||
"deleted": "#dc3330ff",
|
||||
"deleted.background": "#ffd9d2ff",
|
||||
"deleted.border": "#ffbbafff",
|
||||
"error": "#dc3330ff",
|
||||
"error.background": "#ffd9d2ff",
|
||||
"error.border": "#ffbbafff",
|
||||
"hidden": "#6a7f86ff",
|
||||
"hidden.background": "#cfd0c4ff",
|
||||
"hidden.border": "#b6bcb5ff",
|
||||
"hint": "#5789a3ff",
|
||||
"hint.background": "#dbe6f6ff",
|
||||
"hint.border": "#bfd3efff",
|
||||
"ignored": "#6a7f86ff",
|
||||
"ignored.background": "#cfd0c4ff",
|
||||
"ignored.border": "#9faaa8ff",
|
||||
"info": "#288bd1ff",
|
||||
"info.background": "#dbe6f6ff",
|
||||
"info.border": "#bfd3efff",
|
||||
"modified": "#b58903ff",
|
||||
"modified.background": "#f5e6d0ff",
|
||||
"modified.border": "#ebd3aaff",
|
||||
"predictive": "#679aafff",
|
||||
"predictive.background": "#e9ead0ff",
|
||||
"predictive.border": "#d6d9abff",
|
||||
"renamed": "#288bd1ff",
|
||||
"renamed.background": "#dbe6f6ff",
|
||||
"renamed.border": "#bfd3efff",
|
||||
"success": "#849903ff",
|
||||
"success.background": "#e9ead0ff",
|
||||
"success.border": "#d6d9abff",
|
||||
"unreachable": "#34555eff",
|
||||
"unreachable.background": "#cfd0c4ff",
|
||||
"unreachable.border": "#9faaa8ff",
|
||||
"warning": "#b58903ff",
|
||||
"warning.background": "#f5e6d0ff",
|
||||
"warning.border": "#ebd3aaff",
|
||||
"players": [
|
||||
{
|
||||
"cursor": "#288bd1ff",
|
||||
"background": "#288bd1ff",
|
||||
"selection": "#288bd13d"
|
||||
},
|
||||
{
|
||||
"cursor": "#d33781ff",
|
||||
"background": "#d33781ff",
|
||||
"selection": "#d337813d"
|
||||
},
|
||||
{
|
||||
"cursor": "#cb4b16ff",
|
||||
"background": "#cb4b16ff",
|
||||
"selection": "#cb4b173d"
|
||||
},
|
||||
{
|
||||
"cursor": "#6c71c3ff",
|
||||
"background": "#6c71c3ff",
|
||||
"selection": "#6c71c33d"
|
||||
},
|
||||
{
|
||||
"cursor": "#2ba198ff",
|
||||
"background": "#2ba198ff",
|
||||
"selection": "#2ba1983d"
|
||||
},
|
||||
{
|
||||
"cursor": "#dc3330ff",
|
||||
"background": "#dc3330ff",
|
||||
"selection": "#dc33303d"
|
||||
},
|
||||
{
|
||||
"cursor": "#b58903ff",
|
||||
"background": "#b58903ff",
|
||||
"selection": "#b589033d"
|
||||
},
|
||||
{
|
||||
"cursor": "#849903ff",
|
||||
"background": "#849903ff",
|
||||
"selection": "#8499033d"
|
||||
}
|
||||
],
|
||||
"syntax": {
|
||||
"attribute": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"boolean": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment": {
|
||||
"color": "#30525bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "#30525bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constant": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constructor": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"embedded": {
|
||||
"color": "#002a35ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"enum": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"function": {
|
||||
"color": "#b58903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"hint": {
|
||||
"color": "#5789a3ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"keyword": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"label": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"link_text": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"number": {
|
||||
"color": "#849903ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"operator": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"predictive": {
|
||||
"color": "#679aafff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"preproc": {
|
||||
"color": "#002a35ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"primary": {
|
||||
"color": "#002a35ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"property": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation": {
|
||||
"color": "#04333eff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.bracket": {
|
||||
"color": "#04333eff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.delimiter": {
|
||||
"color": "#04333eff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
"color": "#04333eff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.special": {
|
||||
"color": "#04333eff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "#30525bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special.symbol": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"tag": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "#cb4b16ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"title": {
|
||||
"color": "#002a35ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"type": {
|
||||
"color": "#2ba198ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#002a35ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variant": {
|
||||
"color": "#288bd1ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Zoe FiriH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,378 +0,0 @@
|
||||
{
|
||||
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
|
||||
"name": "Summercamp",
|
||||
"author": "Zed Industries",
|
||||
"themes": [
|
||||
{
|
||||
"name": "Summercamp",
|
||||
"appearance": "dark",
|
||||
"style": {
|
||||
"border": "#302c21ff",
|
||||
"border.variant": "#29251bff",
|
||||
"border.focused": "#193760ff",
|
||||
"border.selected": "#193760ff",
|
||||
"border.transparent": "#00000000",
|
||||
"border.disabled": "#2e2a1fff",
|
||||
"elevated_surface.background": "#231f16ff",
|
||||
"surface.background": "#231f16ff",
|
||||
"background": "#2a261cff",
|
||||
"element.background": "#231f16ff",
|
||||
"element.hover": "#29251bff",
|
||||
"element.active": "#2f2b20ff",
|
||||
"element.selected": "#2f2b20ff",
|
||||
"element.disabled": "#231f16ff",
|
||||
"drop_target.background": "#736e5580",
|
||||
"ghost_element.background": "#00000000",
|
||||
"ghost_element.hover": "#29251bff",
|
||||
"ghost_element.active": "#2f2b20ff",
|
||||
"ghost_element.selected": "#2f2b20ff",
|
||||
"ghost_element.disabled": "#231f16ff",
|
||||
"text": "#f8f5deff",
|
||||
"text.muted": "#736e55ff",
|
||||
"text.placeholder": "#4c4735ff",
|
||||
"text.disabled": "#4c4735ff",
|
||||
"text.accent": "#499befff",
|
||||
"icon": "#f8f5deff",
|
||||
"icon.muted": "#736e55ff",
|
||||
"icon.disabled": "#4c4735ff",
|
||||
"icon.placeholder": "#736e55ff",
|
||||
"icon.accent": "#499befff",
|
||||
"status_bar.background": "#2a261cff",
|
||||
"title_bar.background": "#2a261cff",
|
||||
"title_bar.inactive_background": "#231f16ff",
|
||||
"toolbar.background": "#1b1810ff",
|
||||
"tab_bar.background": "#231f16ff",
|
||||
"tab.inactive_background": "#231f16ff",
|
||||
"tab.active_background": "#1b1810ff",
|
||||
"search.match_background": "#499bef66",
|
||||
"panel.background": "#231f16ff",
|
||||
"panel.focused_border": "#499befff",
|
||||
"pane.focused_border": null,
|
||||
"scrollbar.thumb.background": "#f8f5de4c",
|
||||
"scrollbar.thumb.hover_background": "#29251bff",
|
||||
"scrollbar.thumb.border": "#29251bff",
|
||||
"scrollbar.track.background": "#00000000",
|
||||
"scrollbar.track.border": "#221e15ff",
|
||||
"editor.foreground": "#f8f5deff",
|
||||
"editor.background": "#1b1810ff",
|
||||
"editor.gutter.background": "#1b1810ff",
|
||||
"editor.subheader.background": "#231f16ff",
|
||||
"editor.active_line.background": "#231f16bf",
|
||||
"editor.highlighted_line.background": "#231f16ff",
|
||||
"editor.line_number": "#676559",
|
||||
"editor.active_line_number": "#e3e2de",
|
||||
"editor.hover_line_number": "#b8b6ad",
|
||||
"editor.invisible": "#494433ff",
|
||||
"editor.wrap_guide": "#f8f5de0d",
|
||||
"editor.active_wrap_guide": "#f8f5de1a",
|
||||
"editor.document_highlight.read_background": "#499bef1a",
|
||||
"editor.document_highlight.write_background": "#49443366",
|
||||
"terminal.background": "#1b1810ff",
|
||||
"terminal.foreground": "#f8f5deff",
|
||||
"terminal.bright_foreground": "#f8f5deff",
|
||||
"terminal.dim_foreground": "#1b1810ff",
|
||||
"terminal.ansi.black": "#1b1810ff",
|
||||
"terminal.ansi.bright_black": "#3a3527ff",
|
||||
"terminal.ansi.dim_black": "#f8f5deff",
|
||||
"terminal.ansi.red": "#e35041ff",
|
||||
"terminal.ansi.bright_red": "#7f2724ff",
|
||||
"terminal.ansi.dim_red": "#faaa9bff",
|
||||
"terminal.ansi.green": "#5dea5aff",
|
||||
"terminal.ansi.bright_green": "#28842cff",
|
||||
"terminal.ansi.dim_green": "#b9f7aeff",
|
||||
"terminal.ansi.yellow": "#f1fe28ff",
|
||||
"terminal.ansi.bright_yellow": "#8c9a0fff",
|
||||
"terminal.ansi.dim_yellow": "#ffffa2ff",
|
||||
"terminal.ansi.blue": "#499befff",
|
||||
"terminal.ansi.bright_blue": "#234b7fff",
|
||||
"terminal.ansi.dim_blue": "#b1ccf8ff",
|
||||
"terminal.ansi.magenta": "#f59be6ff",
|
||||
"terminal.ansi.bright_magenta": "#88487eff",
|
||||
"terminal.ansi.dim_magenta": "#fccef3ff",
|
||||
"terminal.ansi.cyan": "#5aeabbff",
|
||||
"terminal.ansi.bright_cyan": "#288461ff",
|
||||
"terminal.ansi.dim_cyan": "#b7f6ddff",
|
||||
"terminal.ansi.white": "#f8f5deff",
|
||||
"terminal.ansi.bright_white": "#f8f5deff",
|
||||
"terminal.ansi.dim_white": "#57533fff",
|
||||
"link_text.hover": "#499befff",
|
||||
"conflict": "#f1fe28ff",
|
||||
"conflict.background": "#546205ff",
|
||||
"conflict.border": "#717f0aff",
|
||||
"created": "#5dea5aff",
|
||||
"created.background": "#094d12ff",
|
||||
"created.border": "#1a6a20ff",
|
||||
"deleted": "#e35041ff",
|
||||
"deleted.background": "#490f12ff",
|
||||
"deleted.border": "#651c1cff",
|
||||
"error": "#e35041ff",
|
||||
"error.background": "#490f12ff",
|
||||
"error.border": "#651c1cff",
|
||||
"hidden": "#4c4735ff",
|
||||
"hidden.background": "#2a261cff",
|
||||
"hidden.border": "#2e2a1fff",
|
||||
"hint": "#246e61ff",
|
||||
"hint.background": "#0e2242ff",
|
||||
"hint.border": "#193760ff",
|
||||
"ignored": "#4c4735ff",
|
||||
"ignored.background": "#2a261cff",
|
||||
"ignored.border": "#302c21ff",
|
||||
"info": "#499befff",
|
||||
"info.background": "#0e2242ff",
|
||||
"info.border": "#193760ff",
|
||||
"modified": "#f1fe28ff",
|
||||
"modified.background": "#546205ff",
|
||||
"modified.border": "#717f0aff",
|
||||
"predictive": "#78434aff",
|
||||
"predictive.background": "#094d12ff",
|
||||
"predictive.border": "#1a6a20ff",
|
||||
"renamed": "#499befff",
|
||||
"renamed.background": "#0e2242ff",
|
||||
"renamed.border": "#193760ff",
|
||||
"success": "#5dea5aff",
|
||||
"success.background": "#094d12ff",
|
||||
"success.border": "#1a6a20ff",
|
||||
"unreachable": "#736e55ff",
|
||||
"unreachable.background": "#2a261cff",
|
||||
"unreachable.border": "#302c21ff",
|
||||
"warning": "#f1fe28ff",
|
||||
"warning.background": "#546205ff",
|
||||
"warning.border": "#717f0aff",
|
||||
"players": [
|
||||
{
|
||||
"cursor": "#499befff",
|
||||
"background": "#499befff",
|
||||
"selection": "#499bef3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#f59be6ff",
|
||||
"background": "#f59be6ff",
|
||||
"selection": "#f59be63d"
|
||||
},
|
||||
{
|
||||
"cursor": "#faa11cff",
|
||||
"background": "#faa11cff",
|
||||
"selection": "#faa11c3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#fe8080ff",
|
||||
"background": "#fe8080ff",
|
||||
"selection": "#fe80803d"
|
||||
},
|
||||
{
|
||||
"cursor": "#5aeabbff",
|
||||
"background": "#5aeabbff",
|
||||
"selection": "#5aeabb3d"
|
||||
},
|
||||
{
|
||||
"cursor": "#e35041ff",
|
||||
"background": "#e35041ff",
|
||||
"selection": "#e350413d"
|
||||
},
|
||||
{
|
||||
"cursor": "#f1fe28ff",
|
||||
"background": "#f1fe28ff",
|
||||
"selection": "#f1fe283d"
|
||||
},
|
||||
{
|
||||
"cursor": "#5dea5aff",
|
||||
"background": "#5dea5aff",
|
||||
"selection": "#5dea5a3d"
|
||||
}
|
||||
],
|
||||
"syntax": {
|
||||
"attribute": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"boolean": {
|
||||
"color": "#5dea5aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment": {
|
||||
"color": "#777159ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"comment.doc": {
|
||||
"color": "#777159ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constant": {
|
||||
"color": "#5dea5aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"constructor": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"embedded": {
|
||||
"color": "#f8f5deff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"emphasis.strong": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"enum": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"function": {
|
||||
"color": "#f1fe28ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"hint": {
|
||||
"color": "#246e61ff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"keyword": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"label": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"link_text": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"link_uri": {
|
||||
"color": "#5dea5aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"number": {
|
||||
"color": "#5dea5aff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"operator": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"predictive": {
|
||||
"color": "#78434aff",
|
||||
"font_style": "italic",
|
||||
"font_weight": null
|
||||
},
|
||||
"preproc": {
|
||||
"color": "#f8f5deff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"primary": {
|
||||
"color": "#f8f5deff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"property": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation": {
|
||||
"color": "#bfbb9bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.bracket": {
|
||||
"color": "#bfbb9bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.delimiter": {
|
||||
"color": "#bfbb9bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.list_marker": {
|
||||
"color": "#bfbb9bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"punctuation.special": {
|
||||
"color": "#bfbb9bff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.escape": {
|
||||
"color": "#777159ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.regex": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"string.special.symbol": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"tag": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"text.literal": {
|
||||
"color": "#faa11cff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"title": {
|
||||
"color": "#f8f5deff",
|
||||
"font_style": null,
|
||||
"font_weight": 700
|
||||
},
|
||||
"type": {
|
||||
"color": "#5aeabbff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#f8f5deff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variant": {
|
||||
"color": "#499befff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -279,7 +279,17 @@ impl AssistantPanel {
|
||||
});
|
||||
pane.toolbar().update(cx, |toolbar, cx| {
|
||||
toolbar.add_item(context_editor_toolbar.clone(), window, cx);
|
||||
toolbar.add_item(cx.new(|cx| BufferSearchBar::new(window, cx)), window, cx)
|
||||
toolbar.add_item(
|
||||
cx.new(|cx| {
|
||||
BufferSearchBar::new(
|
||||
Some(workspace.project().read(cx).languages().clone()),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
pane
|
||||
});
|
||||
|
||||
@@ -1704,7 +1704,7 @@ impl PromptEditor {
|
||||
// always show the cursor (even when it isn't focused) because
|
||||
// typing in one will make what you typed appear in all of them.
|
||||
editor.set_show_cursor_when_unfocused(true, cx);
|
||||
editor.set_placeholder_text(Self::placeholder_text(codegen.read(cx), window), cx);
|
||||
editor.set_placeholder_text(Self::placeholder_text(codegen.read(cx), window, cx), cx);
|
||||
editor
|
||||
});
|
||||
|
||||
@@ -1783,7 +1783,10 @@ impl PromptEditor {
|
||||
self.editor = cx.new(|cx| {
|
||||
let mut editor = Editor::auto_height(Self::MAX_LINES as usize, window, cx);
|
||||
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
|
||||
editor.set_placeholder_text(Self::placeholder_text(self.codegen.read(cx), window), cx);
|
||||
editor.set_placeholder_text(
|
||||
Self::placeholder_text(self.codegen.read(cx), window, cx),
|
||||
cx,
|
||||
);
|
||||
editor.set_placeholder_text("Add a prompt…", cx);
|
||||
editor.set_text(prompt, window, cx);
|
||||
if focus {
|
||||
@@ -1794,8 +1797,8 @@ impl PromptEditor {
|
||||
self.subscribe_to_editor(window, cx);
|
||||
}
|
||||
|
||||
fn placeholder_text(codegen: &Codegen, window: &Window) -> String {
|
||||
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window)
|
||||
fn placeholder_text(codegen: &Codegen, window: &Window, cx: &App) -> String {
|
||||
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window, cx)
|
||||
.map(|keybinding| format!(" • {keybinding} for context"))
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -2084,12 +2087,13 @@ impl PromptEditor {
|
||||
.tooltip({
|
||||
let focus_handle = self.editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
cx.new(|_| {
|
||||
cx.new(|cx| {
|
||||
let mut tooltip = Tooltip::new("Previous Alternative").key_binding(
|
||||
KeyBinding::for_action_in(
|
||||
&CyclePreviousInlineAssist,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
);
|
||||
if !disabled && current_index != 0 {
|
||||
@@ -2126,12 +2130,13 @@ impl PromptEditor {
|
||||
.tooltip({
|
||||
let focus_handle = self.editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
cx.new(|_| {
|
||||
cx.new(|cx| {
|
||||
let mut tooltip = Tooltip::new("Next Alternative").key_binding(
|
||||
KeyBinding::for_action_in(
|
||||
&CycleNextInlineAssist,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
);
|
||||
if !disabled && current_index != total_models - 1 {
|
||||
|
||||
@@ -725,7 +725,7 @@ impl PromptEditor {
|
||||
cx,
|
||||
);
|
||||
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
|
||||
editor.set_placeholder_text(Self::placeholder_text(window), cx);
|
||||
editor.set_placeholder_text(Self::placeholder_text(window, cx), cx);
|
||||
editor
|
||||
});
|
||||
|
||||
@@ -774,8 +774,8 @@ impl PromptEditor {
|
||||
this
|
||||
}
|
||||
|
||||
fn placeholder_text(window: &Window) -> String {
|
||||
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window)
|
||||
fn placeholder_text(window: &Window, cx: &App) -> String {
|
||||
let context_keybinding = text_for_action(&zed_actions::assistant::ToggleFocus, window, cx)
|
||||
.map(|keybinding| format!(" • {keybinding} for context"))
|
||||
.unwrap_or_default();
|
||||
|
||||
|
||||
@@ -849,6 +849,7 @@ impl AssistantPanel {
|
||||
&OpenHistory,
|
||||
&self.focus_handle(cx),
|
||||
window,
|
||||
cx
|
||||
))
|
||||
.on_click(move |_event, window, cx| {
|
||||
window.dispatch_action(OpenHistory.boxed_clone(), cx);
|
||||
|
||||
@@ -453,6 +453,7 @@ impl Render for ContextStrip {
|
||||
&ToggleContextPicker,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.map(|binding| binding.into_any_element()),
|
||||
),
|
||||
|
||||
@@ -271,7 +271,7 @@ impl<T: 'static> PromptEditor<T> {
|
||||
};
|
||||
|
||||
let assistant_panel_keybinding =
|
||||
ui::text_for_action(&zed_actions::assistant::ToggleFocus, window)
|
||||
ui::text_for_action(&zed_actions::assistant::ToggleFocus, window, cx)
|
||||
.map(|keybinding| format!("{keybinding} to chat ― "))
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -618,12 +618,13 @@ impl<T: 'static> PromptEditor<T> {
|
||||
.tooltip({
|
||||
let focus_handle = self.editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
cx.new(|_| {
|
||||
cx.new(|cx| {
|
||||
let mut tooltip = Tooltip::new("Previous Alternative").key_binding(
|
||||
KeyBinding::for_action_in(
|
||||
&CyclePreviousInlineAssist,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
);
|
||||
if !disabled && current_index != 0 {
|
||||
@@ -659,12 +660,13 @@ impl<T: 'static> PromptEditor<T> {
|
||||
.tooltip({
|
||||
let focus_handle = self.editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
cx.new(|_| {
|
||||
cx.new(|cx| {
|
||||
let mut tooltip = Tooltip::new("Next Alternative").key_binding(
|
||||
KeyBinding::for_action_in(
|
||||
&CycleNextInlineAssist,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
);
|
||||
if !disabled && current_index != total_models - 1 {
|
||||
|
||||
@@ -13,7 +13,7 @@ use rope::Point;
|
||||
use settings::Settings;
|
||||
use std::time::Duration;
|
||||
use text::Bias;
|
||||
use theme::ThemeSettings;
|
||||
use theme::{get_ui_font_size, ThemeSettings};
|
||||
use ui::{
|
||||
prelude::*, ButtonLike, KeyBinding, PopoverMenu, PopoverMenuHandle, Switch, TintColor, Tooltip,
|
||||
};
|
||||
@@ -369,11 +369,7 @@ impl Render for MessageEditor {
|
||||
.anchor(gpui::Corner::BottomLeft)
|
||||
.offset(gpui::Point {
|
||||
x: px(0.0),
|
||||
y: px(-ThemeSettings::clamp_font_size(
|
||||
ThemeSettings::get_global(cx).ui_font_size,
|
||||
)
|
||||
.0 * 2.0)
|
||||
- px(4.0),
|
||||
y: (-get_ui_font_size(cx) * 2) - px(4.0),
|
||||
})
|
||||
.with_handle(self.inline_context_picker_menu_handle.clone()),
|
||||
)
|
||||
@@ -394,6 +390,7 @@ impl Render for MessageEditor {
|
||||
&ChatMode,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)),
|
||||
)
|
||||
.child(h_flex().gap_1().child(self.model_selector.clone()).child(
|
||||
@@ -423,6 +420,7 @@ impl Render for MessageEditor {
|
||||
&editor::actions::Cancel,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.map(|binding| binding.into_any_element()),
|
||||
),
|
||||
@@ -453,6 +451,7 @@ impl Render for MessageEditor {
|
||||
&Chat,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.map(|binding| binding.into_any_element()),
|
||||
),
|
||||
|
||||
@@ -2290,7 +2290,7 @@ impl ContextEditor {
|
||||
},
|
||||
))
|
||||
.children(
|
||||
KeyBinding::for_action_in(&Assist, &focus_handle, window)
|
||||
KeyBinding::for_action_in(&Assist, &focus_handle, window, cx)
|
||||
.map(|binding| binding.into_any_element()),
|
||||
)
|
||||
.on_click(move |_event, window, cx| {
|
||||
@@ -2343,7 +2343,7 @@ impl ContextEditor {
|
||||
.layer(ElevationIndex::ModalSurface)
|
||||
.child(Label::new("Suggest Edits"))
|
||||
.children(
|
||||
KeyBinding::for_action_in(&Edit, &focus_handle, window)
|
||||
KeyBinding::for_action_in(&Edit, &focus_handle, window, cx)
|
||||
.map(|binding| binding.into_any_element()),
|
||||
)
|
||||
.on_click(move |_event, window, cx| {
|
||||
|
||||
@@ -18,6 +18,7 @@ SEED_PATH = "crates/collab/seed.default.json"
|
||||
LLM_DATABASE_URL = "postgres://postgres@localhost/zed_llm"
|
||||
LLM_DATABASE_MAX_CONNECTIONS = 5
|
||||
LLM_API_SECRET = "llm-secret"
|
||||
OPENAI_API_KEY = "llm-secret"
|
||||
|
||||
# SLACK_PANICS_WEBHOOK = ""
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ google_ai.workspace = true
|
||||
hex.workspace = true
|
||||
http_client.workspace = true
|
||||
jsonwebtoken.workspace = true
|
||||
livekit_server.workspace = true
|
||||
livekit_api.workspace = true
|
||||
log.workspace = true
|
||||
nanoid.workspace = true
|
||||
open_ai.workspace = true
|
||||
|
||||
@@ -5,7 +5,6 @@ pub mod extensions;
|
||||
pub mod ips_file;
|
||||
pub mod slack;
|
||||
|
||||
use crate::api::events::SnowflakeRow;
|
||||
use crate::{
|
||||
auth,
|
||||
db::{User, UserId},
|
||||
@@ -100,7 +99,6 @@ pub fn routes(rpc_server: Arc<rpc::Server>) -> Router<(), Body> {
|
||||
.route("/user", get(get_authenticated_user))
|
||||
.route("/users/:id/access_tokens", post(create_access_token))
|
||||
.route("/rpc_server_snapshot", get(get_rpc_server_snapshot))
|
||||
.route("/snowflake/events", post(write_snowflake_event))
|
||||
.merge(billing::router())
|
||||
.merge(contributors::router())
|
||||
.layer(
|
||||
@@ -247,19 +245,3 @@ async fn create_access_token(
|
||||
encrypted_access_token,
|
||||
}))
|
||||
}
|
||||
|
||||
/// An endpoint that writes a Snowflake event to our event stream.
|
||||
///
|
||||
/// This endpoint is exposed such that other internal services can write
|
||||
/// telemetry events without needing to talk to AWS Kinesis directly.
|
||||
async fn write_snowflake_event(
|
||||
Extension(app): Extension<Arc<AppState>>,
|
||||
Json(event): Json<SnowflakeRow>,
|
||||
) -> Result<()> {
|
||||
let kinesis_client = app.kinesis_client.clone();
|
||||
let kinesis_stream = app.config.kinesis_stream.clone();
|
||||
|
||||
event.write(&kinesis_client, &kinesis_stream).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ impl ServiceMode {
|
||||
pub struct AppState {
|
||||
pub db: Arc<Database>,
|
||||
pub llm_db: Option<Arc<LlmDatabase>>,
|
||||
pub livekit_client: Option<Arc<dyn livekit_server::api::Client>>,
|
||||
pub livekit_client: Option<Arc<dyn livekit_api::Client>>,
|
||||
pub blob_store_client: Option<aws_sdk_s3::Client>,
|
||||
pub stripe_client: Option<Arc<stripe::Client>>,
|
||||
pub stripe_billing: Option<Arc<StripeBilling>>,
|
||||
@@ -311,11 +311,11 @@ impl AppState {
|
||||
.zip(config.livekit_key.as_ref())
|
||||
.zip(config.livekit_secret.as_ref())
|
||||
{
|
||||
Some(Arc::new(livekit_server::api::LiveKitClient::new(
|
||||
Some(Arc::new(livekit_api::LiveKitClient::new(
|
||||
server.clone(),
|
||||
key.clone(),
|
||||
secret.clone(),
|
||||
)) as Arc<dyn livekit_server::api::Client>)
|
||||
)) as Arc<dyn livekit_api::Client>)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
@@ -397,6 +397,7 @@ impl Server {
|
||||
.add_request_handler(forward_mutating_project_request::<proto::Commit>)
|
||||
.add_request_handler(forward_read_only_project_request::<proto::GitShow>)
|
||||
.add_request_handler(forward_read_only_project_request::<proto::GitReset>)
|
||||
.add_request_handler(forward_read_only_project_request::<proto::GitCheckoutFiles>)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::SetIndexText>)
|
||||
.add_request_handler(forward_mutating_project_request::<proto::OpenCommitMessageBuffer>)
|
||||
.add_message_handler(broadcast_project_message_from_host::<proto::AdvertiseContexts>)
|
||||
@@ -1544,7 +1545,7 @@ async fn set_room_participant_role(
|
||||
.update_participant(
|
||||
livekit_room.clone(),
|
||||
request.user_id.to_string(),
|
||||
livekit_server::proto::ParticipantPermission {
|
||||
livekit_api::proto::ParticipantPermission {
|
||||
can_subscribe: true,
|
||||
can_publish,
|
||||
can_publish_data: can_publish,
|
||||
|
||||
@@ -250,7 +250,7 @@ async fn test_basic_following(
|
||||
});
|
||||
executor.run_until_parked();
|
||||
// are you sure you want to leave the call?
|
||||
cx_c.simulate_prompt_answer(0);
|
||||
cx_c.simulate_prompt_answer("Close window and hang up");
|
||||
cx_c.cx.update(|_| {
|
||||
drop(workspace_c);
|
||||
});
|
||||
|
||||
@@ -4438,15 +4438,14 @@ async fn test_formatting_buffer(
|
||||
.await
|
||||
.unwrap();
|
||||
let project_b = client_b.join_remote_project(project_id, cx_b).await;
|
||||
let lsp_store_b = project_b.update(cx_b, |p, _| p.lsp_store());
|
||||
|
||||
let buffer_b = project_b
|
||||
.update(cx_b, |p, cx| p.open_buffer((worktree_id, "a.rs"), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let _handle = lsp_store_b.update(cx_b, |lsp_store, cx| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer_b, cx)
|
||||
let _handle = project_b.update(cx_b, |project, cx| {
|
||||
project.register_buffer_with_language_servers(&buffer_b, cx)
|
||||
});
|
||||
let fake_language_server = fake_language_servers.next().await.unwrap();
|
||||
fake_language_server.handle_request::<lsp::request::Formatting, _, _>(|_, _| async move {
|
||||
|
||||
@@ -992,6 +992,7 @@ impl Render for ChatPanel {
|
||||
.key_binding(KeyBinding::for_action(
|
||||
&collab_panel::ToggleFocus,
|
||||
window,
|
||||
cx,
|
||||
))
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(
|
||||
|
||||
@@ -402,7 +402,7 @@ impl PickerDelegate for CommandPaletteDelegate {
|
||||
ix: usize,
|
||||
selected: bool,
|
||||
window: &mut Window,
|
||||
_: &mut Context<Picker<Self>>,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Option<Self::ListItem> {
|
||||
let r#match = self.matches.get(ix)?;
|
||||
let command = self.commands.get(r#match.candidate_id)?;
|
||||
@@ -424,6 +424,7 @@ impl PickerDelegate for CommandPaletteDelegate {
|
||||
&*command.action,
|
||||
&self.previous_focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@ path = "src/component.rs"
|
||||
collections.workspace = true
|
||||
gpui.workspace = true
|
||||
linkme.workspace = true
|
||||
once_cell = "1.20.3"
|
||||
once_cell.workspace = true
|
||||
parking_lot.workspace = true
|
||||
theme.workspace = true
|
||||
|
||||
|
||||
@@ -458,12 +458,14 @@ impl Copilot {
|
||||
.on_notification::<StatusNotification, _>(|_, _| { /* Silence the notification */ })
|
||||
.detach();
|
||||
|
||||
let initialize_params = None;
|
||||
let configuration = lsp::DidChangeConfigurationParams {
|
||||
settings: Default::default(),
|
||||
};
|
||||
let server = cx
|
||||
.update(|cx| server.initialize(initialize_params, configuration.into(), cx))?
|
||||
.update(|cx| {
|
||||
let params = server.default_initialize_params(cx);
|
||||
server.initialize(params, configuration.into(), cx)
|
||||
})?
|
||||
.await?;
|
||||
|
||||
let status = server
|
||||
|
||||
@@ -29,14 +29,8 @@ impl Template for KeybindingTemplate {
|
||||
|
||||
fn render(&self, context: &PreprocessorContext, args: &HashMap<String, String>) -> String {
|
||||
let action = args.get("action").map(String::as_str).unwrap_or("");
|
||||
let macos_binding = context
|
||||
.find_binding("macos", action)
|
||||
.unwrap_or_default()
|
||||
.replace("\\", "\");
|
||||
let linux_binding = context
|
||||
.find_binding("linux", action)
|
||||
.unwrap_or_default()
|
||||
.replace("\\", "\");
|
||||
let macos_binding = context.find_binding("macos", action).unwrap_or_default();
|
||||
let linux_binding = context.find_binding("linux", action).unwrap_or_default();
|
||||
format!("<kbd class=\"keybinding\">{macos_binding}|{linux_binding}</kbd>")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
indoc.workspace = true
|
||||
inline_completion.workspace = true
|
||||
inventory.workspace = true
|
||||
itertools.workspace = true
|
||||
language.workspace = true
|
||||
linkify.workspace = true
|
||||
|
||||
@@ -267,9 +267,7 @@ gpui::actions!(
|
||||
CopyHighlightJson,
|
||||
CopyFileName,
|
||||
CopyFileNameWithoutExtension,
|
||||
CopyPath,
|
||||
CopyPermalinkToLine,
|
||||
CopyRelativePath,
|
||||
Cut,
|
||||
CutToEndOfLine,
|
||||
Delete,
|
||||
|
||||
@@ -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};
|
||||
@@ -134,7 +134,7 @@ use project::{
|
||||
lsp_store::{FormatTrigger, LspFormatTarget, OpenLspBufferHandle},
|
||||
project_settings::{GitGutterSetting, ProjectSettings},
|
||||
CodeAction, Completion, CompletionIntent, DocumentHighlight, InlayHint, Location, LocationLink,
|
||||
LspStore, PrepareRenameResponse, Project, ProjectItem, ProjectTransaction, TaskSourceKind,
|
||||
PrepareRenameResponse, Project, ProjectItem, ProjectTransaction, TaskSourceKind,
|
||||
};
|
||||
use rand::prelude::*;
|
||||
use rpc::{proto::*, ErrorExt};
|
||||
@@ -162,12 +162,15 @@ use std::{
|
||||
pub use sum_tree::Bias;
|
||||
use sum_tree::TreeMap;
|
||||
use text::{BufferId, OffsetUtf16, Rope};
|
||||
use theme::{ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, ThemeColors, ThemeSettings};
|
||||
use theme::{
|
||||
observe_buffer_font_size_adjustment, ActiveTheme, PlayerColor, StatusColors, SyntaxTheme,
|
||||
ThemeColors, ThemeSettings,
|
||||
};
|
||||
use ui::{
|
||||
h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize, Key,
|
||||
Tooltip,
|
||||
};
|
||||
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TakeUntilExt, TryFutureExt};
|
||||
use util::{defer, maybe, post_inc, RangeExt, ResultExt, TryFutureExt};
|
||||
use workspace::item::{ItemHandle, PreviewTabsSettings};
|
||||
use workspace::notifications::{DetachAndPromptErr, NotificationId, NotifyTaskExt};
|
||||
use workspace::{
|
||||
@@ -194,8 +197,7 @@ pub(crate) const FORMAT_TIMEOUT: Duration = Duration::from_secs(2);
|
||||
pub(crate) const SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);
|
||||
|
||||
pub(crate) const EDIT_PREDICTION_KEY_CONTEXT: &str = "edit_prediction";
|
||||
pub(crate) const EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT: &str =
|
||||
"edit_prediction_requires_modifier";
|
||||
pub(crate) const EDIT_PREDICTION_CONFLICT_KEY_CONTEXT: &str = "edit_prediction_conflict";
|
||||
|
||||
pub fn render_parsed_markdown(
|
||||
element_id: impl Into<ElementId>,
|
||||
@@ -508,15 +510,6 @@ enum EditPredictionSettings {
|
||||
},
|
||||
}
|
||||
|
||||
impl EditPredictionSettings {
|
||||
pub fn is_enabled(&self) -> bool {
|
||||
match self {
|
||||
EditPredictionSettings::Disabled => false,
|
||||
EditPredictionSettings::Enabled { .. } => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum InlineCompletionHighlight {}
|
||||
|
||||
pub enum MenuInlineCompletionsPolicy {
|
||||
@@ -1455,6 +1448,7 @@ impl Editor {
|
||||
cx.observe_in(&display_map, window, Self::on_display_map_changed),
|
||||
cx.observe(&blink_manager, |_, _, cx| cx.notify()),
|
||||
cx.observe_global_in::<SettingsStore>(window, Self::settings_changed),
|
||||
observe_buffer_font_size_adjustment(cx, |_, cx| cx.notify()),
|
||||
cx.observe_window_activation(window, |editor, window, cx| {
|
||||
let active = window.is_window_active();
|
||||
editor.blink_manager.update(cx, |blink_manager, cx| {
|
||||
@@ -1498,9 +1492,8 @@ impl Editor {
|
||||
|
||||
if let Some(buffer) = buffer.read(cx).as_singleton() {
|
||||
if let Some(project) = this.project.as_ref() {
|
||||
let lsp_store = project.read(cx).lsp_store();
|
||||
let handle = lsp_store.update(cx, |lsp_store, cx| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx)
|
||||
let handle = project.update(cx, |project, cx| {
|
||||
project.register_buffer_with_language_servers(&buffer, cx)
|
||||
});
|
||||
this.registered_buffers
|
||||
.insert(buffer.read(cx).remote_id(), handle);
|
||||
@@ -1545,13 +1538,10 @@ impl Editor {
|
||||
key_context.add("renaming");
|
||||
}
|
||||
|
||||
let mut showing_completions = false;
|
||||
|
||||
match self.context_menu.borrow().as_ref() {
|
||||
Some(CodeContextMenu::Completions(_)) => {
|
||||
key_context.add("menu");
|
||||
key_context.add("showing_completions");
|
||||
showing_completions = true;
|
||||
}
|
||||
Some(CodeContextMenu::CodeActions(_)) => {
|
||||
key_context.add("menu");
|
||||
@@ -1579,15 +1569,11 @@ impl Editor {
|
||||
}
|
||||
|
||||
if has_active_edit_prediction {
|
||||
key_context.add("copilot_suggestion");
|
||||
key_context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
||||
if showing_completions
|
||||
|| self.edit_prediction_requires_modifier()
|
||||
// Require modifier key when the cursor is on leading whitespace, to allow `tab`
|
||||
// bindings to insert tab characters.
|
||||
|| (self.edit_prediction_requires_modifier_in_leading_space && self.edit_prediction_cursor_on_leading_whitespace)
|
||||
{
|
||||
key_context.add(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT);
|
||||
if self.edit_prediction_in_conflict() {
|
||||
key_context.add(EDIT_PREDICTION_CONFLICT_KEY_CONTEXT);
|
||||
} else {
|
||||
key_context.add(EDIT_PREDICTION_KEY_CONTEXT);
|
||||
key_context.add("copilot_suggestion");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1598,18 +1584,52 @@ impl Editor {
|
||||
key_context
|
||||
}
|
||||
|
||||
pub fn edit_prediction_in_conflict(&self) -> bool {
|
||||
if !self.show_edit_predictions_in_menu() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let showing_completions = self
|
||||
.context_menu
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.map_or(false, |context| {
|
||||
matches!(context, CodeContextMenu::Completions(_))
|
||||
});
|
||||
|
||||
showing_completions
|
||||
|| self.edit_prediction_requires_modifier()
|
||||
// Require modifier key when the cursor is on leading whitespace, to allow `tab`
|
||||
// bindings to insert tab characters.
|
||||
|| (self.edit_prediction_requires_modifier_in_leading_space && self.edit_prediction_cursor_on_leading_whitespace)
|
||||
}
|
||||
|
||||
pub fn accept_edit_prediction_keybind(
|
||||
&self,
|
||||
window: &Window,
|
||||
cx: &App,
|
||||
) -> AcceptEditPredictionBinding {
|
||||
let key_context = self.key_context_internal(true, window, cx);
|
||||
let in_conflict = self.edit_prediction_in_conflict();
|
||||
|
||||
AcceptEditPredictionBinding(
|
||||
window
|
||||
.bindings_for_action_in_context(&AcceptEditPrediction, key_context)
|
||||
.into_iter()
|
||||
.filter(|binding| {
|
||||
!in_conflict
|
||||
|| binding
|
||||
.keystrokes()
|
||||
.first()
|
||||
.map_or(false, |keystroke| keystroke.modifiers.modified())
|
||||
})
|
||||
.rev()
|
||||
.next(),
|
||||
.min_by_key(|binding| {
|
||||
binding
|
||||
.keystrokes()
|
||||
.first()
|
||||
.map_or(u8::MAX, |k| k.modifiers.number_of_modifiers())
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1870,16 +1890,14 @@ impl Editor {
|
||||
|
||||
fn register_buffers_with_language_servers(&mut self, cx: &mut Context<Self>) {
|
||||
let buffers = self.buffer.read(cx).all_buffers();
|
||||
let Some(lsp_store) = self.lsp_store(cx) else {
|
||||
let Some(project) = self.project.as_ref() else {
|
||||
return;
|
||||
};
|
||||
lsp_store.update(cx, |lsp_store, cx| {
|
||||
project.update(cx, |project, cx| {
|
||||
for buffer in buffers {
|
||||
self.registered_buffers
|
||||
.entry(buffer.read(cx).remote_id())
|
||||
.or_insert_with(|| {
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx)
|
||||
});
|
||||
.or_insert_with(|| project.register_buffer_with_language_servers(&buffer, cx));
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -2079,14 +2097,14 @@ impl Editor {
|
||||
};
|
||||
if let Some(buffer_id) = new_cursor_position.buffer_id {
|
||||
if !self.registered_buffers.contains_key(&buffer_id) {
|
||||
if let Some(lsp_store) = self.lsp_store(cx) {
|
||||
lsp_store.update(cx, |lsp_store, cx| {
|
||||
if let Some(project) = self.project.as_ref() {
|
||||
project.update(cx, |project, cx| {
|
||||
let Some(buffer) = self.buffer.read(cx).buffer(buffer_id) else {
|
||||
return;
|
||||
};
|
||||
self.registered_buffers.insert(
|
||||
buffer_id,
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx),
|
||||
project.register_buffer_with_language_servers(&buffer, cx),
|
||||
);
|
||||
})
|
||||
}
|
||||
@@ -5297,11 +5315,6 @@ impl Editor {
|
||||
self.edit_prediction_settings =
|
||||
self.edit_prediction_settings_at_position(&buffer, cursor_buffer_position, cx);
|
||||
|
||||
if !self.edit_prediction_settings.is_enabled() {
|
||||
self.discard_inline_completion(false, cx);
|
||||
return None;
|
||||
}
|
||||
|
||||
self.edit_prediction_cursor_on_leading_whitespace =
|
||||
multibuffer.is_line_whitespace_upto(cursor);
|
||||
|
||||
@@ -5981,52 +5994,23 @@ impl Editor {
|
||||
} => {
|
||||
let first_edit_row = edits.first()?.0.start.text_anchor.to_point(&snapshot).row;
|
||||
|
||||
let highlighted_edits = crate::inline_completion_edit_text(
|
||||
let (highlighted_edits, has_more_lines) = crate::inline_completion_edit_text(
|
||||
&snapshot,
|
||||
&edits,
|
||||
edit_preview.as_ref()?,
|
||||
true,
|
||||
cx,
|
||||
);
|
||||
)
|
||||
.first_line_preview();
|
||||
|
||||
let len_total = highlighted_edits.text.len();
|
||||
let first_line = &highlighted_edits.text
|
||||
[..highlighted_edits.text.find('\n').unwrap_or(len_total)];
|
||||
let first_line_len = first_line.len();
|
||||
|
||||
let first_highlight_start = highlighted_edits
|
||||
.highlights
|
||||
.first()
|
||||
.map_or(0, |(range, _)| range.start);
|
||||
let drop_prefix_len = first_line
|
||||
.char_indices()
|
||||
.find(|(_, c)| !c.is_whitespace())
|
||||
.map_or(first_highlight_start, |(ix, _)| {
|
||||
ix.min(first_highlight_start)
|
||||
});
|
||||
|
||||
let preview_text = &first_line[drop_prefix_len..];
|
||||
let preview_len = preview_text.len();
|
||||
let highlights = highlighted_edits
|
||||
.highlights
|
||||
.into_iter()
|
||||
.take_until(|(range, _)| range.start > first_line_len)
|
||||
.map(|(range, style)| {
|
||||
(
|
||||
range.start - drop_prefix_len
|
||||
..(range.end - drop_prefix_len).min(preview_len),
|
||||
style,
|
||||
)
|
||||
});
|
||||
|
||||
let styled_text = gpui::StyledText::new(SharedString::new(preview_text))
|
||||
.with_highlights(&style.text, highlights);
|
||||
let styled_text = gpui::StyledText::new(highlighted_edits.text)
|
||||
.with_highlights(&style.text, highlighted_edits.highlights);
|
||||
|
||||
let preview = h_flex()
|
||||
.gap_1()
|
||||
.min_w_16()
|
||||
.child(styled_text)
|
||||
.when(len_total > first_line_len, |parent| parent.child("…"));
|
||||
.when(has_more_lines, |parent| parent.child("…"));
|
||||
|
||||
let left = if first_edit_row != cursor_point.row {
|
||||
render_relative_row_jump("", cursor_point.row, first_edit_row)
|
||||
@@ -6949,10 +6933,10 @@ impl Editor {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let selections = self.selections.all(cx).into_iter().map(|s| s.range());
|
||||
self.revert_hunks_in_ranges(selections, window, cx);
|
||||
self.discard_hunks_in_ranges(selections, window, cx);
|
||||
}
|
||||
|
||||
fn revert_hunks_in_ranges(
|
||||
fn discard_hunks_in_ranges(
|
||||
&mut self,
|
||||
ranges: impl Iterator<Item = Range<Point>>,
|
||||
window: &mut Window,
|
||||
@@ -11622,7 +11606,10 @@ impl Editor {
|
||||
if let Some(project) = self.project.clone() {
|
||||
self.buffer.update(cx, |multi_buffer, cx| {
|
||||
project.update(cx, |project, cx| {
|
||||
project.restart_language_servers_for_buffers(multi_buffer.all_buffers(), cx);
|
||||
project.restart_language_servers_for_buffers(
|
||||
multi_buffer.all_buffers().into_iter().collect(),
|
||||
cx,
|
||||
);
|
||||
});
|
||||
})
|
||||
}
|
||||
@@ -12476,10 +12463,7 @@ impl Editor {
|
||||
snapshot: &MultiBufferSnapshot,
|
||||
) -> bool {
|
||||
let mut hunks = self.diff_hunks_in_ranges(ranges, &snapshot);
|
||||
hunks.any(|hunk| {
|
||||
log::debug!("considering {hunk:?}");
|
||||
hunk.secondary_status == DiffHunkSecondaryStatus::HasSecondaryHunk
|
||||
})
|
||||
hunks.any(|hunk| hunk.secondary_status == DiffHunkSecondaryStatus::HasSecondaryHunk)
|
||||
}
|
||||
|
||||
pub fn toggle_staged_selected_diff_hunks(
|
||||
@@ -13080,7 +13064,12 @@ impl Editor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_path(&mut self, _: &CopyPath, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
pub fn copy_path(
|
||||
&mut self,
|
||||
_: &zed_actions::workspace::CopyPath,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if let Some(path) = self.target_file_abs_path(cx) {
|
||||
if let Some(path) = path.to_str() {
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(path.to_string()));
|
||||
@@ -13090,7 +13079,7 @@ impl Editor {
|
||||
|
||||
pub fn copy_relative_path(
|
||||
&mut self,
|
||||
_: &CopyRelativePath,
|
||||
_: &zed_actions::workspace::CopyRelativePath,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
@@ -13619,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);
|
||||
@@ -13643,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
|
||||
@@ -14033,12 +14022,6 @@ impl Editor {
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
pub fn lsp_store(&self, cx: &App) -> Option<Entity<LspStore>> {
|
||||
self.project
|
||||
.as_ref()
|
||||
.map(|project| project.read(cx).lsp_store())
|
||||
}
|
||||
|
||||
fn on_buffer_changed(&mut self, _: Entity<MultiBuffer>, cx: &mut Context<Self>) {
|
||||
cx.notify();
|
||||
}
|
||||
@@ -14065,11 +14048,11 @@ impl Editor {
|
||||
if let Some(buffer) = buffer_edited {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
if !self.registered_buffers.contains_key(&buffer_id) {
|
||||
if let Some(lsp_store) = self.lsp_store(cx) {
|
||||
lsp_store.update(cx, |lsp_store, cx| {
|
||||
if let Some(project) = self.project.as_ref() {
|
||||
project.update(cx, |project, cx| {
|
||||
self.registered_buffers.insert(
|
||||
buffer_id,
|
||||
lsp_store.register_buffer_with_language_servers(&buffer, cx),
|
||||
project.register_buffer_with_language_servers(&buffer, cx),
|
||||
);
|
||||
})
|
||||
}
|
||||
@@ -14079,28 +14062,23 @@ impl Editor {
|
||||
cx.emit(SearchEvent::MatchesInvalidated);
|
||||
if *singleton_buffer_edited {
|
||||
if let Some(project) = &self.project {
|
||||
let project = project.read(cx);
|
||||
#[allow(clippy::mutable_key_type)]
|
||||
let languages_affected = multibuffer
|
||||
.read(cx)
|
||||
.all_buffers()
|
||||
.into_iter()
|
||||
.filter_map(|buffer| {
|
||||
let buffer = buffer.read(cx);
|
||||
let language = buffer.language()?;
|
||||
if project.is_local()
|
||||
&& project
|
||||
.language_servers_for_local_buffer(buffer, cx)
|
||||
.count()
|
||||
== 0
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(language)
|
||||
}
|
||||
})
|
||||
.cloned()
|
||||
.collect::<HashSet<_>>();
|
||||
let languages_affected = multibuffer.update(cx, |multibuffer, cx| {
|
||||
multibuffer
|
||||
.all_buffers()
|
||||
.into_iter()
|
||||
.filter_map(|buffer| {
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
let language = buffer.language()?;
|
||||
let should_discard = project.update(cx, |project, cx| {
|
||||
project.is_local()
|
||||
&& !project.has_language_servers_for(buffer, cx)
|
||||
});
|
||||
should_discard.not().then_some(language.clone())
|
||||
})
|
||||
})
|
||||
.collect::<HashSet<_>>()
|
||||
});
|
||||
if !languages_affected.is_empty() {
|
||||
self.refresh_inlay_hints(
|
||||
InlayHintRefreshReason::BufferEdited(languages_affected),
|
||||
@@ -14129,15 +14107,13 @@ impl Editor {
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
if self.buffer.read(cx).diff_for(buffer_id).is_none() {
|
||||
if let Some(project) = &self.project {
|
||||
self.load_diff_task = Some(
|
||||
get_uncommitted_diff_for_buffer(
|
||||
project,
|
||||
[buffer.clone()],
|
||||
self.buffer.clone(),
|
||||
cx,
|
||||
)
|
||||
.shared(),
|
||||
);
|
||||
get_uncommitted_diff_for_buffer(
|
||||
project,
|
||||
[buffer.clone()],
|
||||
self.buffer.clone(),
|
||||
cx,
|
||||
)
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
cx.emit(EditorEvent::ExcerptsAdded {
|
||||
@@ -14695,15 +14671,18 @@ impl Editor {
|
||||
self.handle_input(text, window, cx);
|
||||
}
|
||||
|
||||
pub fn supports_inlay_hints(&self, cx: &App) -> bool {
|
||||
pub fn supports_inlay_hints(&self, cx: &mut App) -> bool {
|
||||
let Some(provider) = self.semantics_provider.as_ref() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let mut supports = false;
|
||||
self.buffer().read(cx).for_each_buffer(|buffer| {
|
||||
supports |= provider.supports_inlay_hints(buffer, cx);
|
||||
self.buffer().update(cx, |this, cx| {
|
||||
this.for_each_buffer(|buffer| {
|
||||
supports |= provider.supports_inlay_hints(buffer, cx);
|
||||
});
|
||||
});
|
||||
|
||||
supports
|
||||
}
|
||||
|
||||
@@ -15251,7 +15230,7 @@ pub trait SemanticsProvider {
|
||||
cx: &mut App,
|
||||
) -> Option<Task<anyhow::Result<InlayHint>>>;
|
||||
|
||||
fn supports_inlay_hints(&self, buffer: &Entity<Buffer>, cx: &App) -> bool;
|
||||
fn supports_inlay_hints(&self, buffer: &Entity<Buffer>, cx: &mut App) -> bool;
|
||||
|
||||
fn document_highlights(
|
||||
&self,
|
||||
@@ -15645,17 +15624,13 @@ impl SemanticsProvider for Entity<Project> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn supports_inlay_hints(&self, buffer: &Entity<Buffer>, cx: &App) -> bool {
|
||||
fn supports_inlay_hints(&self, buffer: &Entity<Buffer>, cx: &mut App) -> bool {
|
||||
// TODO: make this work for remote projects
|
||||
self.read(cx)
|
||||
.language_servers_for_local_buffer(buffer.read(cx), cx)
|
||||
.any(
|
||||
|(_, server)| match server.capabilities().inlay_hint_provider {
|
||||
Some(lsp::OneOf::Left(enabled)) => enabled,
|
||||
Some(lsp::OneOf::Right(_)) => true,
|
||||
None => false,
|
||||
},
|
||||
)
|
||||
self.update(cx, |this, cx| {
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
this.any_language_server_supports_inlay_hints(buffer, cx)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn inlay_hints(
|
||||
@@ -16117,7 +16092,7 @@ impl Render for Editor {
|
||||
font_family: settings.buffer_font.family.clone(),
|
||||
font_features: settings.buffer_font.features.clone(),
|
||||
font_fallbacks: settings.buffer_font.fallbacks.clone(),
|
||||
font_size: settings.buffer_font_size().into(),
|
||||
font_size: settings.buffer_font_size(cx).into(),
|
||||
font_weight: settings.buffer_font.weight,
|
||||
line_height: relative(settings.buffer_line_height.value()),
|
||||
..Default::default()
|
||||
|
||||
@@ -13193,28 +13193,6 @@ async fn test_diff_base_change_with_expanded_diff_hunks(
|
||||
|
||||
cx.set_diff_base("new diff base!");
|
||||
executor.run_until_parked();
|
||||
cx.assert_state_with_diff(
|
||||
r#"
|
||||
use some::mod2;
|
||||
|
||||
const A: u32 = 42;
|
||||
const C: u32 = 42;
|
||||
|
||||
fn main(ˇ) {
|
||||
//println!("hello");
|
||||
|
||||
println!("world");
|
||||
//
|
||||
//
|
||||
}
|
||||
"#
|
||||
.unindent(),
|
||||
);
|
||||
|
||||
cx.update_editor(|editor, window, cx| {
|
||||
editor.expand_all_diff_hunks(&ExpandAllHunkDiffs, window, cx);
|
||||
});
|
||||
executor.run_until_parked();
|
||||
cx.assert_state_with_diff(
|
||||
r#"
|
||||
- new diff base!
|
||||
|
||||
@@ -15,14 +15,13 @@ use crate::{
|
||||
items::BufferSearchHighlights,
|
||||
mouse_context_menu::{self, MenuPosition, MouseContextMenu},
|
||||
scroll::{axis_pair, scroll_amount::ScrollAmount, AxisPair},
|
||||
AcceptEditPrediction, BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayPoint,
|
||||
DisplayRow, DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode,
|
||||
BlockId, ChunkReplacement, CursorShape, CustomBlockId, DisplayPoint, DisplayRow,
|
||||
DocumentHighlightRead, DocumentHighlightWrite, EditDisplayMode, Editor, EditorMode,
|
||||
EditorSettings, EditorSnapshot, EditorStyle, ExpandExcerpts, FocusedBlock, GoToHunk,
|
||||
GoToPrevHunk, GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor,
|
||||
InlineCompletion, JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point,
|
||||
RevertSelectedHunks, RowExt, RowRangeExt, SelectPhase, Selection, SoftWrap,
|
||||
StickyHeaderExcerpt, ToPoint, ToggleFold, CURSORS_VISIBLE_FOR,
|
||||
EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT, FILE_HEADER_HEIGHT,
|
||||
GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor, InlineCompletion,
|
||||
JumpData, LineDown, LineUp, OpenExcerpts, PageDown, PageUp, Point, RevertSelectedHunks, RowExt,
|
||||
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};
|
||||
@@ -32,14 +31,14 @@ 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 as _,
|
||||
FontId, GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement,
|
||||
KeyBindingContextPredicate, Keystroke, Length, ModifiersChangedEvent, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta,
|
||||
ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled,
|
||||
Subscription, TextRun, TextStyleRefinement, WeakEntity, Window,
|
||||
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable, FontId,
|
||||
GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, Keystroke, Length,
|
||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
|
||||
ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size,
|
||||
StatefulInteractiveElement, Style, Styled, Subscription, TextRun, TextStyleRefinement,
|
||||
WeakEntity, Window,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::{
|
||||
@@ -55,7 +54,7 @@ use multi_buffer::{
|
||||
RowInfo, ToOffset,
|
||||
};
|
||||
use project::project_settings::{GitGutterSetting, ProjectSettings};
|
||||
use settings::{KeyBindingValidator, KeyBindingValidatorRegistration, Settings};
|
||||
use settings::Settings;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::{
|
||||
any::TypeId,
|
||||
@@ -75,21 +74,24 @@ use ui::{
|
||||
POPOVER_Y_PADDING,
|
||||
};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use util::{markdown::MarkdownString, RangeExt, ResultExt};
|
||||
use util::{RangeExt, ResultExt};
|
||||
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,
|
||||
@@ -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)
|
||||
@@ -1918,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
|
||||
@@ -2658,6 +2731,7 @@ impl EditorElement {
|
||||
&OpenExcerpts,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.map(|binding| binding.into_any_element()),
|
||||
),
|
||||
@@ -4136,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
|
||||
{
|
||||
@@ -4167,13 +4256,16 @@ impl EditorElement {
|
||||
let y = display_row_range.start.as_f32() * line_height
|
||||
+ text_hitbox.bounds.top()
|
||||
- scroll_pixel_position.y;
|
||||
let x = text_hitbox.bounds.right() - px(100.);
|
||||
let x = text_hitbox.bounds.right()
|
||||
- rems(6.).to_pixels(window.rem_size())
|
||||
- px(33.);
|
||||
|
||||
let mut element = diff_hunk_controls(
|
||||
display_row_range.start.0,
|
||||
multi_buffer_range.clone(),
|
||||
line_height,
|
||||
&editor,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
element.prepaint_as_root(
|
||||
@@ -4339,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)) => {
|
||||
@@ -4537,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 {
|
||||
@@ -4555,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) => (
|
||||
@@ -4595,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(),
|
||||
));
|
||||
@@ -4716,7 +4829,15 @@ impl EditorElement {
|
||||
) {
|
||||
for (_, hunk_hitbox) in &layout.display_hunks {
|
||||
if let Some(hunk_hitbox) = hunk_hitbox {
|
||||
window.set_cursor_style(CursorStyle::PointingHand, hunk_hitbox);
|
||||
if !self
|
||||
.editor
|
||||
.read(cx)
|
||||
.buffer()
|
||||
.read(cx)
|
||||
.all_diff_hunks_expanded()
|
||||
{
|
||||
window.set_cursor_style(CursorStyle::PointingHand, hunk_hitbox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4731,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;
|
||||
@@ -5290,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,
|
||||
@@ -5598,7 +5725,7 @@ impl EditorElement {
|
||||
window.on_mouse_event({
|
||||
let position_map = layout.position_map.clone();
|
||||
let editor = self.editor.clone();
|
||||
let multi_buffer_range =
|
||||
let diff_hunk_range =
|
||||
layout
|
||||
.display_hunks
|
||||
.iter()
|
||||
@@ -5634,7 +5761,7 @@ impl EditorElement {
|
||||
Self::mouse_left_down(
|
||||
editor,
|
||||
event,
|
||||
multi_buffer_range.clone(),
|
||||
diff_hunk_range.clone(),
|
||||
&position_map,
|
||||
line_numbers.as_ref(),
|
||||
window,
|
||||
@@ -5834,50 +5961,6 @@ impl AcceptEditPredictionBinding {
|
||||
}
|
||||
}
|
||||
|
||||
struct AcceptEditPredictionsBindingValidator;
|
||||
|
||||
inventory::submit! { KeyBindingValidatorRegistration(|| Box::new(AcceptEditPredictionsBindingValidator)) }
|
||||
|
||||
impl KeyBindingValidator for AcceptEditPredictionsBindingValidator {
|
||||
fn action_type_id(&self) -> TypeId {
|
||||
TypeId::of::<AcceptEditPrediction>()
|
||||
}
|
||||
|
||||
fn validate(&self, binding: &gpui::KeyBinding) -> Result<(), MarkdownString> {
|
||||
use KeyBindingContextPredicate::*;
|
||||
|
||||
if binding.keystrokes().len() == 1 && binding.keystrokes()[0].modifiers.modified() {
|
||||
return Ok(());
|
||||
}
|
||||
let required_predicate =
|
||||
Not(Identifier(EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT.into()).into());
|
||||
match binding.predicate() {
|
||||
Some(predicate) if required_predicate.is_superset(&predicate) => {
|
||||
return Ok(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let negated_requires_modifier_key_context = MarkdownString::inline_code(&format!(
|
||||
"!{}",
|
||||
EDIT_PREDICTION_REQUIRES_MODIFIER_KEY_CONTEXT
|
||||
));
|
||||
Err(MarkdownString(format!(
|
||||
"{} can only be bound to a single keystroke with modifiers, so \
|
||||
that pressing these modifiers can be used for prediction \
|
||||
preview.\n\n\
|
||||
This restriction does not apply when the context requires {}, \
|
||||
since these bindings are not used for prediction preview. For \
|
||||
example, in the default keymap `tab` requires {}, and `alt-tab` \
|
||||
is used otherwise.\n\n\
|
||||
See [the documentation]({}) for more details.",
|
||||
MarkdownString::inline_code(AcceptEditPrediction.name()),
|
||||
negated_requires_modifier_key_context.clone(),
|
||||
negated_requires_modifier_key_context,
|
||||
"https://zed.dev/docs/completions#edit-predictions",
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn prepaint_gutter_button(
|
||||
button: IconButton,
|
||||
@@ -6917,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,
|
||||
};
|
||||
@@ -7797,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>)>,
|
||||
@@ -8961,8 +9022,13 @@ fn diff_hunk_controls(
|
||||
hunk_range: Range<Anchor>,
|
||||
line_height: Pixels,
|
||||
editor: &Entity<Editor>,
|
||||
_window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> AnyElement {
|
||||
let stage = editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.buffer.read(cx).snapshot(cx);
|
||||
editor.has_stageable_diff_hunks_in_ranges(&[hunk_range.start..hunk_range.start], &snapshot)
|
||||
});
|
||||
h_flex()
|
||||
.h(line_height)
|
||||
.mr_1()
|
||||
@@ -8975,59 +9041,7 @@ fn diff_hunk_controls(
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.gap_1()
|
||||
.child(
|
||||
IconButton::new(("next-hunk", row as u64), IconName::ArrowDown)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small)
|
||||
// .disabled(!has_multiple_hunks)
|
||||
.tooltip({
|
||||
let focus_handle = editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
Tooltip::for_action_in("Next Hunk", &GoToHunk, &focus_handle, window, cx)
|
||||
}
|
||||
})
|
||||
.on_click({
|
||||
let editor = editor.clone();
|
||||
move |_event, window, cx| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let position = hunk_range.end.to_point(&snapshot.buffer_snapshot);
|
||||
editor.go_to_hunk_after_position(&snapshot, position, window, cx);
|
||||
editor.expand_selected_diff_hunks(cx);
|
||||
});
|
||||
}
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
IconButton::new(("prev-hunk", row as u64), IconName::ArrowUp)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small)
|
||||
// .disabled(!has_multiple_hunks)
|
||||
.tooltip({
|
||||
let focus_handle = editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
Tooltip::for_action_in(
|
||||
"Previous Hunk",
|
||||
&GoToPrevHunk,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
})
|
||||
.on_click({
|
||||
let editor = editor.clone();
|
||||
move |_event, window, cx| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let point = hunk_range.start.to_point(&snapshot.buffer_snapshot);
|
||||
editor.go_to_hunk_before_position(&snapshot, point, window, cx);
|
||||
editor.expand_selected_diff_hunks(cx);
|
||||
});
|
||||
}
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
IconButton::new("discard", IconName::Undo)
|
||||
IconButton::new(("discard-hunk", row as u64), IconName::Undo)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small)
|
||||
.tooltip({
|
||||
@@ -9048,10 +9062,59 @@ fn diff_hunk_controls(
|
||||
editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let point = hunk_range.start.to_point(&snapshot.buffer_snapshot);
|
||||
editor.revert_hunks_in_ranges([point..point].into_iter(), window, cx);
|
||||
editor.discard_hunks_in_ranges([point..point].into_iter(), window, cx);
|
||||
});
|
||||
}
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
Button::new(("skip-hunk", row as u64), "Skip")
|
||||
.label_size(LabelSize::Small)
|
||||
.tooltip({
|
||||
let focus_handle = editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
Tooltip::for_action_in("Skip Hunk", &GoToHunk, &focus_handle, window, cx)
|
||||
}
|
||||
})
|
||||
.on_click({
|
||||
let editor = editor.clone();
|
||||
move |_event, window, cx| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let position = hunk_range.end.to_point(&snapshot.buffer_snapshot);
|
||||
editor.go_to_hunk_after_position(&snapshot, position, window, cx);
|
||||
editor.expand_selected_diff_hunks(cx);
|
||||
});
|
||||
}
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
Button::new(
|
||||
("stage-unstage-hunk", row as u64),
|
||||
if stage { "Stage" } else { "Unstage" },
|
||||
)
|
||||
.label_size(LabelSize::Small)
|
||||
.tooltip({
|
||||
let focus_handle = editor.focus_handle(cx);
|
||||
move |window, cx| {
|
||||
Tooltip::for_action_in(
|
||||
if stage { "Stage Hunk" } else { "Unstage Hunk" },
|
||||
&ToggleStagedSelectedDiffHunks,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
})
|
||||
.on_click({
|
||||
let editor = editor.clone();
|
||||
move |_event, _window, cx| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
editor
|
||||
.stage_or_unstage_diff_hunks(&[hunk_range.start..hunk_range.start], cx);
|
||||
});
|
||||
}
|
||||
}),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
@@ -1401,11 +1401,9 @@ impl SearchableItem for Editor {
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.unfold_ranges(matches, false, false, cx);
|
||||
let mut ranges = Vec::new();
|
||||
for m in matches {
|
||||
ranges.push(self.range_for_match(m))
|
||||
}
|
||||
self.change_selections(None, window, cx, |s| s.select_ranges(ranges));
|
||||
self.change_selections(None, window, cx, |s| {
|
||||
s.select_ranges(matches.iter().cloned())
|
||||
});
|
||||
}
|
||||
fn replace(
|
||||
&mut self,
|
||||
|
||||
@@ -21,7 +21,6 @@ where
|
||||
let Some(project) = &editor.project else {
|
||||
return None;
|
||||
};
|
||||
let multibuffer = editor.buffer().read(cx);
|
||||
let mut language_servers_for = HashMap::default();
|
||||
editor
|
||||
.selections
|
||||
@@ -29,29 +28,21 @@ where
|
||||
.iter()
|
||||
.filter(|selection| selection.start == selection.end)
|
||||
.filter_map(|selection| Some((selection.start.buffer_id?, selection.start)))
|
||||
.filter_map(|(buffer_id, trigger_anchor)| {
|
||||
let buffer = multibuffer.buffer(buffer_id)?;
|
||||
.find_map(|(buffer_id, trigger_anchor)| {
|
||||
let buffer = editor.buffer().read(cx).buffer(buffer_id)?;
|
||||
let server_id = *match language_servers_for.entry(buffer_id) {
|
||||
Entry::Occupied(occupied_entry) => occupied_entry.into_mut(),
|
||||
Entry::Vacant(vacant_entry) => {
|
||||
let language_server_id = project
|
||||
.read(cx)
|
||||
.language_servers_for_local_buffer(buffer.read(cx), cx)
|
||||
.find_map(|(adapter, server)| {
|
||||
if adapter.name.0.as_ref() == language_server_name {
|
||||
Some(server.server_id())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
let language_server_id = buffer.update(cx, |buffer, cx| {
|
||||
project.update(cx, |project, cx| {
|
||||
project.language_server_id_for_name(buffer, language_server_name, cx)
|
||||
})
|
||||
});
|
||||
vacant_entry.insert(language_server_id)
|
||||
}
|
||||
}
|
||||
.as_ref()?;
|
||||
|
||||
Some((buffer, trigger_anchor, server_id))
|
||||
})
|
||||
.find_map(|(buffer, trigger_anchor, server_id)| {
|
||||
let language = buffer.read(cx).language_at(trigger_anchor.text_anchor)?;
|
||||
if !filter_language(&language) {
|
||||
return None;
|
||||
|
||||
@@ -387,7 +387,7 @@ impl Render for ProposedChangesEditorToolbar {
|
||||
Some(editor) => {
|
||||
let focus_handle = editor.focus_handle(cx);
|
||||
let keybinding =
|
||||
KeyBinding::for_action_in(&ApplyAllDiffHunks, &focus_handle, window)
|
||||
KeyBinding::for_action_in(&ApplyAllDiffHunks, &focus_handle, window, cx)
|
||||
.map(|binding| binding.into_any_element());
|
||||
|
||||
button_like.children(keybinding).on_click({
|
||||
@@ -467,7 +467,7 @@ impl SemanticsProvider for BranchBufferSemanticsProvider {
|
||||
self.0.resolve_inlay_hint(hint, buffer, server_id, cx)
|
||||
}
|
||||
|
||||
fn supports_inlay_hints(&self, buffer: &Entity<Buffer>, cx: &App) -> bool {
|
||||
fn supports_inlay_hints(&self, buffer: &Entity<Buffer>, cx: &mut App) -> bool {
|
||||
if let Some(buffer) = self.to_base(&buffer, &[], cx) {
|
||||
self.0.supports_inlay_hints(&buffer, cx)
|
||||
} else {
|
||||
|
||||
@@ -731,8 +731,9 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) {
|
||||
|
||||
// Start a new instance of the language server.
|
||||
project.update(cx, |project, cx| {
|
||||
project.restart_language_servers_for_buffers([buffer.clone()], cx)
|
||||
project.restart_language_servers_for_buffers(vec![buffer.clone()], cx)
|
||||
});
|
||||
cx.executor().run_until_parked();
|
||||
|
||||
// The extension has cached the binary path, and does not attempt
|
||||
// to reinstall it.
|
||||
@@ -752,7 +753,7 @@ async fn test_extension_store_with_test_extension(cx: &mut TestAppContext) {
|
||||
|
||||
cx.executor().run_until_parked();
|
||||
project.update(cx, |project, cx| {
|
||||
project.restart_language_servers_for_buffers([buffer.clone()], cx)
|
||||
project.restart_language_servers_for_buffers(vec![buffer.clone()], cx)
|
||||
});
|
||||
|
||||
// The extension re-fetches the latest version of the language server.
|
||||
|
||||
@@ -64,12 +64,6 @@ impl FeatureFlag for PredictEditsFeatureFlag {
|
||||
const NAME: &'static str = "predict-edits";
|
||||
}
|
||||
|
||||
/// A feature flag that controls things that shouldn't go live until the predictive edits launch.
|
||||
pub struct PredictEditsLaunchFeatureFlag;
|
||||
impl FeatureFlag for PredictEditsLaunchFeatureFlag {
|
||||
const NAME: &'static str = "predict-edits-launch";
|
||||
}
|
||||
|
||||
pub struct PredictEditsRateCompletionsFeatureFlag;
|
||||
impl FeatureFlag for PredictEditsRateCompletionsFeatureFlag {
|
||||
const NAME: &'static str = "predict-edits-rate-completions";
|
||||
|
||||
@@ -1317,7 +1317,7 @@ impl PickerDelegate for FileFinderDelegate {
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.child(
|
||||
Button::new("open-selection", "Open")
|
||||
.key_binding(KeyBinding::for_action(&menu::Confirm, window))
|
||||
.key_binding(KeyBinding::for_action(&menu::Confirm, window, cx))
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(menu::Confirm.boxed_clone(), cx)
|
||||
}),
|
||||
@@ -1334,6 +1334,7 @@ impl PickerDelegate for FileFinderDelegate {
|
||||
&ToggleMenu,
|
||||
&context,
|
||||
window,
|
||||
cx,
|
||||
)),
|
||||
)
|
||||
.menu({
|
||||
|
||||
@@ -23,7 +23,7 @@ async fn test_matching_paths(cx: &mut TestAppContext) {
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"a": {
|
||||
"banana": "",
|
||||
@@ -33,7 +33,7 @@ async fn test_matching_paths(cx: &mut TestAppContext) {
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
|
||||
let (picker, workspace, cx) = build_find_picker(project, cx);
|
||||
|
||||
@@ -153,7 +153,7 @@ async fn test_complex_path(cx: &mut TestAppContext) {
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/root",
|
||||
path!("/root"),
|
||||
json!({
|
||||
"其他": {
|
||||
"S数据表格": {
|
||||
@@ -164,7 +164,7 @@ async fn test_complex_path(cx: &mut TestAppContext) {
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/root".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/root").as_ref()], cx).await;
|
||||
|
||||
let (picker, workspace, cx) = build_find_picker(project, cx);
|
||||
|
||||
@@ -194,7 +194,7 @@ async fn test_row_column_numbers_query_inside_file(cx: &mut TestAppContext) {
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
first_file_name: first_file_contents,
|
||||
@@ -204,7 +204,7 @@ async fn test_row_column_numbers_query_inside_file(cx: &mut TestAppContext) {
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
|
||||
let (picker, workspace, cx) = build_find_picker(project, cx);
|
||||
|
||||
@@ -269,7 +269,7 @@ async fn test_row_column_numbers_query_outside_file(cx: &mut TestAppContext) {
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/src",
|
||||
path!("/src"),
|
||||
json!({
|
||||
"test": {
|
||||
first_file_name: first_file_contents,
|
||||
@@ -279,7 +279,7 @@ async fn test_row_column_numbers_query_outside_file(cx: &mut TestAppContext) {
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/src".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/src").as_ref()], cx).await;
|
||||
|
||||
let (picker, workspace, cx) = build_find_picker(project, cx);
|
||||
|
||||
@@ -1777,7 +1777,7 @@ async fn test_opens_file_on_modifier_keys_release(cx: &mut gpui::TestAppContext)
|
||||
.fs
|
||||
.as_fake()
|
||||
.insert_tree(
|
||||
"/test",
|
||||
path!("/test"),
|
||||
json!({
|
||||
"1.txt": "// One",
|
||||
"2.txt": "// Two",
|
||||
@@ -1785,7 +1785,7 @@ async fn test_opens_file_on_modifier_keys_release(cx: &mut gpui::TestAppContext)
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(app_state.fs.clone(), ["/test".as_ref()], cx).await;
|
||||
let project = Project::test(app_state.fs.clone(), [path!("/test").as_ref()], cx).await;
|
||||
let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project, window, cx));
|
||||
|
||||
open_queried_buffer("1", 1, "1.txt", &workspace, cx).await;
|
||||
|
||||
@@ -13,11 +13,8 @@ path = "src/file_icons.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
collections.workspace = true
|
||||
gpui.workspace = true
|
||||
serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
theme.workspace = true
|
||||
util.workspace = true
|
||||
|
||||
@@ -1,52 +1,33 @@
|
||||
use std::sync::Arc;
|
||||
use std::{path::Path, str};
|
||||
|
||||
use collections::HashMap;
|
||||
|
||||
use gpui::{App, AssetSource, Global, SharedString};
|
||||
use serde_derive::Deserialize;
|
||||
use gpui::{App, SharedString};
|
||||
use settings::Settings;
|
||||
use theme::{IconTheme, ThemeRegistry, ThemeSettings};
|
||||
use util::paths::PathExt;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub struct FileIcons {
|
||||
stems: HashMap<String, String>,
|
||||
suffixes: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Global for FileIcons {}
|
||||
|
||||
pub const FILE_TYPES_ASSET: &str = "icons/file_icons/file_types.json";
|
||||
|
||||
pub fn init(assets: impl AssetSource, cx: &mut App) {
|
||||
cx.set_global(FileIcons::new(assets))
|
||||
icon_theme: Arc<IconTheme>,
|
||||
}
|
||||
|
||||
impl FileIcons {
|
||||
pub fn get(cx: &App) -> &Self {
|
||||
cx.global::<FileIcons>()
|
||||
}
|
||||
pub fn get(cx: &App) -> Self {
|
||||
let theme_settings = ThemeSettings::get_global(cx);
|
||||
|
||||
pub fn new(assets: impl AssetSource) -> Self {
|
||||
assets
|
||||
.load(FILE_TYPES_ASSET)
|
||||
.ok()
|
||||
.flatten()
|
||||
.and_then(|file| serde_json::from_str::<FileIcons>(str::from_utf8(&file).unwrap()).ok())
|
||||
.unwrap_or_else(|| FileIcons {
|
||||
stems: HashMap::default(),
|
||||
suffixes: HashMap::default(),
|
||||
})
|
||||
Self {
|
||||
icon_theme: theme_settings.active_icon_theme.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_icon(path: &Path, cx: &App) -> Option<SharedString> {
|
||||
let this = cx.try_global::<Self>()?;
|
||||
let this = Self::get(cx);
|
||||
|
||||
let get_icon_from_suffix = |suffix: &str| -> Option<SharedString> {
|
||||
this.stems
|
||||
this.icon_theme
|
||||
.file_stems
|
||||
.get(suffix)
|
||||
.or_else(|| this.suffixes.get(suffix))
|
||||
.or_else(|| this.icon_theme.file_suffixes.get(suffix))
|
||||
.and_then(|typ| this.get_icon_for_type(typ, cx))
|
||||
};
|
||||
// TODO: Associate a type with the languages and have the file's language
|
||||
|
||||
@@ -37,7 +37,8 @@ actions!(
|
||||
// editor::RevertSelectedHunks
|
||||
StageAll,
|
||||
UnstageAll,
|
||||
RevertAll,
|
||||
DiscardTrackedChanges,
|
||||
TrashUntrackedFiles,
|
||||
Uncommit,
|
||||
Commit,
|
||||
ClearCommitMessage
|
||||
|
||||
@@ -111,6 +111,7 @@ pub trait GitRepository: Send + Sync {
|
||||
fn branch_exits(&self, _: &str) -> Result<bool>;
|
||||
|
||||
fn reset(&self, commit: &str, mode: ResetMode) -> Result<()>;
|
||||
fn checkout_files(&self, commit: &str, paths: &[RepoPath]) -> Result<()>;
|
||||
|
||||
fn show(&self, commit: &str) -> Result<CommitDetails>;
|
||||
|
||||
@@ -233,6 +234,31 @@ impl GitRepository for RealGitRepository {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn checkout_files(&self, commit: &str, paths: &[RepoPath]) -> Result<()> {
|
||||
if paths.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
let working_directory = self
|
||||
.repository
|
||||
.lock()
|
||||
.workdir()
|
||||
.context("failed to read git work directory")?
|
||||
.to_path_buf();
|
||||
|
||||
let output = new_std_command(&self.git_binary_path)
|
||||
.current_dir(&working_directory)
|
||||
.args(["checkout", commit, "--"])
|
||||
.args(paths.iter().map(|path| path.as_ref()))
|
||||
.output()?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!(
|
||||
"Failed to checkout files:\n{}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_index_text(&self, path: &RepoPath) -> Option<String> {
|
||||
fn logic(repo: &git2::Repository, path: &RepoPath) -> Result<Option<String>> {
|
||||
const STAGE_NORMAL: i32 = 0;
|
||||
@@ -371,7 +397,7 @@ impl GitRepository for RealGitRepository {
|
||||
"%(contents:subject)",
|
||||
]
|
||||
.join("%00");
|
||||
let args = vec!["for-each-ref", "refs/heads/*", "--format", &fields];
|
||||
let args = vec!["for-each-ref", "refs/heads/**/*", "--format", &fields];
|
||||
|
||||
let output = new_std_command(&self.git_binary_path)
|
||||
.current_dir(&working_directory)
|
||||
@@ -617,6 +643,10 @@ impl GitRepository for FakeGitRepository {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn checkout_files(&self, _: &str, _: &[RepoPath]) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn path(&self) -> PathBuf {
|
||||
let state = self.state.lock();
|
||||
state.path.clone()
|
||||
|
||||
@@ -36,6 +36,7 @@ serde.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
strum.workspace = true
|
||||
theme.workspace = true
|
||||
time.workspace = true
|
||||
ui.workspace = true
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::git_panel_settings::StatusStyle;
|
||||
use crate::repository_selector::RepositorySelectorPopoverMenu;
|
||||
use crate::ProjectDiff;
|
||||
use crate::{
|
||||
git_panel_settings::GitPanelSettings, git_status_icon, repository_selector::RepositorySelector,
|
||||
};
|
||||
use crate::{project_diff, ProjectDiff};
|
||||
use collections::HashMap;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::commit_tooltip::CommitTooltip;
|
||||
@@ -13,6 +13,7 @@ use editor::{
|
||||
};
|
||||
use git::repository::{CommitDetails, ResetMode};
|
||||
use git::{repository::RepoPath, status::FileStatus, Commit, ToggleStaged};
|
||||
use git::{DiscardTrackedChanges, StageAll, TrashUntrackedFiles, UnstageAll};
|
||||
use gpui::*;
|
||||
use itertools::Itertools;
|
||||
use language::{markdown, Buffer, File, ParsedMarkdown};
|
||||
@@ -26,13 +27,13 @@ use project::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::Settings as _;
|
||||
use std::{collections::HashSet, path::PathBuf, sync::Arc, time::Duration, usize};
|
||||
use strum::{IntoEnumIterator, VariantNames};
|
||||
use time::OffsetDateTime;
|
||||
use ui::{
|
||||
prelude::*, ButtonLike, Checkbox, ContextMenu, Divider, DividerColor, ElevationIndex, ListItem,
|
||||
ListItemSpacing, Scrollbar, ScrollbarState, Tooltip,
|
||||
};
|
||||
use util::{maybe, ResultExt, TryFutureExt};
|
||||
use workspace::SaveIntent;
|
||||
use workspace::{
|
||||
dock::{DockPosition, Panel, PanelEvent},
|
||||
notifications::{DetachAndPromptErr, NotificationId},
|
||||
@@ -51,6 +52,21 @@ actions!(
|
||||
]
|
||||
);
|
||||
|
||||
fn prompt<T>(msg: &str, detail: Option<&str>, window: &mut Window, cx: &mut App) -> Task<Result<T>>
|
||||
where
|
||||
T: IntoEnumIterator + VariantNames + 'static,
|
||||
{
|
||||
let rx = window.prompt(PromptLevel::Info, msg, detail, &T::VARIANTS, cx);
|
||||
cx.spawn(|_| async move { Ok(T::iter().nth(rx.await?).unwrap()) })
|
||||
}
|
||||
|
||||
#[derive(strum::EnumIter, strum::VariantNames)]
|
||||
#[strum(serialize_all = "title_case")]
|
||||
enum TrashCancel {
|
||||
Trash,
|
||||
Cancel,
|
||||
}
|
||||
|
||||
const GIT_PANEL_KEY: &str = "GitPanel";
|
||||
|
||||
const UPDATE_DEBOUNCE: Duration = Duration::from_millis(50);
|
||||
@@ -112,8 +128,8 @@ impl GitHeaderEntry {
|
||||
pub fn title(&self) -> &'static str {
|
||||
match self.header {
|
||||
Section::Conflict => "Conflicts",
|
||||
Section::Tracked => "Changes",
|
||||
Section::New => "New",
|
||||
Section::Tracked => "Tracked",
|
||||
Section::New => "Untracked",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,9 +158,17 @@ pub struct GitStatusEntry {
|
||||
pub(crate) is_staged: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum TargetStatus {
|
||||
Staged,
|
||||
Unstaged,
|
||||
Reverted,
|
||||
Unchanged,
|
||||
}
|
||||
|
||||
struct PendingOperation {
|
||||
finished: bool,
|
||||
will_become_staged: bool,
|
||||
target_status: TargetStatus,
|
||||
repo_paths: HashSet<RepoPath>,
|
||||
op_id: usize,
|
||||
}
|
||||
@@ -599,7 +623,7 @@ impl GitPanel {
|
||||
});
|
||||
}
|
||||
|
||||
fn revert(
|
||||
fn revert_selected(
|
||||
&mut self,
|
||||
_: &editor::actions::RevertFile,
|
||||
window: &mut Window,
|
||||
@@ -608,28 +632,37 @@ impl GitPanel {
|
||||
maybe!({
|
||||
let list_entry = self.entries.get(self.selected_entry?)?.clone();
|
||||
let entry = list_entry.status_entry()?;
|
||||
let active_repo = self.active_repository.as_ref()?;
|
||||
self.revert_entry(&entry, window, cx);
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn revert_entry(
|
||||
&mut self,
|
||||
entry: &GitStatusEntry,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
maybe!({
|
||||
let active_repo = self.active_repository.clone()?;
|
||||
let path = active_repo
|
||||
.read(cx)
|
||||
.repo_path_to_project_path(&entry.repo_path)?;
|
||||
let workspace = self.workspace.clone();
|
||||
|
||||
if entry.status.is_staged() != Some(false) {
|
||||
self.update_staging_area_for_entries(false, vec![entry.repo_path.clone()], cx);
|
||||
self.perform_stage(false, vec![entry.repo_path.clone()], cx);
|
||||
}
|
||||
let filename = path.path.file_name()?.to_string_lossy();
|
||||
|
||||
if entry.status.is_created() {
|
||||
let prompt = window.prompt(
|
||||
PromptLevel::Info,
|
||||
"Do you want to trash this file?",
|
||||
None,
|
||||
&["Trash", "Cancel"],
|
||||
cx,
|
||||
);
|
||||
if !entry.status.is_created() {
|
||||
self.perform_checkout(vec![entry.repo_path.clone()], cx);
|
||||
} else {
|
||||
let prompt = prompt(&format!("Trash {}?", filename), None, window, cx);
|
||||
cx.spawn_in(window, |_, mut cx| async move {
|
||||
match prompt.await {
|
||||
Ok(0) => {}
|
||||
_ => return Ok(()),
|
||||
match prompt.await? {
|
||||
TrashCancel::Trash => {}
|
||||
TrashCancel::Cancel => return Ok(()),
|
||||
}
|
||||
let task = workspace.update(&mut cx, |workspace, cx| {
|
||||
workspace
|
||||
@@ -647,45 +680,235 @@ impl GitPanel {
|
||||
cx,
|
||||
|e, _, _| Some(format!("{e}")),
|
||||
);
|
||||
return Some(());
|
||||
}
|
||||
|
||||
let open_path = workspace.update(cx, |workspace, cx| {
|
||||
workspace.open_path_preview(path, None, true, false, window, cx)
|
||||
});
|
||||
|
||||
cx.spawn_in(window, |_, mut cx| async move {
|
||||
let item = open_path?.await?;
|
||||
let editor = cx.update(|_, cx| {
|
||||
item.act_as::<Editor>(cx)
|
||||
.ok_or_else(|| anyhow::anyhow!("didn't open editor"))
|
||||
})??;
|
||||
|
||||
if let Some(task) =
|
||||
editor.update(&mut cx, |editor, _| editor.wait_for_diff_to_load())?
|
||||
{
|
||||
task.await
|
||||
};
|
||||
|
||||
editor.update_in(&mut cx, |editor, window, cx| {
|
||||
editor.revert_file(&Default::default(), window, cx);
|
||||
})?;
|
||||
|
||||
workspace
|
||||
.update_in(&mut cx, |workspace, window, cx| {
|
||||
workspace.save_active_item(SaveIntent::Save, window, cx)
|
||||
})?
|
||||
.await?;
|
||||
Ok(())
|
||||
})
|
||||
.detach_and_prompt_err("Failed to open file", window, cx, |e, _, _| {
|
||||
Some(format!("{e}"))
|
||||
});
|
||||
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn perform_checkout(&mut self, repo_paths: Vec<RepoPath>, cx: &mut Context<Self>) {
|
||||
let workspace = self.workspace.clone();
|
||||
let Some(active_repository) = self.active_repository.clone() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let op_id = self.pending.iter().map(|p| p.op_id).max().unwrap_or(0) + 1;
|
||||
self.pending.push(PendingOperation {
|
||||
op_id,
|
||||
target_status: TargetStatus::Reverted,
|
||||
repo_paths: repo_paths.iter().cloned().collect(),
|
||||
finished: false,
|
||||
});
|
||||
self.update_visible_entries(cx);
|
||||
let task = cx.spawn(|_, mut cx| async move {
|
||||
let tasks: Vec<_> = workspace.update(&mut cx, |workspace, cx| {
|
||||
workspace.project().update(cx, |project, cx| {
|
||||
repo_paths
|
||||
.iter()
|
||||
.filter_map(|repo_path| {
|
||||
let path = active_repository
|
||||
.read(cx)
|
||||
.repo_path_to_project_path(&repo_path)?;
|
||||
Some(project.open_buffer(path, cx))
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
})?;
|
||||
|
||||
let buffers = futures::future::join_all(tasks).await;
|
||||
|
||||
active_repository
|
||||
.update(&mut cx, |repo, _| repo.checkout_files("HEAD", repo_paths))?
|
||||
.await??;
|
||||
|
||||
let tasks: Vec<_> = cx.update(|cx| {
|
||||
buffers
|
||||
.iter()
|
||||
.filter_map(|buffer| {
|
||||
buffer.as_ref().ok()?.update(cx, |buffer, cx| {
|
||||
buffer.is_dirty().then(|| buffer.reload(cx))
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
})?;
|
||||
|
||||
futures::future::join_all(tasks).await;
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let result = task.await;
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
for pending in this.pending.iter_mut() {
|
||||
if pending.op_id == op_id {
|
||||
pending.finished = true;
|
||||
if result.is_err() {
|
||||
pending.target_status = TargetStatus::Unchanged;
|
||||
this.update_visible_entries(cx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
result
|
||||
.map_err(|e| {
|
||||
this.show_err_toast(e, cx);
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn discard_tracked_changes(
|
||||
&mut self,
|
||||
_: &DiscardTrackedChanges,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let entries = self
|
||||
.entries
|
||||
.iter()
|
||||
.filter_map(|entry| entry.status_entry().cloned())
|
||||
.filter(|status_entry| !status_entry.status.is_created())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
match entries.len() {
|
||||
0 => return,
|
||||
1 => return self.revert_entry(&entries[0], window, cx),
|
||||
_ => {}
|
||||
}
|
||||
let details = entries
|
||||
.iter()
|
||||
.filter_map(|entry| entry.repo_path.0.file_name())
|
||||
.map(|filename| filename.to_string_lossy())
|
||||
.join("\n");
|
||||
|
||||
#[derive(strum::EnumIter, strum::VariantNames)]
|
||||
#[strum(serialize_all = "title_case")]
|
||||
enum DiscardCancel {
|
||||
DiscardTrackedChanges,
|
||||
Cancel,
|
||||
}
|
||||
let prompt = prompt(
|
||||
"Discard changes to these files?",
|
||||
Some(&details),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
match prompt.await {
|
||||
Ok(DiscardCancel::DiscardTrackedChanges) => {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
let repo_paths = entries.into_iter().map(|entry| entry.repo_path).collect();
|
||||
this.perform_checkout(repo_paths, cx);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
fn clean_all(&mut self, _: &TrashUntrackedFiles, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let workspace = self.workspace.clone();
|
||||
let Some(active_repo) = self.active_repository.clone() else {
|
||||
return;
|
||||
};
|
||||
let to_delete = self
|
||||
.entries
|
||||
.iter()
|
||||
.filter_map(|entry| entry.status_entry())
|
||||
.filter(|status_entry| status_entry.status.is_created())
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
match to_delete.len() {
|
||||
0 => return,
|
||||
1 => return self.revert_entry(&to_delete[0], window, cx),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
let details = to_delete
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
entry
|
||||
.repo_path
|
||||
.0
|
||||
.file_name()
|
||||
.map(|f| f.to_string_lossy())
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.join("\n");
|
||||
|
||||
let prompt = prompt("Trash these files?", Some(&details), window, cx);
|
||||
cx.spawn_in(window, |this, mut cx| async move {
|
||||
match prompt.await? {
|
||||
TrashCancel::Trash => {}
|
||||
TrashCancel::Cancel => return Ok(()),
|
||||
}
|
||||
let tasks = workspace.update(&mut cx, |workspace, cx| {
|
||||
to_delete
|
||||
.iter()
|
||||
.filter_map(|entry| {
|
||||
workspace.project().update(cx, |project, cx| {
|
||||
let project_path = active_repo
|
||||
.read(cx)
|
||||
.repo_path_to_project_path(&entry.repo_path)?;
|
||||
project.delete_file(project_path, true, cx)
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})?;
|
||||
let to_unstage = to_delete
|
||||
.into_iter()
|
||||
.filter_map(|entry| {
|
||||
if entry.status.is_staged() != Some(false) {
|
||||
Some(entry.repo_path.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.perform_stage(false, to_unstage, cx)
|
||||
})?;
|
||||
for task in tasks {
|
||||
task.await?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.detach_and_prompt_err("Failed to trash files", window, cx, |e, _, _| {
|
||||
Some(format!("{e}"))
|
||||
});
|
||||
}
|
||||
|
||||
fn stage_all(&mut self, _: &StageAll, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
let repo_paths = self
|
||||
.entries
|
||||
.iter()
|
||||
.filter_map(|entry| entry.status_entry())
|
||||
.filter(|status_entry| status_entry.is_staged != Some(true))
|
||||
.map(|status_entry| status_entry.repo_path.clone())
|
||||
.collect::<Vec<_>>();
|
||||
self.perform_stage(true, repo_paths, cx);
|
||||
}
|
||||
|
||||
fn unstage_all(&mut self, _: &UnstageAll, _window: &mut Window, cx: &mut Context<Self>) {
|
||||
let repo_paths = self
|
||||
.entries
|
||||
.iter()
|
||||
.filter_map(|entry| entry.status_entry())
|
||||
.filter(|status_entry| status_entry.is_staged != Some(false))
|
||||
.map(|status_entry| status_entry.repo_path.clone())
|
||||
.collect::<Vec<_>>();
|
||||
self.perform_stage(false, repo_paths, cx);
|
||||
}
|
||||
|
||||
fn toggle_staged_for_entry(
|
||||
&mut self,
|
||||
entry: &GitListEntry,
|
||||
@@ -720,22 +943,21 @@ impl GitPanel {
|
||||
(goal_staged_state, entries)
|
||||
}
|
||||
};
|
||||
self.update_staging_area_for_entries(stage, repo_paths, cx);
|
||||
self.perform_stage(stage, repo_paths, cx);
|
||||
}
|
||||
|
||||
fn update_staging_area_for_entries(
|
||||
&mut self,
|
||||
stage: bool,
|
||||
repo_paths: Vec<RepoPath>,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
fn perform_stage(&mut self, stage: bool, repo_paths: Vec<RepoPath>, cx: &mut Context<Self>) {
|
||||
let Some(active_repository) = self.active_repository.clone() else {
|
||||
return;
|
||||
};
|
||||
let op_id = self.pending.iter().map(|p| p.op_id).max().unwrap_or(0) + 1;
|
||||
self.pending.push(PendingOperation {
|
||||
op_id,
|
||||
will_become_staged: stage,
|
||||
target_status: if stage {
|
||||
TargetStatus::Staged
|
||||
} else {
|
||||
TargetStatus::Unstaged
|
||||
},
|
||||
repo_paths: repo_paths.iter().cloned().collect(),
|
||||
finished: false,
|
||||
});
|
||||
@@ -749,14 +971,14 @@ impl GitPanel {
|
||||
let result = cx
|
||||
.update(|cx| {
|
||||
if stage {
|
||||
active_repository.read(cx).stage_entries(repo_paths.clone())
|
||||
active_repository
|
||||
.update(cx, |repo, cx| repo.stage_entries(repo_paths.clone(), cx))
|
||||
} else {
|
||||
active_repository
|
||||
.read(cx)
|
||||
.unstage_entries(repo_paths.clone())
|
||||
.update(cx, |repo, cx| repo.unstage_entries(repo_paths.clone(), cx))
|
||||
}
|
||||
})?
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
for pending in this.pending.iter_mut() {
|
||||
@@ -849,9 +1071,10 @@ impl GitPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
let stage_task = active_repository.read(cx).stage_entries(changed_files);
|
||||
let stage_task =
|
||||
active_repository.update(cx, |repo, cx| repo.stage_entries(changed_files, cx));
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
stage_task.await??;
|
||||
stage_task.await?;
|
||||
let commit_task = active_repository
|
||||
.update(&mut cx, |repo, _| repo.commit(message.into(), None))?;
|
||||
commit_task.await?
|
||||
@@ -1104,6 +1327,14 @@ impl GitPanel {
|
||||
let is_new = entry.status.is_created();
|
||||
let is_staged = entry.status.is_staged();
|
||||
|
||||
if self.pending.iter().any(|pending| {
|
||||
pending.target_status == TargetStatus::Reverted
|
||||
&& !pending.finished
|
||||
&& pending.repo_paths.contains(&entry.repo_path)
|
||||
}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let display_name = if difference > 1 {
|
||||
// Show partial path for deeply nested files
|
||||
entry
|
||||
@@ -1235,7 +1466,12 @@ impl GitPanel {
|
||||
fn entry_is_staged(&self, entry: &GitStatusEntry) -> Option<bool> {
|
||||
for pending in self.pending.iter().rev() {
|
||||
if pending.repo_paths.contains(&entry.repo_path) {
|
||||
return Some(pending.will_become_staged);
|
||||
match pending.target_status {
|
||||
TargetStatus::Staged => return Some(true),
|
||||
TargetStatus::Unstaged => return Some(false),
|
||||
TargetStatus::Reverted => continue,
|
||||
TargetStatus::Unchanged => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
entry.is_staged
|
||||
@@ -1247,6 +1483,10 @@ impl GitPanel {
|
||||
|| self.conflicted_staged_count > 0
|
||||
}
|
||||
|
||||
fn has_conflicts(&self) -> bool {
|
||||
self.conflicted_count > 0
|
||||
}
|
||||
|
||||
fn has_tracked_changes(&self) -> bool {
|
||||
self.tracked_count > 0
|
||||
}
|
||||
@@ -1315,10 +1555,17 @@ impl GitPanel {
|
||||
.is_above_project()
|
||||
});
|
||||
|
||||
self.panel_header_container(window, cx)
|
||||
.when(all_repositories.len() > 1 || has_repo_above, |el| {
|
||||
el.child(self.render_repository_selector(cx))
|
||||
})
|
||||
self.panel_header_container(window, cx).when(
|
||||
all_repositories.len() > 1 || has_repo_above,
|
||||
|el| {
|
||||
el.child(
|
||||
Label::new("Repository")
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(self.render_repository_selector(cx))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn render_repository_selector(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
@@ -1700,6 +1947,12 @@ impl GitPanel {
|
||||
.with_horizontal_sizing_behavior(ListHorizontalSizingBehavior::Unconstrained)
|
||||
.track_scroll(self.scroll_handle.clone()),
|
||||
)
|
||||
.on_mouse_down(
|
||||
MouseButton::Right,
|
||||
cx.listener(move |this, event: &MouseDownEvent, window, cx| {
|
||||
this.deploy_panel_context_menu(event.position, window, cx)
|
||||
}),
|
||||
)
|
||||
.children(self.render_scrollbar(cx))
|
||||
}
|
||||
|
||||
@@ -1742,7 +1995,7 @@ impl GitPanel {
|
||||
repo.update(cx, |repo, cx| repo.show(sha, cx))
|
||||
}
|
||||
|
||||
fn deploy_context_menu(
|
||||
fn deploy_entry_context_menu(
|
||||
&mut self,
|
||||
position: Point<Pixels>,
|
||||
ix: usize,
|
||||
@@ -1767,7 +2020,38 @@ impl GitPanel {
|
||||
.action("Open Diff", Confirm.boxed_clone())
|
||||
.action("Open File", SecondaryConfirm.boxed_clone())
|
||||
});
|
||||
self.selected_entry = Some(ix);
|
||||
self.set_context_menu(context_menu, position, window, cx);
|
||||
}
|
||||
|
||||
fn deploy_panel_context_menu(
|
||||
&mut self,
|
||||
position: Point<Pixels>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let context_menu = ContextMenu::build(window, cx, |context_menu, _, _| {
|
||||
context_menu
|
||||
.action("Stage All", StageAll.boxed_clone())
|
||||
.action("Unstage All", UnstageAll.boxed_clone())
|
||||
.action("Open Diff", project_diff::Diff.boxed_clone())
|
||||
.separator()
|
||||
.action(
|
||||
"Discard Tracked Changes",
|
||||
DiscardTrackedChanges.boxed_clone(),
|
||||
)
|
||||
.action("Trash Untracked Files", TrashUntrackedFiles.boxed_clone())
|
||||
});
|
||||
self.set_context_menu(context_menu, position, window, cx);
|
||||
}
|
||||
|
||||
fn set_context_menu(
|
||||
&mut self,
|
||||
context_menu: Entity<ContextMenu>,
|
||||
position: Point<Pixels>,
|
||||
window: &Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let subscription = cx.subscribe_in(
|
||||
&context_menu,
|
||||
window,
|
||||
@@ -1781,7 +2065,6 @@ impl GitPanel {
|
||||
cx.notify();
|
||||
},
|
||||
);
|
||||
self.selected_entry = Some(ix);
|
||||
self.context_menu = Some((context_menu, position, subscription));
|
||||
cx.notify();
|
||||
}
|
||||
@@ -1833,14 +2116,14 @@ impl GitPanel {
|
||||
|
||||
let mut is_staged: ToggleState = self.entry_is_staged(entry).into();
|
||||
|
||||
if !self.has_staged_changes() && !entry.status.is_created() {
|
||||
if !self.has_staged_changes() && !self.has_conflicts() && !entry.status.is_created() {
|
||||
is_staged = ToggleState::Selected;
|
||||
}
|
||||
|
||||
let checkbox = Checkbox::new(id, is_staged)
|
||||
.disabled(!has_write_access)
|
||||
.fill()
|
||||
.placeholder(!self.has_staged_changes())
|
||||
.placeholder(!self.has_staged_changes() && !self.has_conflicts())
|
||||
.elevation(ElevationIndex::Surface)
|
||||
.on_click({
|
||||
let entry = entry.clone();
|
||||
@@ -1887,7 +2170,8 @@ impl GitPanel {
|
||||
})
|
||||
.on_secondary_mouse_down(cx.listener(
|
||||
move |this, event: &MouseDownEvent, window, cx| {
|
||||
this.deploy_context_menu(event.position, ix, window, cx)
|
||||
this.deploy_entry_context_menu(event.position, ix, window, cx);
|
||||
cx.stop_propagation();
|
||||
},
|
||||
))
|
||||
.child(
|
||||
@@ -1920,12 +2204,7 @@ impl GitPanel {
|
||||
impl Render for GitPanel {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let project = self.project.read(cx);
|
||||
let has_entries = self
|
||||
.active_repository
|
||||
.as_ref()
|
||||
.map_or(false, |active_repository| {
|
||||
active_repository.read(cx).entry_count() > 0
|
||||
});
|
||||
let has_entries = self.entries.len() > 0;
|
||||
let room = self
|
||||
.workspace
|
||||
.upgrade()
|
||||
@@ -1958,10 +2237,14 @@ impl Render for GitPanel {
|
||||
.on_action(cx.listener(Self::close_panel))
|
||||
.on_action(cx.listener(Self::open_diff))
|
||||
.on_action(cx.listener(Self::open_file))
|
||||
.on_action(cx.listener(Self::revert))
|
||||
.on_action(cx.listener(Self::revert_selected))
|
||||
.on_action(cx.listener(Self::focus_changes_list))
|
||||
.on_action(cx.listener(Self::focus_editor))
|
||||
.on_action(cx.listener(Self::toggle_staged_for_selected))
|
||||
.on_action(cx.listener(Self::stage_all))
|
||||
.on_action(cx.listener(Self::unstage_all))
|
||||
.on_action(cx.listener(Self::discard_tracked_changes))
|
||||
.on_action(cx.listener(Self::clean_all))
|
||||
.when(has_write_access && has_co_authors, |git_panel| {
|
||||
git_panel.on_action(cx.listener(Self::toggle_fill_co_authors))
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::any::{Any, TypeId};
|
||||
use anyhow::Result;
|
||||
use buffer_diff::BufferDiff;
|
||||
use collections::HashSet;
|
||||
use editor::{scroll::Autoscroll, Editor, EditorEvent};
|
||||
use editor::{scroll::Autoscroll, Editor, EditorEvent, ToPoint};
|
||||
use feature_flags::FeatureFlagViewExt;
|
||||
use futures::StreamExt;
|
||||
use gpui::{
|
||||
@@ -180,13 +180,6 @@ impl ProjectDiff {
|
||||
};
|
||||
let repo = git_repo.read(cx);
|
||||
|
||||
let Some(abs_path) = repo
|
||||
.repo_path_to_project_path(&entry.repo_path)
|
||||
.and_then(|project_path| self.project.read(cx).absolute_path(&project_path, cx))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let namespace = if repo.has_conflict(&entry.repo_path) {
|
||||
CONFLICT_NAMESPACE
|
||||
} else if entry.status.is_created() {
|
||||
@@ -195,7 +188,7 @@ impl ProjectDiff {
|
||||
TRACKED_NAMESPACE
|
||||
};
|
||||
|
||||
let path_key = PathKey::namespaced(namespace, &abs_path);
|
||||
let path_key = PathKey::namespaced(namespace, entry.repo_path.0.clone());
|
||||
|
||||
self.scroll_to_path(path_key, window, cx)
|
||||
}
|
||||
@@ -222,7 +215,12 @@ impl ProjectDiff {
|
||||
match event {
|
||||
EditorEvent::ScrollPositionChanged { .. } => editor.update(cx, |editor, cx| {
|
||||
let anchor = editor.scroll_manager.anchor().anchor;
|
||||
let Some((_, buffer, _)) = self.multibuffer.read(cx).excerpt_containing(anchor, cx)
|
||||
let multibuffer = self.multibuffer.read(cx);
|
||||
let snapshot = multibuffer.snapshot(cx);
|
||||
let mut point = anchor.to_point(&snapshot);
|
||||
point.row = (point.row + 1).min(snapshot.max_row().0);
|
||||
|
||||
let Some((_, buffer, _)) = self.multibuffer.read(cx).excerpt_containing(point, cx)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -266,9 +264,6 @@ impl ProjectDiff {
|
||||
let Some(project_path) = repo.repo_path_to_project_path(&entry.repo_path) else {
|
||||
continue;
|
||||
};
|
||||
let Some(abs_path) = self.project.read(cx).absolute_path(&project_path, cx) else {
|
||||
continue;
|
||||
};
|
||||
let namespace = if repo.has_conflict(&entry.repo_path) {
|
||||
CONFLICT_NAMESPACE
|
||||
} else if entry.status.is_created() {
|
||||
@@ -276,7 +271,7 @@ impl ProjectDiff {
|
||||
} else {
|
||||
TRACKED_NAMESPACE
|
||||
};
|
||||
let path_key = PathKey::namespaced(namespace, &abs_path);
|
||||
let path_key = PathKey::namespaced(namespace, entry.repo_path.0.clone());
|
||||
|
||||
previous_paths.remove(&path_key);
|
||||
let load_buffer = self
|
||||
@@ -344,12 +339,9 @@ impl ProjectDiff {
|
||||
.contains_focused(window, cx)
|
||||
{
|
||||
self.focus_handle.focus(window);
|
||||
} else if self.focus_handle.contains_focused(window, cx)
|
||||
&& !self.multibuffer.read(cx).is_empty()
|
||||
{
|
||||
} else if self.focus_handle.is_focused(window) && !self.multibuffer.read(cx).is_empty() {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.focus_handle(cx).focus(window);
|
||||
editor.move_to_beginning(&Default::default(), window, cx);
|
||||
});
|
||||
}
|
||||
if self.pending_scroll.as_ref() == Some(&path_key) {
|
||||
|
||||
@@ -298,6 +298,7 @@ mod tests {
|
||||
use project::{FakeFs, Project};
|
||||
use serde_json::json;
|
||||
use std::{num::NonZeroU32, sync::Arc, time::Duration};
|
||||
use util::path;
|
||||
use workspace::{AppState, Workspace};
|
||||
|
||||
#[gpui::test]
|
||||
@@ -305,7 +306,7 @@ mod tests {
|
||||
init_test(cx);
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"a.rs": indoc!{"
|
||||
struct SingleLine; // display line 0
|
||||
@@ -326,7 +327,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
let worktree_id = workspace.update(cx, |workspace, cx| {
|
||||
@@ -335,7 +336,9 @@ mod tests {
|
||||
})
|
||||
});
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/dir/a.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let editor = workspace
|
||||
@@ -414,14 +417,14 @@ mod tests {
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"a.rs": "ēlo"
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
@@ -437,7 +440,9 @@ mod tests {
|
||||
})
|
||||
});
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/dir/a.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let editor = workspace
|
||||
@@ -497,14 +502,14 @@ mod tests {
|
||||
let text = "ēlo你好";
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"a.rs": text
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
@@ -520,7 +525,9 @@ mod tests {
|
||||
})
|
||||
});
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/dir/a.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let editor = workspace
|
||||
@@ -573,14 +580,14 @@ mod tests {
|
||||
let text = "ēlo你好";
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
path!("/dir"),
|
||||
json!({
|
||||
"a.rs": text
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, ["/dir".as_ref()], cx).await;
|
||||
let project = Project::test(fs, [path!("/dir").as_ref()], cx).await;
|
||||
let (workspace, cx) =
|
||||
cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx));
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
@@ -596,7 +603,9 @@ mod tests {
|
||||
})
|
||||
});
|
||||
let _buffer = project
|
||||
.update(cx, |project, cx| project.open_local_buffer("/dir/a.rs", cx))
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer(path!("/dir/a.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let editor = workspace
|
||||
|
||||
@@ -133,7 +133,7 @@ pathfinder_geometry = "0.5"
|
||||
[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies]
|
||||
# Always used
|
||||
flume = "0.11"
|
||||
oo7 = { git = "https://github.com/zed-industries/oo7", branch = "avoid-crypto-panic" }
|
||||
oo7 = { version = "0.4.0", default-features = false, features = ["async-std", "native_crypto"] }
|
||||
|
||||
# Used in both windowing options
|
||||
ashpd = { workspace = true, optional = true }
|
||||
|
||||
@@ -286,8 +286,9 @@ impl TestAppContext {
|
||||
}
|
||||
|
||||
/// Simulates clicking a button in an platform-level alert dialog.
|
||||
pub fn simulate_prompt_answer(&self, button_ix: usize) {
|
||||
self.test_platform.simulate_prompt_answer(button_ix);
|
||||
#[track_caller]
|
||||
pub fn simulate_prompt_answer(&self, button: &str) {
|
||||
self.test_platform.simulate_prompt_answer(button);
|
||||
}
|
||||
|
||||
/// Returns true if there's an alert dialog open.
|
||||
@@ -295,6 +296,11 @@ impl TestAppContext {
|
||||
self.test_platform.has_pending_prompt()
|
||||
}
|
||||
|
||||
/// Returns true if there's an alert dialog open.
|
||||
pub fn pending_prompt(&self) -> Option<(String, String)> {
|
||||
self.test_platform.pending_prompt()
|
||||
}
|
||||
|
||||
/// All the urls that have been opened with cx.open_url() during this test.
|
||||
pub fn opened_url(&self) -> Option<String> {
|
||||
self.test_platform.opened_url.borrow().clone()
|
||||
|
||||
@@ -607,6 +607,25 @@ impl Default for Background {
|
||||
}
|
||||
}
|
||||
|
||||
impl Background {
|
||||
/// Gets the color of the background if there is one.
|
||||
pub fn color(&self) -> Option<Hsla> {
|
||||
match self.tag {
|
||||
BackgroundTag::Solid => Some(self.solid),
|
||||
BackgroundTag::LinearGradient => None,
|
||||
BackgroundTag::PatternSlash => Some(self.solid),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a background with a solid color
|
||||
pub fn solid_color(color: impl Into<Hsla>) -> Background {
|
||||
Background {
|
||||
solid: color.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a hash pattern background
|
||||
pub fn pattern_slash(color: Hsla, thickness: f32) -> Background {
|
||||
Background {
|
||||
|
||||
@@ -181,19 +181,12 @@ impl<P: LinuxClient + 'static> Platform for P {
|
||||
log::info!("Restarting process, using app path: {:?}", app_path);
|
||||
|
||||
// Script to wait for the current process to exit and then restart the app.
|
||||
// We also wait for possibly open TCP sockets by the process to be closed,
|
||||
// since on Linux it's not guaranteed that a process' resources have been
|
||||
// cleaned up when `kill -0` returns.
|
||||
let script = format!(
|
||||
r#"
|
||||
while kill -0 {pid} 2>/dev/null; do
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
while lsof -nP -iTCP -a -p {pid} 2>/dev/null; do
|
||||
sleep 0.1
|
||||
done
|
||||
|
||||
{app_path}
|
||||
"#,
|
||||
pid = app_pid,
|
||||
|
||||
@@ -64,9 +64,16 @@ impl ScreenCaptureSource for TestScreenCaptureSource {
|
||||
|
||||
impl ScreenCaptureStream for TestScreenCaptureStream {}
|
||||
|
||||
struct TestPrompt {
|
||||
msg: String,
|
||||
detail: Option<String>,
|
||||
answers: Vec<String>,
|
||||
tx: oneshot::Sender<usize>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct TestPrompts {
|
||||
multiple_choice: VecDeque<oneshot::Sender<usize>>,
|
||||
multiple_choice: VecDeque<TestPrompt>,
|
||||
new_path: VecDeque<(PathBuf, oneshot::Sender<Result<Option<PathBuf>>>)>,
|
||||
}
|
||||
|
||||
@@ -123,33 +130,64 @@ impl TestPlatform {
|
||||
.new_path
|
||||
.pop_front()
|
||||
.expect("no pending new path prompt");
|
||||
self.background_executor().set_waiting_hint(None);
|
||||
tx.send(Ok(select_path(&path))).ok();
|
||||
}
|
||||
|
||||
pub(crate) fn simulate_prompt_answer(&self, response_ix: usize) {
|
||||
let tx = self
|
||||
#[track_caller]
|
||||
pub(crate) fn simulate_prompt_answer(&self, response: &str) {
|
||||
let prompt = self
|
||||
.prompts
|
||||
.borrow_mut()
|
||||
.multiple_choice
|
||||
.pop_front()
|
||||
.expect("no pending multiple choice prompt");
|
||||
self.background_executor().set_waiting_hint(None);
|
||||
tx.send(response_ix).ok();
|
||||
let Some(ix) = prompt.answers.iter().position(|a| a == response) else {
|
||||
panic!(
|
||||
"PROMPT: {}\n{:?}\n{:?}\nCannot respond with {}",
|
||||
prompt.msg, prompt.detail, prompt.answers, response
|
||||
)
|
||||
};
|
||||
prompt.tx.send(ix).ok();
|
||||
}
|
||||
|
||||
pub(crate) fn has_pending_prompt(&self) -> bool {
|
||||
!self.prompts.borrow().multiple_choice.is_empty()
|
||||
}
|
||||
|
||||
pub(crate) fn pending_prompt(&self) -> Option<(String, String)> {
|
||||
let prompts = self.prompts.borrow();
|
||||
let prompt = prompts.multiple_choice.front()?;
|
||||
Some((
|
||||
prompt.msg.clone(),
|
||||
prompt.detail.clone().unwrap_or_default(),
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) fn set_screen_capture_sources(&self, sources: Vec<TestScreenCaptureSource>) {
|
||||
*self.screen_capture_sources.borrow_mut() = sources;
|
||||
}
|
||||
|
||||
pub(crate) fn prompt(&self, msg: &str, detail: Option<&str>) -> oneshot::Receiver<usize> {
|
||||
pub(crate) fn prompt(
|
||||
&self,
|
||||
msg: &str,
|
||||
detail: Option<&str>,
|
||||
answers: &[&str],
|
||||
) -> oneshot::Receiver<usize> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let answers: Vec<String> = answers.iter().map(|&s| s.to_string()).collect();
|
||||
self.background_executor()
|
||||
.set_waiting_hint(Some(format!("PROMPT: {:?} {:?}", msg, detail)));
|
||||
self.prompts.borrow_mut().multiple_choice.push_back(tx);
|
||||
self.prompts
|
||||
.borrow_mut()
|
||||
.multiple_choice
|
||||
.push_back(TestPrompt {
|
||||
msg: msg.to_string(),
|
||||
detail: detail.map(|s| s.to_string()),
|
||||
answers: answers.clone(),
|
||||
tx,
|
||||
});
|
||||
rx
|
||||
}
|
||||
|
||||
@@ -292,6 +330,8 @@ impl Platform for TestPlatform {
|
||||
directory: &std::path::Path,
|
||||
) -> oneshot::Receiver<Result<Option<std::path::PathBuf>>> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
self.background_executor()
|
||||
.set_waiting_hint(Some(format!("PROMPT FOR PATH: {:?}", directory)));
|
||||
self.prompts
|
||||
.borrow_mut()
|
||||
.new_path
|
||||
|
||||
@@ -159,7 +159,7 @@ impl PlatformWindow for TestWindow {
|
||||
_level: crate::PromptLevel,
|
||||
msg: &str,
|
||||
detail: Option<&str>,
|
||||
_answers: &[&str],
|
||||
answers: &[&str],
|
||||
) -> Option<futures::channel::oneshot::Receiver<usize>> {
|
||||
Some(
|
||||
self.0
|
||||
@@ -167,7 +167,7 @@ impl PlatformWindow for TestWindow {
|
||||
.platform
|
||||
.upgrade()
|
||||
.expect("platform dropped")
|
||||
.prompt(msg, detail),
|
||||
.prompt(msg, detail, answers),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1201,14 +1201,23 @@ fn handle_system_theme_changed(
|
||||
|
||||
fn parse_syskeydown_msg_keystroke(wparam: WPARAM) -> Option<Keystroke> {
|
||||
let modifiers = current_modifiers();
|
||||
if !modifiers.alt {
|
||||
// on Windows, F10 can trigger this event, not just the alt key
|
||||
// and we just don't care about F10
|
||||
return None;
|
||||
}
|
||||
|
||||
let vk_code = wparam.loword();
|
||||
|
||||
// on Windows, F10 can trigger this event, not just the alt key,
|
||||
// so when F10 was pressed, handle only it
|
||||
if !modifiers.alt {
|
||||
if vk_code == VK_F10.0 {
|
||||
let offset = vk_code - VK_F1.0;
|
||||
return Some(Keystroke {
|
||||
modifiers,
|
||||
key: format!("f{}", offset + 1),
|
||||
key_char: None,
|
||||
});
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
let key = match VIRTUAL_KEY(vk_code) {
|
||||
VK_BACK => "backspace",
|
||||
VK_RETURN => "enter",
|
||||
@@ -1226,7 +1235,23 @@ fn parse_syskeydown_msg_keystroke(wparam: WPARAM) -> Option<Keystroke> {
|
||||
VK_ESCAPE => "escape",
|
||||
VK_INSERT => "insert",
|
||||
VK_DELETE => "delete",
|
||||
_ => return basic_vkcode_to_string(vk_code, modifiers),
|
||||
_ => {
|
||||
let basic_key = basic_vkcode_to_string(vk_code, modifiers);
|
||||
if basic_key.is_some() {
|
||||
return basic_key;
|
||||
} else {
|
||||
if vk_code >= VK_F1.0 && vk_code <= VK_F24.0 {
|
||||
let offset = vk_code - VK_F1.0;
|
||||
return Some(Keystroke {
|
||||
modifiers,
|
||||
key: format!("f{}", offset + 1),
|
||||
key_char: None,
|
||||
});
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.to_owned();
|
||||
|
||||
|
||||
@@ -622,6 +622,41 @@ impl HighlightedText {
|
||||
gpui::StyledText::new(self.text.clone())
|
||||
.with_highlights(default_style, self.highlights.iter().cloned())
|
||||
}
|
||||
|
||||
/// Returns the first line without leading whitespace unless highlighted
|
||||
/// and a boolean indicating if there are more lines after
|
||||
pub fn first_line_preview(self) -> (Self, bool) {
|
||||
let newline_ix = self.text.find('\n').unwrap_or(self.text.len());
|
||||
let first_line = &self.text[..newline_ix];
|
||||
|
||||
// Trim leading whitespace, unless an edit starts prior to it.
|
||||
let mut preview_start_ix = first_line.len() - first_line.trim_start().len();
|
||||
if let Some((first_highlight_range, _)) = self.highlights.first() {
|
||||
preview_start_ix = preview_start_ix.min(first_highlight_range.start);
|
||||
}
|
||||
|
||||
let preview_text = &first_line[preview_start_ix..];
|
||||
let preview_highlights = self
|
||||
.highlights
|
||||
.into_iter()
|
||||
.take_while(|(range, _)| range.start < newline_ix)
|
||||
.filter_map(|(mut range, highlight)| {
|
||||
range.start = range.start.saturating_sub(preview_start_ix);
|
||||
range.end = range.end.saturating_sub(preview_start_ix).min(newline_ix);
|
||||
if range.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some((range, highlight))
|
||||
}
|
||||
});
|
||||
|
||||
let preview = Self {
|
||||
text: SharedString::new(preview_text),
|
||||
highlights: preview_highlights.collect(),
|
||||
};
|
||||
|
||||
(preview, self.text.len() > newline_ix)
|
||||
}
|
||||
}
|
||||
|
||||
impl HighlightedTextBuilder {
|
||||
|
||||
@@ -44,7 +44,6 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde_json::Value;
|
||||
use settings::WorktreeId;
|
||||
use smol::future::FutureExt as _;
|
||||
use std::num::NonZeroU32;
|
||||
use std::{
|
||||
any::Any,
|
||||
ffi::OsStr,
|
||||
@@ -60,6 +59,7 @@ use std::{
|
||||
Arc, LazyLock,
|
||||
},
|
||||
};
|
||||
use std::{num::NonZeroU32, sync::OnceLock};
|
||||
use syntax_map::{QueryCursorHandle, SyntaxSnapshot};
|
||||
use task::RunnableTag;
|
||||
pub use task_context::{ContextProvider, RunnableRange};
|
||||
@@ -162,6 +162,7 @@ pub struct CachedLspAdapter {
|
||||
pub adapter: Arc<dyn LspAdapter>,
|
||||
pub reinstall_attempt_count: AtomicU64,
|
||||
cached_binary: futures::lock::Mutex<Option<LanguageServerBinary>>,
|
||||
attach_kind: OnceLock<Attach>,
|
||||
}
|
||||
|
||||
impl Debug for CachedLspAdapter {
|
||||
@@ -197,6 +198,7 @@ impl CachedLspAdapter {
|
||||
adapter,
|
||||
cached_binary: Default::default(),
|
||||
reinstall_attempt_count: AtomicU64::new(0),
|
||||
attach_kind: Default::default(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -258,6 +260,38 @@ impl CachedLspAdapter {
|
||||
.cloned()
|
||||
.unwrap_or_else(|| language_name.lsp_id())
|
||||
}
|
||||
pub fn find_project_root(
|
||||
&self,
|
||||
path: &Path,
|
||||
ancestor_depth: usize,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
) -> Option<Arc<Path>> {
|
||||
self.adapter
|
||||
.find_project_root(path, ancestor_depth, delegate)
|
||||
}
|
||||
pub fn attach_kind(&self) -> Attach {
|
||||
*self.attach_kind.get_or_init(|| self.adapter.attach_kind())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum Attach {
|
||||
/// Create a single language server instance per subproject root.
|
||||
InstancePerRoot,
|
||||
/// Use one shared language server instance for all subprojects within a project.
|
||||
Shared,
|
||||
}
|
||||
|
||||
impl Attach {
|
||||
pub fn root_path(
|
||||
&self,
|
||||
root_subproject_path: (WorktreeId, Arc<Path>),
|
||||
) -> (WorktreeId, Arc<Path>) {
|
||||
match self {
|
||||
Attach::InstancePerRoot => root_subproject_path,
|
||||
Attach::Shared => (root_subproject_path.0, Arc::from(Path::new(""))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// [`LspAdapterDelegate`] allows [`LspAdapter]` implementations to interface with the application
|
||||
@@ -268,6 +302,7 @@ pub trait LspAdapterDelegate: Send + Sync {
|
||||
fn http_client(&self) -> Arc<dyn HttpClient>;
|
||||
fn worktree_id(&self) -> WorktreeId;
|
||||
fn worktree_root_path(&self) -> &Path;
|
||||
fn exists(&self, path: &Path, is_dir: Option<bool>) -> bool;
|
||||
fn update_status(&self, language: LanguageServerName, status: LanguageServerBinaryStatus);
|
||||
async fn language_server_download_dir(&self, name: &LanguageServerName) -> Option<Arc<Path>>;
|
||||
|
||||
@@ -506,6 +541,19 @@ pub trait LspAdapter: 'static + Send + Sync {
|
||||
fn prepare_initialize_params(&self, original: InitializeParams) -> Result<InitializeParams> {
|
||||
Ok(original)
|
||||
}
|
||||
fn attach_kind(&self) -> Attach {
|
||||
Attach::Shared
|
||||
}
|
||||
fn find_project_root(
|
||||
&self,
|
||||
|
||||
_path: &Path,
|
||||
_ancestor_depth: usize,
|
||||
_: &Arc<dyn LspAdapterDelegate>,
|
||||
) -> Option<Arc<Path>> {
|
||||
// By default all language servers are rooted at the root of the worktree.
|
||||
Some(Arc::from("".as_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
async fn try_fetch_server_binary<L: LspAdapter + 'static + Send + Sync + ?Sized>(
|
||||
|
||||
@@ -108,6 +108,7 @@ struct LanguageRegistryState {
|
||||
available_languages: Vec<AvailableLanguage>,
|
||||
grammars: HashMap<Arc<str>, AvailableGrammar>,
|
||||
lsp_adapters: HashMap<LanguageName, Vec<Arc<CachedLspAdapter>>>,
|
||||
all_lsp_adapters: HashMap<LanguageServerName, Arc<CachedLspAdapter>>,
|
||||
available_lsp_adapters:
|
||||
HashMap<LanguageServerName, Arc<dyn Fn() -> Arc<CachedLspAdapter> + 'static + Send + Sync>>,
|
||||
loading_languages: HashMap<LanguageId, Vec<oneshot::Sender<Result<Arc<Language>>>>>,
|
||||
@@ -234,6 +235,7 @@ impl LanguageRegistry {
|
||||
language_settings: Default::default(),
|
||||
loading_languages: Default::default(),
|
||||
lsp_adapters: Default::default(),
|
||||
all_lsp_adapters: Default::default(),
|
||||
available_lsp_adapters: HashMap::default(),
|
||||
subscription: watch::channel(),
|
||||
theme: Default::default(),
|
||||
@@ -356,12 +358,16 @@ impl LanguageRegistry {
|
||||
adapter: Arc<dyn LspAdapter>,
|
||||
) -> Arc<CachedLspAdapter> {
|
||||
let cached = CachedLspAdapter::new(adapter);
|
||||
self.state
|
||||
.write()
|
||||
let mut state = self.state.write();
|
||||
state
|
||||
.lsp_adapters
|
||||
.entry(language_name)
|
||||
.or_default()
|
||||
.push(cached.clone());
|
||||
state
|
||||
.all_lsp_adapters
|
||||
.insert(cached.name.clone(), cached.clone());
|
||||
|
||||
cached
|
||||
}
|
||||
|
||||
@@ -401,12 +407,17 @@ impl LanguageRegistry {
|
||||
let adapter_name = LanguageServerName(adapter.name.into());
|
||||
let capabilities = adapter.capabilities.clone();
|
||||
let initializer = adapter.initializer.take();
|
||||
self.state
|
||||
.write()
|
||||
.lsp_adapters
|
||||
.entry(language_name.clone())
|
||||
.or_default()
|
||||
.push(CachedLspAdapter::new(Arc::new(adapter)));
|
||||
let adapter = CachedLspAdapter::new(Arc::new(adapter));
|
||||
{
|
||||
let mut state = self.state.write();
|
||||
state
|
||||
.lsp_adapters
|
||||
.entry(language_name.clone())
|
||||
.or_default()
|
||||
.push(adapter.clone());
|
||||
state.all_lsp_adapters.insert(adapter.name(), adapter);
|
||||
}
|
||||
|
||||
self.register_fake_language_server(adapter_name, capabilities, initializer)
|
||||
}
|
||||
|
||||
@@ -419,12 +430,16 @@ impl LanguageRegistry {
|
||||
adapter: crate::FakeLspAdapter,
|
||||
) {
|
||||
let language_name = language_name.into();
|
||||
self.state
|
||||
.write()
|
||||
let mut state = self.state.write();
|
||||
let cached_adapter = CachedLspAdapter::new(Arc::new(adapter));
|
||||
state
|
||||
.lsp_adapters
|
||||
.entry(language_name.clone())
|
||||
.or_default()
|
||||
.push(CachedLspAdapter::new(Arc::new(adapter)));
|
||||
.push(cached_adapter.clone());
|
||||
state
|
||||
.all_lsp_adapters
|
||||
.insert(cached_adapter.name(), cached_adapter);
|
||||
}
|
||||
|
||||
/// Register a fake language server (without the adapter)
|
||||
@@ -895,6 +910,10 @@ impl LanguageRegistry {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn adapter_for_name(&self, name: &LanguageServerName) -> Option<Arc<CachedLspAdapter>> {
|
||||
self.state.read().all_lsp_adapters.get(name).cloned()
|
||||
}
|
||||
|
||||
pub fn update_lsp_status(
|
||||
&self,
|
||||
server_name: LanguageServerName,
|
||||
|
||||
@@ -28,6 +28,7 @@ http_client.workspace = true
|
||||
image.workspace = true
|
||||
lmstudio = { workspace = true, features = ["schemars"] }
|
||||
log.workspace = true
|
||||
mistral = { workspace = true, features = ["schemars"] }
|
||||
ollama = { workspace = true, features = ["schemars"] }
|
||||
open_ai = { workspace = true, features = ["schemars"] }
|
||||
parking_lot.workspace = true
|
||||
|
||||
@@ -269,6 +269,47 @@ impl LanguageModelRequest {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_mistral(self, model: String, max_output_tokens: Option<u32>) -> mistral::Request {
|
||||
let len = self.messages.len();
|
||||
let merged_messages =
|
||||
self.messages
|
||||
.into_iter()
|
||||
.fold(Vec::with_capacity(len), |mut acc, msg| {
|
||||
let role = msg.role;
|
||||
let content = msg.string_contents();
|
||||
|
||||
acc.push(match role {
|
||||
Role::User => mistral::RequestMessage::User { content },
|
||||
Role::Assistant => mistral::RequestMessage::Assistant {
|
||||
content: Some(content),
|
||||
tool_calls: Vec::new(),
|
||||
},
|
||||
Role::System => mistral::RequestMessage::System { content },
|
||||
});
|
||||
acc
|
||||
});
|
||||
|
||||
mistral::Request {
|
||||
model,
|
||||
messages: merged_messages,
|
||||
stream: true,
|
||||
max_tokens: max_output_tokens,
|
||||
temperature: self.temperature,
|
||||
response_format: None,
|
||||
tools: self
|
||||
.tools
|
||||
.into_iter()
|
||||
.map(|tool| mistral::ToolDefinition::Function {
|
||||
function: mistral::FunctionDefinition {
|
||||
name: tool.name,
|
||||
description: Some(tool.description),
|
||||
parameters: Some(tool.input_schema),
|
||||
},
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_google(self, model: String) -> google_ai::GenerateContentRequest {
|
||||
google_ai::GenerateContentRequest {
|
||||
model,
|
||||
|
||||
@@ -28,6 +28,7 @@ http_client.workspace = true
|
||||
language_model.workspace = true
|
||||
lmstudio = { workspace = true, features = ["schemars"] }
|
||||
menu.workspace = true
|
||||
mistral = { workspace = true, features = ["schemars"] }
|
||||
ollama = { workspace = true, features = ["schemars"] }
|
||||
open_ai = { workspace = true, features = ["schemars"] }
|
||||
project.workspace = true
|
||||
|
||||
@@ -17,6 +17,7 @@ pub use crate::provider::cloud::RefreshLlmTokenListener;
|
||||
use crate::provider::copilot_chat::CopilotChatLanguageModelProvider;
|
||||
use crate::provider::google::GoogleLanguageModelProvider;
|
||||
use crate::provider::lmstudio::LmStudioLanguageModelProvider;
|
||||
use crate::provider::mistral::MistralLanguageModelProvider;
|
||||
use crate::provider::ollama::OllamaLanguageModelProvider;
|
||||
use crate::provider::open_ai::OpenAiLanguageModelProvider;
|
||||
pub use crate::settings::*;
|
||||
@@ -64,6 +65,10 @@ fn register_language_model_providers(
|
||||
GoogleLanguageModelProvider::new(client.http_client(), cx),
|
||||
cx,
|
||||
);
|
||||
registry.register_provider(
|
||||
MistralLanguageModelProvider::new(client.http_client(), cx),
|
||||
cx,
|
||||
);
|
||||
registry.register_provider(CopilotChatLanguageModelProvider::new(cx), cx);
|
||||
|
||||
cx.observe_flag::<feature_flags::LanguageModels, _>(move |enabled, cx| {
|
||||
|
||||
@@ -4,5 +4,6 @@ pub mod copilot_chat;
|
||||
pub mod deepseek;
|
||||
pub mod google;
|
||||
pub mod lmstudio;
|
||||
pub mod mistral;
|
||||
pub mod ollama;
|
||||
pub mod open_ai;
|
||||
|
||||
573
crates/language_models/src/provider/mistral.rs
Normal file
573
crates/language_models/src/provider/mistral.rs
Normal file
@@ -0,0 +1,573 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use collections::BTreeMap;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use futures::{future::BoxFuture, FutureExt, StreamExt};
|
||||
use gpui::{
|
||||
AnyView, App, AsyncApp, Context, Entity, FontStyle, Subscription, Task, TextStyle, WhiteSpace,
|
||||
};
|
||||
use http_client::HttpClient;
|
||||
use language_model::{
|
||||
LanguageModel, LanguageModelCompletionEvent, LanguageModelId, LanguageModelName,
|
||||
LanguageModelProvider, LanguageModelProviderId, LanguageModelProviderName,
|
||||
LanguageModelProviderState, LanguageModelRequest, RateLimiter, Role,
|
||||
};
|
||||
|
||||
use futures::stream::BoxStream;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::{Settings, SettingsStore};
|
||||
use std::sync::Arc;
|
||||
use strum::IntoEnumIterator;
|
||||
use theme::ThemeSettings;
|
||||
use ui::{prelude::*, Icon, IconName, Tooltip};
|
||||
use util::ResultExt;
|
||||
|
||||
use crate::AllLanguageModelSettings;
|
||||
|
||||
const PROVIDER_ID: &str = "mistral";
|
||||
const PROVIDER_NAME: &str = "Mistral";
|
||||
|
||||
#[derive(Default, Clone, Debug, PartialEq)]
|
||||
pub struct MistralSettings {
|
||||
pub api_url: String,
|
||||
pub available_models: Vec<AvailableModel>,
|
||||
pub needs_setting_migration: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
|
||||
pub struct AvailableModel {
|
||||
pub name: String,
|
||||
pub display_name: Option<String>,
|
||||
pub max_tokens: usize,
|
||||
pub max_output_tokens: Option<u32>,
|
||||
pub max_completion_tokens: Option<u32>,
|
||||
}
|
||||
|
||||
pub struct MistralLanguageModelProvider {
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
state: gpui::Entity<State>,
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
api_key: Option<String>,
|
||||
api_key_from_env: bool,
|
||||
_subscription: Subscription,
|
||||
}
|
||||
|
||||
const MISTRAL_API_KEY_VAR: &str = "MISTRAL_API_KEY";
|
||||
|
||||
impl State {
|
||||
fn is_authenticated(&self) -> bool {
|
||||
self.api_key.is_some()
|
||||
}
|
||||
|
||||
fn reset_api_key(&self, cx: &mut Context<Self>) -> Task<Result<()>> {
|
||||
let settings = &AllLanguageModelSettings::get_global(cx).mistral;
|
||||
let delete_credentials = cx.delete_credentials(&settings.api_url);
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
delete_credentials.await.log_err();
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.api_key = None;
|
||||
this.api_key_from_env = false;
|
||||
cx.notify();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn set_api_key(&mut self, api_key: String, cx: &mut Context<Self>) -> Task<Result<()>> {
|
||||
let settings = &AllLanguageModelSettings::get_global(cx).mistral;
|
||||
let write_credentials =
|
||||
cx.write_credentials(&settings.api_url, "Bearer", api_key.as_bytes());
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
write_credentials.await?;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.api_key = Some(api_key);
|
||||
cx.notify();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn authenticate(&self, cx: &mut Context<Self>) -> Task<Result<()>> {
|
||||
if self.is_authenticated() {
|
||||
Task::ready(Ok(()))
|
||||
} else {
|
||||
let api_url = AllLanguageModelSettings::get_global(cx)
|
||||
.mistral
|
||||
.api_url
|
||||
.clone();
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
let (api_key, from_env) = if let Ok(api_key) = std::env::var(MISTRAL_API_KEY_VAR) {
|
||||
(api_key, true)
|
||||
} else {
|
||||
let (_, api_key) = cx
|
||||
.update(|cx| cx.read_credentials(&api_url))?
|
||||
.await?
|
||||
.ok_or_else(|| anyhow!("credentials not found"))?;
|
||||
(String::from_utf8(api_key)?, false)
|
||||
};
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.api_key = Some(api_key);
|
||||
this.api_key_from_env = from_env;
|
||||
cx.notify();
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MistralLanguageModelProvider {
|
||||
pub fn new(http_client: Arc<dyn HttpClient>, cx: &mut App) -> Self {
|
||||
let state = cx.new(|cx| State {
|
||||
api_key: None,
|
||||
api_key_from_env: false,
|
||||
_subscription: cx.observe_global::<SettingsStore>(|_this: &mut State, cx| {
|
||||
cx.notify();
|
||||
}),
|
||||
});
|
||||
|
||||
Self { http_client, state }
|
||||
}
|
||||
}
|
||||
|
||||
impl LanguageModelProviderState for MistralLanguageModelProvider {
|
||||
type ObservableEntity = State;
|
||||
|
||||
fn observable_entity(&self) -> Option<gpui::Entity<Self::ObservableEntity>> {
|
||||
Some(self.state.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl LanguageModelProvider for MistralLanguageModelProvider {
|
||||
fn id(&self) -> LanguageModelProviderId {
|
||||
LanguageModelProviderId(PROVIDER_ID.into())
|
||||
}
|
||||
|
||||
fn name(&self) -> LanguageModelProviderName {
|
||||
LanguageModelProviderName(PROVIDER_NAME.into())
|
||||
}
|
||||
|
||||
fn icon(&self) -> IconName {
|
||||
IconName::AiMistral
|
||||
}
|
||||
|
||||
fn provided_models(&self, cx: &App) -> Vec<Arc<dyn LanguageModel>> {
|
||||
let mut models = BTreeMap::default();
|
||||
|
||||
// Add base models from mistral::Model::iter()
|
||||
for model in mistral::Model::iter() {
|
||||
if !matches!(model, mistral::Model::Custom { .. }) {
|
||||
models.insert(model.id().to_string(), model);
|
||||
}
|
||||
}
|
||||
|
||||
// Override with available models from settings
|
||||
for model in &AllLanguageModelSettings::get_global(cx)
|
||||
.mistral
|
||||
.available_models
|
||||
{
|
||||
models.insert(
|
||||
model.name.clone(),
|
||||
mistral::Model::Custom {
|
||||
name: model.name.clone(),
|
||||
display_name: model.display_name.clone(),
|
||||
max_tokens: model.max_tokens,
|
||||
max_output_tokens: model.max_output_tokens,
|
||||
max_completion_tokens: model.max_completion_tokens,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
models
|
||||
.into_values()
|
||||
.map(|model| {
|
||||
Arc::new(MistralLanguageModel {
|
||||
id: LanguageModelId::from(model.id().to_string()),
|
||||
model,
|
||||
state: self.state.clone(),
|
||||
http_client: self.http_client.clone(),
|
||||
request_limiter: RateLimiter::new(4),
|
||||
}) as Arc<dyn LanguageModel>
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn is_authenticated(&self, cx: &App) -> bool {
|
||||
self.state.read(cx).is_authenticated()
|
||||
}
|
||||
|
||||
fn authenticate(&self, cx: &mut App) -> Task<Result<()>> {
|
||||
self.state.update(cx, |state, cx| state.authenticate(cx))
|
||||
}
|
||||
|
||||
fn configuration_view(&self, window: &mut Window, cx: &mut App) -> AnyView {
|
||||
cx.new(|cx| ConfigurationView::new(self.state.clone(), window, cx))
|
||||
.into()
|
||||
}
|
||||
|
||||
fn reset_credentials(&self, cx: &mut App) -> Task<Result<()>> {
|
||||
self.state.update(cx, |state, cx| state.reset_api_key(cx))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MistralLanguageModel {
|
||||
id: LanguageModelId,
|
||||
model: mistral::Model,
|
||||
state: gpui::Entity<State>,
|
||||
http_client: Arc<dyn HttpClient>,
|
||||
request_limiter: RateLimiter,
|
||||
}
|
||||
|
||||
impl MistralLanguageModel {
|
||||
fn stream_completion(
|
||||
&self,
|
||||
request: mistral::Request,
|
||||
cx: &AsyncApp,
|
||||
) -> BoxFuture<
|
||||
'static,
|
||||
Result<futures::stream::BoxStream<'static, Result<mistral::StreamResponse>>>,
|
||||
> {
|
||||
let http_client = self.http_client.clone();
|
||||
let Ok((api_key, api_url)) = cx.read_entity(&self.state, |state, cx| {
|
||||
let settings = &AllLanguageModelSettings::get_global(cx).mistral;
|
||||
(state.api_key.clone(), settings.api_url.clone())
|
||||
}) else {
|
||||
return futures::future::ready(Err(anyhow!("App state dropped"))).boxed();
|
||||
};
|
||||
|
||||
let future = self.request_limiter.stream(async move {
|
||||
let api_key = api_key.ok_or_else(|| anyhow!("Missing Mistral API Key"))?;
|
||||
let request =
|
||||
mistral::stream_completion(http_client.as_ref(), &api_url, &api_key, request);
|
||||
let response = request.await?;
|
||||
Ok(response)
|
||||
});
|
||||
|
||||
async move { Ok(future.await?.boxed()) }.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl LanguageModel for MistralLanguageModel {
|
||||
fn id(&self) -> LanguageModelId {
|
||||
self.id.clone()
|
||||
}
|
||||
|
||||
fn name(&self) -> LanguageModelName {
|
||||
LanguageModelName::from(self.model.display_name().to_string())
|
||||
}
|
||||
|
||||
fn provider_id(&self) -> LanguageModelProviderId {
|
||||
LanguageModelProviderId(PROVIDER_ID.into())
|
||||
}
|
||||
|
||||
fn provider_name(&self) -> LanguageModelProviderName {
|
||||
LanguageModelProviderName(PROVIDER_NAME.into())
|
||||
}
|
||||
|
||||
fn telemetry_id(&self) -> String {
|
||||
format!("mistral/{}", self.model.id())
|
||||
}
|
||||
|
||||
fn max_token_count(&self) -> usize {
|
||||
self.model.max_token_count()
|
||||
}
|
||||
|
||||
fn max_output_tokens(&self) -> Option<u32> {
|
||||
self.model.max_output_tokens()
|
||||
}
|
||||
|
||||
fn count_tokens(
|
||||
&self,
|
||||
request: LanguageModelRequest,
|
||||
cx: &App,
|
||||
) -> BoxFuture<'static, Result<usize>> {
|
||||
cx.background_executor()
|
||||
.spawn(async move {
|
||||
let messages = request
|
||||
.messages
|
||||
.into_iter()
|
||||
.map(|message| tiktoken_rs::ChatCompletionRequestMessage {
|
||||
role: match message.role {
|
||||
Role::User => "user".into(),
|
||||
Role::Assistant => "assistant".into(),
|
||||
Role::System => "system".into(),
|
||||
},
|
||||
content: Some(message.string_contents()),
|
||||
name: None,
|
||||
function_call: None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
tiktoken_rs::num_tokens_from_messages("gpt-4", &messages)
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn stream_completion(
|
||||
&self,
|
||||
request: LanguageModelRequest,
|
||||
cx: &AsyncApp,
|
||||
) -> BoxFuture<'static, Result<BoxStream<'static, Result<LanguageModelCompletionEvent>>>> {
|
||||
let request = request.into_mistral(self.model.id().to_string(), self.max_output_tokens());
|
||||
let stream = self.stream_completion(request, cx);
|
||||
|
||||
async move {
|
||||
let stream = stream.await?;
|
||||
Ok(stream
|
||||
.map(|result| {
|
||||
result.and_then(|response| {
|
||||
response
|
||||
.choices
|
||||
.first()
|
||||
.ok_or_else(|| anyhow!("Empty response"))
|
||||
.map(|choice| {
|
||||
choice
|
||||
.delta
|
||||
.content
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.map(LanguageModelCompletionEvent::Text)
|
||||
})
|
||||
})
|
||||
})
|
||||
.boxed())
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn use_any_tool(
|
||||
&self,
|
||||
request: LanguageModelRequest,
|
||||
tool_name: String,
|
||||
tool_description: String,
|
||||
schema: serde_json::Value,
|
||||
cx: &AsyncApp,
|
||||
) -> BoxFuture<'static, Result<futures::stream::BoxStream<'static, Result<String>>>> {
|
||||
let mut request = request.into_mistral(self.model.id().into(), self.max_output_tokens());
|
||||
request.tools = vec![mistral::ToolDefinition::Function {
|
||||
function: mistral::FunctionDefinition {
|
||||
name: tool_name.clone(),
|
||||
description: Some(tool_description),
|
||||
parameters: Some(schema),
|
||||
},
|
||||
}];
|
||||
|
||||
let response = self.stream_completion(request, cx);
|
||||
self.request_limiter
|
||||
.run(async move {
|
||||
let stream = response.await?;
|
||||
|
||||
let tool_args_stream = stream
|
||||
.filter_map(move |response| async move {
|
||||
match response {
|
||||
Ok(response) => {
|
||||
for choice in response.choices {
|
||||
if let Some(tool_calls) = choice.delta.tool_calls {
|
||||
for tool_call in tool_calls {
|
||||
if let Some(function) = tool_call.function {
|
||||
if let Some(args) = function.arguments {
|
||||
return Some(Ok(args));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
Err(e) => Some(Err(e)),
|
||||
}
|
||||
})
|
||||
.boxed();
|
||||
|
||||
Ok(tool_args_stream)
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
struct ConfigurationView {
|
||||
api_key_editor: Entity<Editor>,
|
||||
state: gpui::Entity<State>,
|
||||
load_credentials_task: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl ConfigurationView {
|
||||
fn new(state: gpui::Entity<State>, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let api_key_editor = cx.new(|cx| {
|
||||
let mut editor = Editor::single_line(window, cx);
|
||||
editor.set_placeholder_text("0aBCDEFGhIjKLmNOpqrSTUVwxyzabCDE1f2", cx);
|
||||
editor
|
||||
});
|
||||
|
||||
cx.observe(&state, |_, _, cx| {
|
||||
cx.notify();
|
||||
})
|
||||
.detach();
|
||||
|
||||
let load_credentials_task = Some(cx.spawn_in(window, {
|
||||
let state = state.clone();
|
||||
|this, mut cx| async move {
|
||||
if let Some(task) = state
|
||||
.update(&mut cx, |state, cx| state.authenticate(cx))
|
||||
.log_err()
|
||||
{
|
||||
// We don't log an error, because "not signed in" is also an error.
|
||||
let _ = task.await;
|
||||
}
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.load_credentials_task = None;
|
||||
cx.notify();
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
}));
|
||||
|
||||
Self {
|
||||
api_key_editor,
|
||||
state,
|
||||
load_credentials_task,
|
||||
}
|
||||
}
|
||||
|
||||
fn save_api_key(&mut self, _: &menu::Confirm, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let api_key = self.api_key_editor.read(cx).text(cx);
|
||||
if api_key.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let state = self.state.clone();
|
||||
cx.spawn_in(window, |_, mut cx| async move {
|
||||
state
|
||||
.update(&mut cx, |state, cx| state.set_api_key(api_key, cx))?
|
||||
.await
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn reset_api_key(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.api_key_editor
|
||||
.update(cx, |editor, cx| editor.set_text("", window, cx));
|
||||
|
||||
let state = self.state.clone();
|
||||
cx.spawn_in(window, |_, mut cx| async move {
|
||||
state
|
||||
.update(&mut cx, |state, cx| state.reset_api_key(cx))?
|
||||
.await
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn render_api_key_editor(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
let text_style = TextStyle {
|
||||
color: cx.theme().colors().text,
|
||||
font_family: settings.ui_font.family.clone(),
|
||||
font_features: settings.ui_font.features.clone(),
|
||||
font_fallbacks: settings.ui_font.fallbacks.clone(),
|
||||
font_size: rems(0.875).into(),
|
||||
font_weight: settings.ui_font.weight,
|
||||
font_style: FontStyle::Normal,
|
||||
line_height: relative(1.3),
|
||||
white_space: WhiteSpace::Normal,
|
||||
..Default::default()
|
||||
};
|
||||
EditorElement::new(
|
||||
&self.api_key_editor,
|
||||
EditorStyle {
|
||||
background: cx.theme().colors().editor_background,
|
||||
local_player: cx.theme().players().local(),
|
||||
text: text_style,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn should_render_editor(&self, cx: &mut Context<Self>) -> bool {
|
||||
!self.state.read(cx).is_authenticated()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ConfigurationView {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
const MISTRAL_CONSOLE_URL: &str = "https://console.mistral.ai/api-keys";
|
||||
const INSTRUCTIONS: [&str; 4] = [
|
||||
"To use Zed's assistant with Mistral, you need to add an API key. Follow these steps:",
|
||||
" - Create one by visiting:",
|
||||
" - Ensure your Mistral account has credits",
|
||||
" - Paste your API key below and hit enter to start using the assistant",
|
||||
];
|
||||
|
||||
let env_var_set = self.state.read(cx).api_key_from_env;
|
||||
|
||||
if self.load_credentials_task.is_some() {
|
||||
div().child(Label::new("Loading credentials...")).into_any()
|
||||
} else if self.should_render_editor(cx) {
|
||||
v_flex()
|
||||
.size_full()
|
||||
.on_action(cx.listener(Self::save_api_key))
|
||||
.child(Label::new(INSTRUCTIONS[0]))
|
||||
.child(h_flex().child(Label::new(INSTRUCTIONS[1])).child(
|
||||
Button::new("mistral_console", MISTRAL_CONSOLE_URL)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.icon(IconName::ArrowUpRight)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.on_click(move |_, _, cx| cx.open_url(MISTRAL_CONSOLE_URL))
|
||||
)
|
||||
)
|
||||
.children(
|
||||
(2..INSTRUCTIONS.len()).map(|n|
|
||||
Label::new(INSTRUCTIONS[n])).collect::<Vec<_>>())
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.my_2()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.rounded_md()
|
||||
.child(self.render_api_key_editor(cx)),
|
||||
)
|
||||
.child(
|
||||
Label::new(
|
||||
format!("You can also assign the {MISTRAL_API_KEY_VAR} environment variable and restart Zed."),
|
||||
)
|
||||
.size(LabelSize::Small),
|
||||
)
|
||||
.into_any()
|
||||
} else {
|
||||
h_flex()
|
||||
.size_full()
|
||||
.justify_between()
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(Icon::new(IconName::Check).color(Color::Success))
|
||||
.child(Label::new(if env_var_set {
|
||||
format!("API key set in {MISTRAL_API_KEY_VAR} environment variable.")
|
||||
} else {
|
||||
"API key configured.".to_string()
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
Button::new("reset-key", "Reset key")
|
||||
.icon(Some(IconName::Trash))
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_position(IconPosition::Start)
|
||||
.disabled(env_var_set)
|
||||
.when(env_var_set, |this| {
|
||||
this.tooltip(Tooltip::text(format!("To reset your API key, unset the {MISTRAL_API_KEY_VAR} environment variable.")))
|
||||
})
|
||||
.on_click(cx.listener(|this, _, window, cx| this.reset_api_key(window, cx))),
|
||||
)
|
||||
.into_any()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ use crate::provider::{
|
||||
deepseek::DeepSeekSettings,
|
||||
google::GoogleSettings,
|
||||
lmstudio::LmStudioSettings,
|
||||
mistral::MistralSettings,
|
||||
ollama::OllamaSettings,
|
||||
open_ai::OpenAiSettings,
|
||||
};
|
||||
@@ -63,6 +64,7 @@ pub struct AllLanguageModelSettings {
|
||||
pub copilot_chat: CopilotChatSettings,
|
||||
pub lmstudio: LmStudioSettings,
|
||||
pub deepseek: DeepSeekSettings,
|
||||
pub mistral: MistralSettings,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
@@ -76,6 +78,7 @@ pub struct AllLanguageModelSettingsContent {
|
||||
pub google: Option<GoogleSettingsContent>,
|
||||
pub deepseek: Option<DeepseekSettingsContent>,
|
||||
pub copilot_chat: Option<CopilotChatSettingsContent>,
|
||||
pub mistral: Option<MistralSettingsContent>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
@@ -171,6 +174,12 @@ pub struct DeepseekSettingsContent {
|
||||
pub available_models: Option<Vec<provider::deepseek::AvailableModel>>,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
pub struct MistralSettingsContent {
|
||||
pub api_url: Option<String>,
|
||||
pub available_models: Option<Vec<provider::mistral::AvailableModel>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
|
||||
#[serde(untagged)]
|
||||
pub enum OpenAiSettingsContent {
|
||||
@@ -356,6 +365,17 @@ impl settings::Settings for AllLanguageModelSettings {
|
||||
.as_ref()
|
||||
.and_then(|s| s.available_models.clone()),
|
||||
);
|
||||
|
||||
// Mistral
|
||||
let mistral = value.mistral.clone();
|
||||
merge(
|
||||
&mut settings.mistral.api_url,
|
||||
mistral.as_ref().and_then(|s| s.api_url.clone()),
|
||||
);
|
||||
merge(
|
||||
&mut settings.mistral.available_models,
|
||||
mistral.as_ref().and_then(|s| s.available_models.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(settings)
|
||||
|
||||
@@ -216,6 +216,7 @@ impl Render for KeyContextView {
|
||||
.key_binding(ui::KeyBinding::for_action(
|
||||
&zed_actions::OpenDefaultKeymap,
|
||||
window,
|
||||
cx
|
||||
))
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(workspace::SplitRight.boxed_clone(), cx);
|
||||
@@ -225,7 +226,7 @@ impl Render for KeyContextView {
|
||||
.child(
|
||||
Button::new("default", "Edit your keymap")
|
||||
.style(ButtonStyle::Filled)
|
||||
.key_binding(ui::KeyBinding::for_action(&zed_actions::OpenKeymap, window))
|
||||
.key_binding(ui::KeyBinding::for_action(&zed_actions::OpenKeymap, window, cx))
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(workspace::SplitRight.boxed_clone(), cx);
|
||||
window.dispatch_action(zed_actions::OpenKeymap.boxed_clone(), cx);
|
||||
|
||||
@@ -735,7 +735,8 @@ impl LspLogView {
|
||||
|
||||
* Binary: {BINARY:#?}
|
||||
|
||||
* Running in project: {PATH:?}
|
||||
* Registered workspace folders:
|
||||
{WORKSPACE_FOLDERS}
|
||||
|
||||
* Capabilities: {CAPABILITIES}
|
||||
|
||||
@@ -743,7 +744,15 @@ impl LspLogView {
|
||||
NAME = server.name(),
|
||||
ID = server.server_id(),
|
||||
BINARY = server.binary(),
|
||||
PATH = server.root_path(),
|
||||
WORKSPACE_FOLDERS = server
|
||||
.workspace_folders()
|
||||
.iter()
|
||||
.filter_map(|path| path
|
||||
.to_file_path()
|
||||
.ok()
|
||||
.map(|path| path.to_string_lossy().into_owned()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
CAPABILITIES = serde_json::to_string_pretty(&server.capabilities())
|
||||
.unwrap_or_else(|e| format!("Failed to serialize capabilities: {e}")),
|
||||
CONFIGURATION = serde_json::to_string_pretty(server.configuration())
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
name = "Shell Script"
|
||||
code_fence_block_name = "bash"
|
||||
grammar = "bash"
|
||||
path_suffixes = ["sh", "bash", "bashrc", "bash_profile", "bash_aliases", "bash_logout", "profile", "zsh", "zshrc", "zshenv", "zsh_profile", "zsh_aliases", "zsh_histfile", "zlogin", "zprofile", ".env", "PKGBUILD"]
|
||||
path_suffixes = ["sh", "bash", "bashrc", "bash_profile", "bash_aliases", "bash_logout", "bats", "profile", "zsh", "zshrc", "zshenv", "zsh_profile", "zsh_aliases", "zsh_histfile", "zlogin", "zprofile", ".env", "PKGBUILD"]
|
||||
line_comments = ["# "]
|
||||
first_line_pattern = '^#!.*\b(?:ash|bash|dash|sh|zsh)\b'
|
||||
first_line_pattern = '^#!.*\b(?:ash|bash|bats|dash|sh|zsh)\b'
|
||||
brackets = [
|
||||
{ start = "[", end = "]", close = true, newline = false },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
(comment) @annotation
|
||||
(type_declaration
|
||||
"type" @context
|
||||
(type_spec
|
||||
name: (_) @name)) @item
|
||||
[
|
||||
(type_spec
|
||||
name: (_) @name) @item
|
||||
(
|
||||
"("
|
||||
(type_spec
|
||||
name: (_) @name) @item
|
||||
")"
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
(function_declaration
|
||||
"func" @context
|
||||
@@ -32,8 +41,18 @@
|
||||
(source_file
|
||||
(var_declaration
|
||||
"var" @context
|
||||
(var_spec
|
||||
name: (identifier) @name) @item))
|
||||
[
|
||||
(var_spec
|
||||
name: (identifier) @name) @item
|
||||
(var_spec_list
|
||||
"("
|
||||
(var_spec
|
||||
name: (identifier) @name) @item
|
||||
")"
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
(method_elem
|
||||
name: (_) @name
|
||||
|
||||
@@ -74,6 +74,23 @@ impl LspAdapter for RustLspAdapter {
|
||||
Self::SERVER_NAME.clone()
|
||||
}
|
||||
|
||||
fn find_project_root(
|
||||
&self,
|
||||
path: &Path,
|
||||
ancestor_depth: usize,
|
||||
delegate: &Arc<dyn LspAdapterDelegate>,
|
||||
) -> Option<Arc<Path>> {
|
||||
let mut outermost_cargo_toml = None;
|
||||
for path in path.ancestors().take(ancestor_depth) {
|
||||
let p = path.join("Cargo.toml");
|
||||
if delegate.exists(&p, Some(false)) {
|
||||
outermost_cargo_toml = Some(Arc::from(path));
|
||||
}
|
||||
}
|
||||
|
||||
outermost_cargo_toml
|
||||
}
|
||||
|
||||
async fn check_if_user_installed(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "livekit_server"
|
||||
name = "livekit_api"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
description = "SDK for the LiveKit server API"
|
||||
@@ -10,7 +10,7 @@ license = "AGPL-3.0-or-later"
|
||||
workspace = true
|
||||
|
||||
[lib]
|
||||
path = "src/livekit_server.rs"
|
||||
path = "src/livekit_api.rs"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
@@ -1,4 +1,6 @@
|
||||
use crate::{proto, token};
|
||||
pub mod proto;
|
||||
pub mod token;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use prost::Message;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user