Compare commits
666 Commits
custom-too
...
remove-dap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aff5050d4e | ||
|
|
a203b1cc36 | ||
|
|
e1c7e1088b | ||
|
|
cbf9ef0851 | ||
|
|
16dba67b38 | ||
|
|
45cf5b5ab5 | ||
|
|
c07526f30b | ||
|
|
24e816be38 | ||
|
|
b67a382e57 | ||
|
|
06338963f3 | ||
|
|
95590967eb | ||
|
|
9786da2fe5 | ||
|
|
0dc90fd35e | ||
|
|
1e0a0fa9f9 | ||
|
|
f81463cc93 | ||
|
|
c9a9ab22f0 | ||
|
|
cf13a62bb5 | ||
|
|
fbf4eb9472 | ||
|
|
ad356d9c8e | ||
|
|
45db28a5ce | ||
|
|
a0c91d620a | ||
|
|
b1ca8c3e45 | ||
|
|
f8e248286e | ||
|
|
0233152bd1 | ||
|
|
294ce96b24 | ||
|
|
f7886adf9a | ||
|
|
bc5904e485 | ||
|
|
12c02a12ca | ||
|
|
36b430a1ae | ||
|
|
7fe8c626d3 | ||
|
|
43e2c4de06 | ||
|
|
6648d6299f | ||
|
|
d0f64d475d | ||
|
|
e285ae60c3 | ||
|
|
53336eedb7 | ||
|
|
3aab70c7bb | ||
|
|
cdb5af2906 | ||
|
|
936ac212e7 | ||
|
|
debcb1f26f | ||
|
|
90440d9652 | ||
|
|
be80dedd8c | ||
|
|
00c24ce289 | ||
|
|
c820f12e9c | ||
|
|
3833788cbc | ||
|
|
91e60d79bb | ||
|
|
ecfc0ef12d | ||
|
|
661e5b0335 | ||
|
|
041e1eef38 | ||
|
|
c8ba6d7c57 | ||
|
|
9d5525e0fb | ||
|
|
9ac18e9404 | ||
|
|
90deb4a82e | ||
|
|
8b45634d39 | ||
|
|
e216805e66 | ||
|
|
062e64d227 | ||
|
|
39d4d624fb | ||
|
|
dad39abeeb | ||
|
|
05ca096a5b | ||
|
|
2fc7c17497 | ||
|
|
af77b2f99f | ||
|
|
16eff80a7b | ||
|
|
64bc112fe5 | ||
|
|
9ef8aceb81 | ||
|
|
2973b46c78 | ||
|
|
b6182d0781 | ||
|
|
dac28730e5 | ||
|
|
9c3e85a6ff | ||
|
|
e21ea19fc6 | ||
|
|
cee4e25d51 | ||
|
|
33e39281a6 | ||
|
|
da66f75410 | ||
|
|
b7f0a1f5c8 | ||
|
|
6ec4adffe7 | ||
|
|
180ce5e9ba | ||
|
|
4fcb10dd26 | ||
|
|
1be2836f60 | ||
|
|
c76144e918 | ||
|
|
aa268d1379 | ||
|
|
3cf96588e2 | ||
|
|
27b60436b8 | ||
|
|
28874b60cf | ||
|
|
dcde289f94 | ||
|
|
52350245e6 | ||
|
|
a56e3eafdf | ||
|
|
ad98bf444d | ||
|
|
080d0c46ad | ||
|
|
dfeddaae8a | ||
|
|
5cd93ca158 | ||
|
|
d60089888f | ||
|
|
4c930652af | ||
|
|
44e9444c8c | ||
|
|
69548f5f34 | ||
|
|
c45b6e9271 | ||
|
|
26f14fd036 | ||
|
|
945e3226d8 | ||
|
|
3bf5833135 | ||
|
|
47b3f55a17 | ||
|
|
c994075327 | ||
|
|
b6b7ad38b5 | ||
|
|
e81a7e1e06 | ||
|
|
889949ca76 | ||
|
|
ef3a6deb05 | ||
|
|
197166a8c1 | ||
|
|
dfe978b06a | ||
|
|
a2e0b6778b | ||
|
|
25db814d0c | ||
|
|
78865820d8 | ||
|
|
1fb0c5b84e | ||
|
|
ec547b8ca3 | ||
|
|
56abc60a34 | ||
|
|
a89e29554f | ||
|
|
8ceb115f3c | ||
|
|
953843acdd | ||
|
|
5a52c7e21f | ||
|
|
9bca023b1a | ||
|
|
647f411b10 | ||
|
|
e1392c9717 | ||
|
|
7b6d20b9ff | ||
|
|
675fb2f54b | ||
|
|
1a5feff9ed | ||
|
|
4de9921fa8 | ||
|
|
5ecfef0aa0 | ||
|
|
868f55c074 | ||
|
|
272721ae30 | ||
|
|
f34fc7fbe8 | ||
|
|
a193efd65a | ||
|
|
568f127f43 | ||
|
|
bc49c18481 | ||
|
|
d03e4149ea | ||
|
|
86946506bf | ||
|
|
41b702807d | ||
|
|
a9d7858f30 | ||
|
|
06c11f97bb | ||
|
|
8ecd5479ac | ||
|
|
a7e26bbfb5 | ||
|
|
f9f28107f5 | ||
|
|
2736b2f477 | ||
|
|
5aa816e85b | ||
|
|
4baa7f7742 | ||
|
|
4e13a00c44 | ||
|
|
943609f1ac | ||
|
|
887e2a65e1 | ||
|
|
c91f51dd68 | ||
|
|
797f5bd967 | ||
|
|
14a2f7526b | ||
|
|
918869fcfe | ||
|
|
46b72f6e3b | ||
|
|
73627a3843 | ||
|
|
fa17737332 | ||
|
|
01648b9370 | ||
|
|
dd4a1f7d30 | ||
|
|
8911c96399 | ||
|
|
404f77357d | ||
|
|
d99653fd15 | ||
|
|
72f13890f0 | ||
|
|
2551a0fe13 | ||
|
|
501073393c | ||
|
|
78d342d582 | ||
|
|
f2722db366 | ||
|
|
f0cd2bfa61 | ||
|
|
020623a19d | ||
|
|
e551923477 | ||
|
|
cbbf2daa2f | ||
|
|
9497987438 | ||
|
|
331aafde23 | ||
|
|
f9c88fb50f | ||
|
|
1698965317 | ||
|
|
1c59d2203b | ||
|
|
42d1b484bd | ||
|
|
7223bf93ba | ||
|
|
3afda611b4 | ||
|
|
acb3ee23a8 | ||
|
|
dd5083ad62 | ||
|
|
0b68944397 | ||
|
|
f0947c1197 | ||
|
|
9cd7e072fe | ||
|
|
f682077ffd | ||
|
|
b3aa18d70c | ||
|
|
030ee04e54 | ||
|
|
e2206b876b | ||
|
|
1f0304f002 | ||
|
|
b5b877bd26 | ||
|
|
bfdf12c51c | ||
|
|
e0891a1df7 | ||
|
|
c1e15c0907 | ||
|
|
f4669e8965 | ||
|
|
43defed0a4 | ||
|
|
ea18dfbe94 | ||
|
|
7ced61d798 | ||
|
|
fba00c728e | ||
|
|
ca970dd77d | ||
|
|
569f500b52 | ||
|
|
b911fb1c9a | ||
|
|
b8c89d3d8a | ||
|
|
098bc759a9 | ||
|
|
ccacce9ccb | ||
|
|
1929dec4a0 | ||
|
|
ed7443db6e | ||
|
|
3e9139eeb1 | ||
|
|
ad1e51f64a | ||
|
|
a91faaceec | ||
|
|
cea5cc7cd0 | ||
|
|
f6d26afb13 | ||
|
|
f8fe1652a7 | ||
|
|
39e70354c1 | ||
|
|
4f8c19a93a | ||
|
|
1b1d37484b | ||
|
|
5dbadab1ac | ||
|
|
d7fa7c208d | ||
|
|
6aba39874c | ||
|
|
5fe2da3e72 | ||
|
|
ab4973fbdb | ||
|
|
e3cb3d143e | ||
|
|
6ed42285d6 | ||
|
|
0b97ffad13 | ||
|
|
7f4f7b056e | ||
|
|
473ebbb6c3 | ||
|
|
3474750588 | ||
|
|
28c6012ff8 | ||
|
|
9a802b9133 | ||
|
|
d7b5132bd9 | ||
|
|
65789d3925 | ||
|
|
bea29464f9 | ||
|
|
980f9c7353 | ||
|
|
aefef9c58c | ||
|
|
29a9eaf5fc | ||
|
|
490d42599b | ||
|
|
04cd04eb44 | ||
|
|
22e52c306a | ||
|
|
6a4a285ee6 | ||
|
|
a50f3c36b0 | ||
|
|
1a0ecf0c16 | ||
|
|
2b8ae367c7 | ||
|
|
61e8d0c39b | ||
|
|
386031e6dd | ||
|
|
b8b65f7a8f | ||
|
|
4068960686 | ||
|
|
df71b972e1 | ||
|
|
6bc5679c86 | ||
|
|
35a52a7f90 | ||
|
|
5971d37942 | ||
|
|
046ff02062 | ||
|
|
2c45c57f7b | ||
|
|
8e738ba4d5 | ||
|
|
008bd534af | ||
|
|
8c72b99031 | ||
|
|
7e0150790a | ||
|
|
a3220dc31d | ||
|
|
3aaee14ecc | ||
|
|
0d84881641 | ||
|
|
b6dc3ca86f | ||
|
|
99bfc342ab | ||
|
|
3a77d7a655 | ||
|
|
2c1f348c49 | ||
|
|
d8f8140965 | ||
|
|
ae0d08f36c | ||
|
|
23ccf08da1 | ||
|
|
977fd87a51 | ||
|
|
80f775e186 | ||
|
|
6f0e223dc7 | ||
|
|
ca80d0c3bd | ||
|
|
ce30deac63 | ||
|
|
31e3e48052 | ||
|
|
81ca004ee6 | ||
|
|
15dd1ee22e | ||
|
|
c54454fa42 | ||
|
|
964a6e8585 | ||
|
|
aa5d51d776 | ||
|
|
ba25aa26c9 | ||
|
|
b69d031e15 | ||
|
|
68ee3c747a | ||
|
|
7cec577daa | ||
|
|
0976e85eb0 | ||
|
|
c19c86085b | ||
|
|
055ffc17cd | ||
|
|
b728779a9a | ||
|
|
fb5bee3ba8 | ||
|
|
ffaaadf2b9 | ||
|
|
9781292cba | ||
|
|
9e37b4708f | ||
|
|
bae6edba88 | ||
|
|
9772573816 | ||
|
|
56f77c3192 | ||
|
|
56df4fbe6e | ||
|
|
45c4aef0da | ||
|
|
1b2871aac2 | ||
|
|
65cd774baa | ||
|
|
591f6cc9a2 | ||
|
|
bb89c1d913 | ||
|
|
d1ddbfc586 | ||
|
|
d226de3230 | ||
|
|
5efdaf3ca7 | ||
|
|
cd2b4a8714 | ||
|
|
15535d3cec | ||
|
|
747ef3e7ec | ||
|
|
aa9875277a | ||
|
|
0c647ae071 | ||
|
|
f6556c5bb6 | ||
|
|
f7eb5213a5 | ||
|
|
d279afa41c | ||
|
|
ddaf1508d3 | ||
|
|
96871b493f | ||
|
|
a45aa3d014 | ||
|
|
57668dbaeb | ||
|
|
115f2eb2e2 | ||
|
|
290c76daef | ||
|
|
e2d449a11f | ||
|
|
a95b16aa67 | ||
|
|
932f4ed10a | ||
|
|
61daad2377 | ||
|
|
8baa2805d0 | ||
|
|
ffc058209d | ||
|
|
b426ff6074 | ||
|
|
6f973bdda4 | ||
|
|
43ea3b47a4 | ||
|
|
30a4c84a48 | ||
|
|
211fd50776 | ||
|
|
fc78c40385 | ||
|
|
6735cfad67 | ||
|
|
2e028a7038 | ||
|
|
afe228fd77 | ||
|
|
fdea7d9de9 | ||
|
|
1c1e34b3d2 | ||
|
|
3a6f2adcc6 | ||
|
|
13afc3741f | ||
|
|
c65ed1c738 | ||
|
|
f5dc1175b8 | ||
|
|
5758f664bc | ||
|
|
b46b8aa76a | ||
|
|
222cd4ba43 | ||
|
|
5bb7f2408a | ||
|
|
b1d24a0524 | ||
|
|
177ae28ab2 | ||
|
|
554a402cec | ||
|
|
7e2c1386fc | ||
|
|
8a4f677119 | ||
|
|
a728f9e751 | ||
|
|
171c74223c | ||
|
|
5f1de1ab65 | ||
|
|
91926cdcfe | ||
|
|
08935b29ef | ||
|
|
eedd865ae8 | ||
|
|
00b6fdc098 | ||
|
|
187d909736 | ||
|
|
ac0ba07c61 | ||
|
|
984cb686a8 | ||
|
|
3b545a79ba | ||
|
|
f76b7c9337 | ||
|
|
8c0a7b1024 | ||
|
|
c2ed56af0b | ||
|
|
f9b045bd23 | ||
|
|
3c301c3ea4 | ||
|
|
93af1bfae7 | ||
|
|
6b4ebac822 | ||
|
|
55c65700ad | ||
|
|
842bf0287d | ||
|
|
1914cef0aa | ||
|
|
171ddfb554 | ||
|
|
bfddc634be | ||
|
|
29918d96a2 | ||
|
|
3b3ac85199 | ||
|
|
9bc08f9f84 | ||
|
|
ce77773796 | ||
|
|
9016a03e90 | ||
|
|
a3dff431c5 | ||
|
|
231b5a910a | ||
|
|
7dec58ce89 | ||
|
|
8b96ac8138 | ||
|
|
4ddb65bdaa | ||
|
|
c26a8f1537 | ||
|
|
f1f1426635 | ||
|
|
278699f2f7 | ||
|
|
9612b60ccb | ||
|
|
c88316655c | ||
|
|
c3a778724f | ||
|
|
c1ab059d54 | ||
|
|
142a6dea17 | ||
|
|
e7f7fb759d | ||
|
|
621d1812d1 | ||
|
|
8cdb1fb55a | ||
|
|
716a81756f | ||
|
|
56943e2c78 | ||
|
|
4694de8e8a | ||
|
|
3985963259 | ||
|
|
559173e550 | ||
|
|
9b82278bb1 | ||
|
|
4405ae2d19 | ||
|
|
571d99cecf | ||
|
|
ed6da4a7f6 | ||
|
|
8a835bcf88 | ||
|
|
3fac36bd77 | ||
|
|
7a6f9d9559 | ||
|
|
ab6f3341c3 | ||
|
|
a4ce44629c | ||
|
|
18fb45f526 | ||
|
|
3184ba1df0 | ||
|
|
e6049f9830 | ||
|
|
0f5e5ea3b4 | ||
|
|
5a0c7d2885 | ||
|
|
499024297d | ||
|
|
3683920dab | ||
|
|
5d07ab0d03 | ||
|
|
09c195e78e | ||
|
|
165e058dce | ||
|
|
0e6042e12f | ||
|
|
1e99694f29 | ||
|
|
dc5d0f4148 | ||
|
|
b2927a07e4 | ||
|
|
b00d63b6c4 | ||
|
|
edf4e53571 | ||
|
|
ac2aa795cd | ||
|
|
b009832229 | ||
|
|
7b7a4757cd | ||
|
|
83cc452465 | ||
|
|
4cf735bd93 | ||
|
|
fc4078f8e8 | ||
|
|
243bd4b225 | ||
|
|
3ac4d1eaac | ||
|
|
921d0c54a3 | ||
|
|
008b6b591b | ||
|
|
2b504b3248 | ||
|
|
045f927b4c | ||
|
|
199b6657c6 | ||
|
|
31b27e1e85 | ||
|
|
5a301fc83a | ||
|
|
618d81a3de | ||
|
|
9bcd03b755 | ||
|
|
f3e7129479 | ||
|
|
149116e76f | ||
|
|
bbb449c1b7 | ||
|
|
651c31c338 | ||
|
|
3c98e8986f | ||
|
|
7885da1a2c | ||
|
|
2843a36853 | ||
|
|
5c45e459bd | ||
|
|
fb169af400 | ||
|
|
db8b8beb70 | ||
|
|
1ac97d2e87 | ||
|
|
11b2bc1ffc | ||
|
|
da1fdd25cd | ||
|
|
e9f0e936ea | ||
|
|
3a3f4990ba | ||
|
|
bb40689472 | ||
|
|
9643e71947 | ||
|
|
9ea23b0a62 | ||
|
|
b561c68d28 | ||
|
|
26e9843a2a | ||
|
|
5678469f9d | ||
|
|
fe58a702a0 | ||
|
|
30b59a6c92 | ||
|
|
0f1738c8cc | ||
|
|
d3fe698c23 | ||
|
|
cb52082821 | ||
|
|
a4db59cabb | ||
|
|
7d243ac274 | ||
|
|
5a08fc2033 | ||
|
|
111a0dc539 | ||
|
|
1ad8ed77e4 | ||
|
|
c92ecc690f | ||
|
|
a4cc28f480 | ||
|
|
f4af5afe62 | ||
|
|
49dd57d1f9 | ||
|
|
96bdeca2ac | ||
|
|
ef63ccff66 | ||
|
|
4181c39224 | ||
|
|
f3cb4a467b | ||
|
|
5f4affdefe | ||
|
|
b1d830cb09 | ||
|
|
e24e5f7e89 | ||
|
|
68158d3fc5 | ||
|
|
0247fd6087 | ||
|
|
d4904f97bb | ||
|
|
8b63c1ab6f | ||
|
|
9dfd2f5bdd | ||
|
|
ca844637f7 | ||
|
|
42aefb4034 | ||
|
|
e974ddedce | ||
|
|
a82d759940 | ||
|
|
a0123e8557 | ||
|
|
7ff1a08356 | ||
|
|
c99865b853 | ||
|
|
fc4d46ec22 | ||
|
|
1c98c1c302 | ||
|
|
aa257ece86 | ||
|
|
b9c1e511a9 | ||
|
|
2ab7f834b2 | ||
|
|
26a5770e08 | ||
|
|
d6dd59c83f | ||
|
|
655b23c635 | ||
|
|
620e65411b | ||
|
|
d222fbe84c | ||
|
|
74931bd472 | ||
|
|
4c5deb0b4e | ||
|
|
a545400534 | ||
|
|
12c853e3f0 | ||
|
|
4bb8ec96fd | ||
|
|
08dbf365bb | ||
|
|
c39c0a55f5 | ||
|
|
4373e479f7 | ||
|
|
7f8c28877f | ||
|
|
1ff23477de | ||
|
|
d28950c633 | ||
|
|
6ff5e00740 | ||
|
|
b70acdfa4a | ||
|
|
403ae10087 | ||
|
|
9a8a54109e | ||
|
|
f0a5775204 | ||
|
|
916150a8e0 | ||
|
|
61533d737c | ||
|
|
11c740b47a | ||
|
|
9c2b909df5 | ||
|
|
8b05b88ada | ||
|
|
0975ca844c | ||
|
|
a136b7279a | ||
|
|
7f1bd3b1d9 | ||
|
|
c7f7d18681 | ||
|
|
96d3f13937 | ||
|
|
1a421db92d | ||
|
|
9c60884771 | ||
|
|
ee3323d12a | ||
|
|
b88fd3e0c5 | ||
|
|
2e10853b34 | ||
|
|
780bfafedf | ||
|
|
0b8c4ded9e | ||
|
|
15d5186399 | ||
|
|
9bc1d4a8ae | ||
|
|
7c9771b8d7 | ||
|
|
d08e28f4e0 | ||
|
|
ef67321ff2 | ||
|
|
4c777ad140 | ||
|
|
923ae5473a | ||
|
|
a48166e5a0 | ||
|
|
ef098c028b | ||
|
|
7ce1b8dc76 | ||
|
|
e350417a33 | ||
|
|
ea9e0755df | ||
|
|
6aced1b3aa | ||
|
|
99e01fc608 | ||
|
|
fe899c9164 | ||
|
|
f8b9937e51 | ||
|
|
dc5928374e | ||
|
|
0deb3cc606 | ||
|
|
ba4a70d7ae | ||
|
|
65a790e4ca | ||
|
|
18cb54280a | ||
|
|
b6e677eb06 | ||
|
|
ffa0609f8d | ||
|
|
77a314350f | ||
|
|
8d7ec33183 | ||
|
|
73ef771875 | ||
|
|
3e1aa65b20 | ||
|
|
92b93850bb | ||
|
|
737b03c928 | ||
|
|
1b42dd5865 | ||
|
|
c9074b1c25 | ||
|
|
00379280f3 | ||
|
|
4e2d0351cc | ||
|
|
a583efd9b9 | ||
|
|
6237c29a42 | ||
|
|
9ea9b41e73 | ||
|
|
8d99f9b7d2 | ||
|
|
014ffbce2e | ||
|
|
68dd3c90c2 | ||
|
|
4a6f6151f0 | ||
|
|
f108d4c705 | ||
|
|
5ab95f1e1a | ||
|
|
49da08ffa4 | ||
|
|
f287c897a4 | ||
|
|
d15ff2d06f | ||
|
|
648daa3237 | ||
|
|
33e127de09 | ||
|
|
5a9b279039 | ||
|
|
cce58570dc | ||
|
|
361bbec3a0 | ||
|
|
a87409813c | ||
|
|
da84aa1ac2 | ||
|
|
817760688a | ||
|
|
13e56010c1 | ||
|
|
b827a35e44 | ||
|
|
9006e8fdff | ||
|
|
ce8ec033f4 | ||
|
|
9678cc9bc3 | ||
|
|
e87c4ddadc | ||
|
|
3f8581a2fb | ||
|
|
00c5b83384 | ||
|
|
4aedc1cd0b | ||
|
|
d238675c1a | ||
|
|
dcf6f6ca30 | ||
|
|
f4606bd951 | ||
|
|
12bef0830a | ||
|
|
953a2b376c | ||
|
|
ac3b9f7a4c | ||
|
|
ef5990d427 | ||
|
|
23a81d5d70 | ||
|
|
515122c54d | ||
|
|
f4eacca987 | ||
|
|
003fb7c81e | ||
|
|
7d2f63ebbd | ||
|
|
93e0bbb833 | ||
|
|
8c5f6a0be7 | ||
|
|
d6cafb8315 | ||
|
|
a24b76b30b | ||
|
|
11d74ea4ec | ||
|
|
93f4775cf6 | ||
|
|
a93913b9a3 | ||
|
|
08afbc6b58 | ||
|
|
b869465f00 | ||
|
|
2debea8115 | ||
|
|
cae295ff65 | ||
|
|
c51206e980 | ||
|
|
1baa5aea94 | ||
|
|
3e022a5565 | ||
|
|
3dd769be94 | ||
|
|
7936a4bee3 | ||
|
|
09aabe481c | ||
|
|
2ea1e4fa85 | ||
|
|
8699dad0e3 | ||
|
|
47a5f0c620 | ||
|
|
854ff68bac | ||
|
|
01d384e676 | ||
|
|
ddd893a795 | ||
|
|
3d7cd5dac7 | ||
|
|
a6fdfb5191 | ||
|
|
73a68d560f | ||
|
|
b4eeb25f55 | ||
|
|
fc991ab273 | ||
|
|
ab58d14559 | ||
|
|
3a0b311378 | ||
|
|
b81065fe63 | ||
|
|
a67f28dba2 | ||
|
|
99b2472e83 | ||
|
|
be45d5aa73 | ||
|
|
0508df9e7b | ||
|
|
153efab377 | ||
|
|
8015fb70e3 | ||
|
|
79d23aa4fe | ||
|
|
d5dae425fc | ||
|
|
d9e09c4a66 | ||
|
|
331625e876 | ||
|
|
61949fb348 | ||
|
|
c7f4e09496 | ||
|
|
5442e116ce | ||
|
|
11a4fc8b02 | ||
|
|
d303ebd46e | ||
|
|
e1de8dc50e | ||
|
|
5fe110c1dd | ||
|
|
89b203d03a | ||
|
|
0f4f8abbaa | ||
|
|
0d97e9e579 | ||
|
|
14b913fb4b | ||
|
|
9f1cd2bdb5 | ||
|
|
547c40e332 | ||
|
|
9cff6d5aa5 | ||
|
|
7e438bc1f3 | ||
|
|
944a52ce91 | ||
|
|
95a814ed41 | ||
|
|
6b9295b6c4 | ||
|
|
1128fce61a | ||
|
|
7c355fdb0f | ||
|
|
0e2a0b9edc | ||
|
|
c130f9c2f2 | ||
|
|
08300c6e90 | ||
|
|
7b71119094 | ||
|
|
c18db76862 | ||
|
|
c0dd152509 | ||
|
|
f402a4e5ce |
@@ -14,10 +14,10 @@ linker = "clang"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=mold"]
|
||||
|
||||
[target.aarch64-apple-darwin]
|
||||
rustflags = ["-C", "link-args=-all_load"]
|
||||
rustflags = ["-C", "link-args=-Objc -all_load"]
|
||||
|
||||
[target.x86_64-apple-darwin]
|
||||
rustflags = ["-C", "link-args=-all_load"]
|
||||
rustflags = ["-C", "link-args=-Objc -all_load"]
|
||||
|
||||
[target.'cfg(target_os = "windows")']
|
||||
rustflags = [
|
||||
@@ -26,6 +26,3 @@ rustflags = [
|
||||
"-C",
|
||||
"target-feature=+crt-static", # This fixes the linking issue when compiling livekit on Windows
|
||||
]
|
||||
|
||||
[env]
|
||||
MACOSX_DEPLOYMENT_TARGET = "10.15.7"
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# This file contains settings for `cargo hakari`.
|
||||
# See https://docs.rs/cargo-hakari/latest/cargo_hakari/config for a full list of options.
|
||||
|
||||
hakari-package = "workspace-hack"
|
||||
|
||||
resolver = "2"
|
||||
dep-format-version = "4"
|
||||
workspace-hack-line-style = "workspace-dotted"
|
||||
|
||||
# this should be the same list as "targets" in ../rust-toolchain.toml
|
||||
platforms = [
|
||||
"x86_64-apple-darwin",
|
||||
"aarch64-apple-darwin",
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
"x86_64-pc-windows-msvc",
|
||||
"x86_64-unknown-linux-musl", # remote server
|
||||
]
|
||||
|
||||
[traversal-excludes]
|
||||
workspace-members = [
|
||||
"remote_server",
|
||||
]
|
||||
third-party = [
|
||||
{ name = "reqwest", version = "0.11.27" },
|
||||
]
|
||||
|
||||
[final-excludes]
|
||||
workspace-members = [
|
||||
"zed_extension_api",
|
||||
|
||||
# exclude all extensions
|
||||
"zed_emmet",
|
||||
"zed_glsl",
|
||||
"zed_html",
|
||||
"perplexity",
|
||||
"zed_proto",
|
||||
"zed_ruff",
|
||||
"slash_commands_example",
|
||||
"zed_snippets",
|
||||
"zed_test_extension",
|
||||
"zed_toml",
|
||||
]
|
||||
@@ -19,10 +19,6 @@
|
||||
# https://github.com/zed-industries/zed/pull/2394
|
||||
eca93c124a488b4e538946cd2d313bd571aa2b86
|
||||
|
||||
# 2024-02-15 Format YAML files
|
||||
# https://github.com/zed-industries/zed/pull/7887
|
||||
a161a7d0c95ca7505bf9218bfae640ee5444c88b
|
||||
|
||||
# 2024-02-25 Format JSON files in assets/
|
||||
# https://github.com/zed-industries/zed/pull/8405
|
||||
ffdda588b41f7d9d270ffe76cab116f828ad545e
|
||||
|
||||
36
.github/ISSUE_TEMPLATE/01_bug_agent.yml
vendored
@@ -1,36 +0,0 @@
|
||||
name: Bug Report (Agent Panel)
|
||||
description: Zed Agent Panel Bugs
|
||||
type: "Bug"
|
||||
labels: ["agent", "ai"]
|
||||
title: "Agent Panel: <a short description of the Agent Panel bug>"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install. -->
|
||||
<!-- Please include the LLM provider and model name you are using -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
Expected Behavior:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: 'Open Zed, and in the command palette select "zed: Copy System Specs Into Clipboard"'
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,36 +0,0 @@
|
||||
name: Bug Report (Edit Predictions)
|
||||
description: Zed Edit Predictions bugs
|
||||
type: "Bug"
|
||||
labels: ["ai", "inline completion", "zeta"]
|
||||
title: "Edit Predictions: <a short description of the Edit Prediction bug>"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install. -->
|
||||
<!-- Please include the LLM provider and model name you are using -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
Expected Behavior:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: 'Open Zed, and in the command palette select "zed: Copy System Specs Into Clipboard"'
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
56
.github/ISSUE_TEMPLATE/10_bug_report.yml
vendored
@@ -1,56 +0,0 @@
|
||||
name: Bug Report (Other)
|
||||
description: |
|
||||
Something else is broken in Zed (exclude crashing).
|
||||
type: "Bug"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Provide a one sentence summary and detailed reproduction steps
|
||||
value: |
|
||||
<!-- Begin your issue with a one sentence summary -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install.
|
||||
- Any code must be sufficient to reproduce (include context!)
|
||||
- Code must as text, not just as a screenshot.
|
||||
- Issues with insufficient detail may be summarily closed.
|
||||
-->
|
||||
|
||||
Steps to reproduce:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
Expected Behavior:
|
||||
Actual Behavior:
|
||||
|
||||
<!-- Before Submitting, did you:
|
||||
1. Include settings.json, keymap.json, .editorconfig if relevant?
|
||||
2. Check your Zed.log for relevant errors? (please include!)
|
||||
3. Click Preview to ensure everything looks right?
|
||||
4. Hide videos, large images and logs in ``` inside collapsible blocks:
|
||||
|
||||
<details><summary>click to expand</summary>
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
</details>
|
||||
-->
|
||||
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Zed Version and System Specs
|
||||
description: |
|
||||
Open Zed, from the command palette select "zed: Copy System Specs Into Clipboard"
|
||||
placeholder: |
|
||||
Output of "zed: Copy System Specs Into Clipboard"
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,8 +1,7 @@
|
||||
name: Bug Report (Git)
|
||||
description: Zed Git-Related Bugs
|
||||
name: Bug Report
|
||||
description: |
|
||||
Something is broken in Zed (exclude crashing).
|
||||
type: "Bug"
|
||||
labels: ["git"]
|
||||
title: "Git: <a short description of the Git bug>"
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
@@ -10,20 +9,20 @@ body:
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
|
||||
### Description
|
||||
<!-- Describe with sufficient detail to reproduce from a clean Zed install. -->
|
||||
<!-- Include all steps necessary to reproduce from a clean Zed installation. Be verbose -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
|
||||
Expected Behavior:
|
||||
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
@@ -5,12 +5,10 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: Summarize the issue with detailed reproduction steps
|
||||
description: Describe the bug with a one line summary, and provide detailed reproduction steps
|
||||
value: |
|
||||
<!-- Begin your issue with a one sentence summary -->
|
||||
SUMMARY_SENTENCE_HERE
|
||||
<!-- Please insert a one line summary of the issue below -->
|
||||
|
||||
### Description
|
||||
<!-- Include all steps necessary to reproduce from a clean Zed installation. Be verbose -->
|
||||
Steps to trigger the problem:
|
||||
1.
|
||||
@@ -18,6 +16,7 @@ body:
|
||||
3.
|
||||
|
||||
Actual Behavior:
|
||||
|
||||
Expected Behavior:
|
||||
|
||||
validations:
|
||||
@@ -41,11 +40,10 @@ body:
|
||||
value: |
|
||||
<details><summary>Zed.log</summary>
|
||||
|
||||
<!-- Paste your log inside the code block. -->
|
||||
```log
|
||||
|
||||
<!-- Click below this line and paste or drag-and-drop your log-->
|
||||
```
|
||||
|
||||
</details>
|
||||
```
|
||||
<!-- Click above this line and paste or drag-and-drop your log--></details>
|
||||
validations:
|
||||
required: false
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -4,6 +4,9 @@ contact_links:
|
||||
- name: Feature Request
|
||||
url: https://github.com/zed-industries/zed/discussions/new/choose
|
||||
about: To request a feature, open a new Discussion in one of the appropriate Discussion categories
|
||||
- name: "Zed Discord"
|
||||
- name: Zed Discussion Forum
|
||||
url: https://github.com/zed-industries/zed/discussions
|
||||
about: A community discussion forum
|
||||
- name: "Zed Discord: #Support Channel"
|
||||
url: https://zed.dev/community-links
|
||||
about: Real-time discussion and user support
|
||||
|
||||
2
.github/actions/run_tests/action.yml
vendored
@@ -10,7 +10,7 @@ runs:
|
||||
cargo install cargo-nextest --locked
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
|
||||
4
.github/actions/run_tests_windows/action.yml
vendored
@@ -16,11 +16,11 @@ runs:
|
||||
run: cargo install cargo-nextest --locked
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Run tests
|
||||
shell: pwsh
|
||||
working-directory: ${{ inputs.working-directory }}
|
||||
run: cargo nextest run --workspace --no-fail-fast --config='profile.dev.debug="limited"'
|
||||
run: cargo nextest run --workspace --no-fail-fast
|
||||
|
||||
354
.github/workflows/ci.yml
vendored
@@ -23,53 +23,9 @@ env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
jobs:
|
||||
job_spec:
|
||||
name: Decide which jobs to run
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
outputs:
|
||||
run_tests: ${{ steps.filter.outputs.run_tests }}
|
||||
run_license: ${{ steps.filter.outputs.run_license }}
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
# 350 is arbitrary; ~10days of history on main (5secs); full history is ~25secs
|
||||
fetch-depth: ${{ github.ref == 'refs/heads/main' && 2 || 350 }}
|
||||
- name: Fetch git history and generate output filters
|
||||
id: filter
|
||||
run: |
|
||||
if [ -z "$GITHUB_BASE_REF" ]; then
|
||||
echo "Not in a PR context (i.e., push to main/stable/preview)"
|
||||
COMPARE_REV=$(git rev-parse HEAD~1)
|
||||
else
|
||||
echo "In a PR context comparing to pull_request.base.ref"
|
||||
git fetch origin "$GITHUB_BASE_REF" --depth=350
|
||||
COMPARE_REV=$(git merge-base "origin/${GITHUB_BASE_REF}" HEAD)
|
||||
fi
|
||||
# Specify anything which should skip full CI in this regex:
|
||||
# - docs/
|
||||
# - .github/ISSUE_TEMPLATE/
|
||||
# - .github/workflows/ (except .github/workflows/ci.yml)
|
||||
SKIP_REGEX='^(docs/|\.github/(ISSUE_TEMPLATE|workflows/(?!ci)))'
|
||||
if [[ $(git diff --name-only $COMPARE_REV ${{ github.sha }} | grep -vP "$SKIP_REGEX") ]]; then
|
||||
echo "run_tests=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "run_tests=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
if [[ $(git diff --name-only $COMPARE_REV ${{ github.sha }} | grep '^Cargo.lock') ]]; then
|
||||
echo "run_license=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "run_license=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
migration_checks:
|
||||
name: Check Postgres and Protobuf migrations, mergability
|
||||
needs: [job_spec]
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
timeout-minutes: 60
|
||||
runs-on:
|
||||
- self-hosted
|
||||
@@ -110,43 +66,9 @@ jobs:
|
||||
input: "crates/proto/proto/"
|
||||
against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=${BUF_BASE_BRANCH},subdir=crates/proto/proto/"
|
||||
|
||||
workspace_hack:
|
||||
timeout-minutes: 60
|
||||
name: Check workspace-hack crate
|
||||
needs: [job_spec]
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
runs-on:
|
||||
- buildjet-8vcpu-ubuntu-2204
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
- name: Add Rust to the PATH
|
||||
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
- name: Install cargo-hakari
|
||||
uses: clechasseur/rs-cargo@8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386 # v2
|
||||
with:
|
||||
command: install
|
||||
args: cargo-hakari@0.9.35
|
||||
|
||||
- name: Check workspace-hack Cargo.toml is up-to-date
|
||||
run: |
|
||||
cargo hakari generate --diff || {
|
||||
echo "To fix, run script/update-workspace-hack or script/update-workspace-hack.ps1";
|
||||
false
|
||||
}
|
||||
- name: Check all crates depend on workspace-hack
|
||||
run: |
|
||||
cargo hakari manage-deps --dry-run || {
|
||||
echo "To fix, run script/update-workspace-hack or script/update-workspace-hack.ps1"
|
||||
false
|
||||
}
|
||||
|
||||
style:
|
||||
timeout-minutes: 60
|
||||
name: Check formatting and spelling
|
||||
needs: [job_spec]
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on:
|
||||
- buildjet-8vcpu-ubuntu-2204
|
||||
@@ -154,21 +76,6 @@ jobs:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
|
||||
with:
|
||||
version: 9
|
||||
|
||||
- name: Prettier Check on /docs
|
||||
working-directory: ./docs
|
||||
run: |
|
||||
pnpm dlx prettier@${PRETTIER_VERSION} . --check || {
|
||||
echo "To fix, run from the root of the zed repo:"
|
||||
echo " cd docs && pnpm dlx prettier@${PRETTIER_VERSION} . --write && cd .."
|
||||
false
|
||||
}
|
||||
env:
|
||||
PRETTIER_VERSION: 3.5.0
|
||||
|
||||
# To support writing comments that they will certainly be revisited.
|
||||
- name: Check for todo! and FIXME comments
|
||||
run: script/check-todos
|
||||
@@ -184,10 +91,7 @@ jobs:
|
||||
macos_tests:
|
||||
timeout-minutes: 60
|
||||
name: (macOS) Run Clippy and tests
|
||||
needs: [job_spec]
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- test
|
||||
@@ -205,27 +109,17 @@ jobs:
|
||||
- name: cargo clippy
|
||||
run: ./script/clippy
|
||||
|
||||
- name: Install cargo-machete
|
||||
uses: clechasseur/rs-cargo@8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386 # v2
|
||||
with:
|
||||
command: install
|
||||
args: cargo-machete@0.7.0
|
||||
|
||||
- name: Check unused dependencies
|
||||
uses: clechasseur/rs-cargo@8435b10f6e71c2e3d4d3b7573003a8ce4bfc6386 # v2
|
||||
with:
|
||||
command: machete
|
||||
uses: bnjbvr/cargo-machete@main
|
||||
|
||||
- name: Check licenses
|
||||
run: |
|
||||
script/check-licenses
|
||||
if [[ "${{ needs.job_spec.outputs.run_license }}" == "true" ]]; then
|
||||
script/generate-licenses /tmp/zed_licenses_output
|
||||
fi
|
||||
script/generate-licenses /tmp/zed_licenses_output
|
||||
|
||||
- name: Check for new vulnerable dependencies
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/dependency-review-action@67d4f4bd7a9b17a0db54d2a7519187c65e339de8 # v4
|
||||
uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4
|
||||
with:
|
||||
license-check: false
|
||||
|
||||
@@ -242,6 +136,7 @@ jobs:
|
||||
cargo check -p workspace
|
||||
cargo build -p remote_server
|
||||
cargo check -p gpui --examples
|
||||
script/check-rust-livekit-macos
|
||||
|
||||
# Since the macOS runners are stateful, so we need to remove the config file to prevent potential bug.
|
||||
- name: Clean CI config file
|
||||
@@ -251,10 +146,7 @@ jobs:
|
||||
linux_tests:
|
||||
timeout-minutes: 60
|
||||
name: (Linux) Run Clippy and tests
|
||||
needs: [job_spec]
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on:
|
||||
- buildjet-16vcpu-ubuntu-2204
|
||||
steps:
|
||||
@@ -267,7 +159,7 @@ jobs:
|
||||
clean: false
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2
|
||||
uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
|
||||
with:
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
cache-provider: "buildjet"
|
||||
@@ -303,12 +195,9 @@ jobs:
|
||||
build_remote_server:
|
||||
timeout-minutes: 60
|
||||
name: (Linux) Build Remote Server
|
||||
needs: [job_spec]
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on:
|
||||
- buildjet-8vcpu-ubuntu-2204
|
||||
- buildjet-16vcpu-ubuntu-2204
|
||||
steps:
|
||||
- name: Add Rust to the PATH
|
||||
run: echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
||||
@@ -319,7 +208,7 @@ jobs:
|
||||
clean: false
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2
|
||||
uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
|
||||
with:
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
cache-provider: "buildjet"
|
||||
@@ -339,14 +228,11 @@ jobs:
|
||||
if: always()
|
||||
run: rm -rf ./../.cargo
|
||||
|
||||
windows_clippy:
|
||||
windows_tests:
|
||||
timeout-minutes: 60
|
||||
name: (Windows) Run Clippy
|
||||
needs: [job_spec]
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
runs-on: windows-2025-16
|
||||
name: (Windows) Run Clippy and tests
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on: hosted-windows-1
|
||||
steps:
|
||||
# more info here:- https://github.com/rust-lang/cargo/issues/13020
|
||||
- name: Enable longer pathnames for git
|
||||
@@ -366,7 +252,7 @@ jobs:
|
||||
Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.ZED_WORKSPACE }}" -Recurse
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2
|
||||
uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
|
||||
with:
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
workspaces: ${{ env.ZED_WORKSPACE }}
|
||||
@@ -379,62 +265,8 @@ jobs:
|
||||
|
||||
- name: cargo clippy
|
||||
working-directory: ${{ env.ZED_WORKSPACE }}
|
||||
run: ./script/clippy.ps1
|
||||
|
||||
- name: Check dev drive space
|
||||
working-directory: ${{ env.ZED_WORKSPACE }}
|
||||
# `setup-dev-driver.ps1` creates a 100GB drive, with CI taking up ~45GB of the drive.
|
||||
run: ./script/exit-ci-if-dev-drive-is-full.ps1 95
|
||||
|
||||
# Since the Windows runners are stateful, so we need to remove the config file to prevent potential bug.
|
||||
- name: Clean CI config file
|
||||
if: always()
|
||||
run: |
|
||||
if (Test-Path "${{ env.CARGO_HOME }}/config.toml") {
|
||||
Remove-Item -Path "${{ env.CARGO_HOME }}/config.toml" -Force
|
||||
}
|
||||
|
||||
# Windows CI takes twice as long as our other platforms and fast github hosted runners are expensive.
|
||||
# But we still want to do CI, so let's only run tests on main and come back to this when we're
|
||||
# ready to self host our Windows CI (e.g. during the push for full Windows support)
|
||||
windows_tests:
|
||||
timeout-minutes: 60
|
||||
name: (Windows) Run Tests
|
||||
needs: [job_spec]
|
||||
if: |
|
||||
github.repository_owner == 'zed-industries' &&
|
||||
needs.job_spec.outputs.run_tests == 'true'
|
||||
# Use bigger runners for PRs (speed); smaller for async (cost)
|
||||
runs-on: ${{ github.event_name == 'pull_request' && 'windows-2025-32' || 'windows-2025-16' }}
|
||||
steps:
|
||||
# more info here:- https://github.com/rust-lang/cargo/issues/13020
|
||||
- name: Enable longer pathnames for git
|
||||
run: git config --system core.longpaths true
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
clean: false
|
||||
|
||||
- name: Create Dev Drive using ReFS
|
||||
run: ./script/setup-dev-driver.ps1
|
||||
|
||||
# actions/checkout does not let us clone into anywhere outside ${{ github.workspace }}, so we have to copy the clone...
|
||||
- name: Copy Git Repo to Dev Drive
|
||||
run: |
|
||||
Copy-Item -Path "${{ github.workspace }}" -Destination "${{ env.ZED_WORKSPACE }}" -Recurse
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2
|
||||
with:
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
workspaces: ${{ env.ZED_WORKSPACE }}
|
||||
cache-provider: "github"
|
||||
|
||||
- name: Configure CI
|
||||
run: |
|
||||
mkdir -p ${{ env.CARGO_HOME }} -ErrorAction Ignore
|
||||
cp ./.cargo/ci-config.toml ${{ env.CARGO_HOME }}/config.toml
|
||||
# Windows can't run shell scripts, so we need to use `cargo xtask`.
|
||||
run: cargo xtask clippy
|
||||
|
||||
- name: Run tests
|
||||
uses: ./.github/actions/run_tests_windows
|
||||
@@ -453,49 +285,7 @@ jobs:
|
||||
# Since the Windows runners are stateful, so we need to remove the config file to prevent potential bug.
|
||||
- name: Clean CI config file
|
||||
if: always()
|
||||
run: |
|
||||
if (Test-Path "${{ env.CARGO_HOME }}/config.toml") {
|
||||
Remove-Item -Path "${{ env.CARGO_HOME }}/config.toml" -Force
|
||||
}
|
||||
|
||||
tests_pass:
|
||||
name: Tests Pass
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- job_spec
|
||||
- style
|
||||
- migration_checks
|
||||
# run_tests: If adding required tests, add them here and to script below.
|
||||
- workspace_hack
|
||||
- linux_tests
|
||||
- build_remote_server
|
||||
- macos_tests
|
||||
- windows_clippy
|
||||
- windows_tests
|
||||
if: always()
|
||||
steps:
|
||||
- name: Check all tests passed
|
||||
run: |
|
||||
# Check dependent jobs...
|
||||
RET_CODE=0
|
||||
# Always check style
|
||||
[[ "${{ needs.style.result }}" != 'success' ]] && { RET_CODE=1; echo "style tests failed"; }
|
||||
|
||||
# Only check test jobs if they were supposed to run
|
||||
if [[ "${{ needs.job_spec.outputs.run_tests }}" == "true" ]]; then
|
||||
[[ "${{ needs.workspace_hack.result }}" != 'success' ]] && { RET_CODE=1; echo "Workspace Hack failed"; }
|
||||
[[ "${{ needs.macos_tests.result }}" != 'success' ]] && { RET_CODE=1; echo "macOS tests failed"; }
|
||||
[[ "${{ needs.linux_tests.result }}" != 'success' ]] && { RET_CODE=1; echo "Linux tests failed"; }
|
||||
[[ "${{ needs.windows_tests.result }}" != 'success' ]] && { RET_CODE=1; echo "Windows tests failed"; }
|
||||
[[ "${{ needs.windows_clippy.result }}" != 'success' ]] && { RET_CODE=1; echo "Windows clippy failed"; }
|
||||
[[ "${{ needs.build_remote_server.result }}" != 'success' ]] && { RET_CODE=1; echo "Remote server build failed"; }
|
||||
# This check is intentionally disabled. See: https://github.com/zed-industries/zed/pull/28431
|
||||
# [[ "${{ needs.migration_checks.result }}" != 'success' ]] && { RET_CODE=1; echo "Migration Checks failed"; }
|
||||
fi
|
||||
if [[ "$RET_CODE" -eq 0 ]]; then
|
||||
echo "All tests passed successfully!"
|
||||
fi
|
||||
exit $RET_CODE
|
||||
run: Remove-Item -Path "${{ env.CARGO_HOME }}/config.toml" -Force
|
||||
|
||||
bundle-mac:
|
||||
timeout-minutes: 120
|
||||
@@ -503,23 +293,20 @@ jobs:
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- bundle
|
||||
if: |
|
||||
startsWith(github.ref, 'refs/tags/v')
|
||||
|| contains(github.event.pull_request.labels.*.name, 'run-bundling')
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
needs: [macos_tests]
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
|
||||
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
|
||||
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
|
||||
APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
|
||||
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
|
||||
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
|
||||
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
@@ -563,14 +350,14 @@ jobs:
|
||||
mv target/x86_64-apple-darwin/release/Zed.dmg target/x86_64-apple-darwin/release/Zed-x86_64.dmg
|
||||
|
||||
- name: Upload app bundle (aarch64) to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
|
||||
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
with:
|
||||
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-aarch64.dmg
|
||||
path: target/aarch64-apple-darwin/release/Zed-aarch64.dmg
|
||||
|
||||
- name: Upload app bundle (x86_64) to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
|
||||
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
with:
|
||||
name: Zed_${{ github.event.pull_request.head.sha || github.sha }}-x86_64.dmg
|
||||
@@ -595,9 +382,7 @@ jobs:
|
||||
name: Linux x86_x64 release bundle
|
||||
runs-on:
|
||||
- buildjet-16vcpu-ubuntu-2004
|
||||
if: |
|
||||
startsWith(github.ref, 'refs/tags/v')
|
||||
|| contains(github.event.pull_request.labels.*.name, 'run-bundling')
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
needs: [linux_tests]
|
||||
env:
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
@@ -614,7 +399,7 @@ jobs:
|
||||
run: ./script/linux && ./script/install-mold 2.34.0
|
||||
|
||||
- name: Determine version and release channel
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
run: |
|
||||
# This exports RELEASE_CHANNEL into env (GITHUB_ENV)
|
||||
script/determine-release-channel
|
||||
@@ -623,23 +408,12 @@ jobs:
|
||||
run: script/bundle-linux
|
||||
|
||||
- name: Upload Linux bundle to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
if: |
|
||||
github.ref == 'refs/heads/main'
|
||||
|| contains(github.event.pull_request.labels.*.name, 'run-bundling')
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
|
||||
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
with:
|
||||
name: zed-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.tar.gz
|
||||
path: target/release/zed-*.tar.gz
|
||||
|
||||
- name: Upload Linux remote server to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
if: |
|
||||
github.ref == 'refs/heads/main'
|
||||
|| contains(github.event.pull_request.labels.*.name, 'run-bundling')
|
||||
with:
|
||||
name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-x86_64-unknown-linux-gnu.gz
|
||||
path: target/zed-remote-server-linux-x86_64.gz
|
||||
|
||||
- name: Upload app bundle to release
|
||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
||||
with:
|
||||
@@ -656,9 +430,7 @@ jobs:
|
||||
name: Linux arm64 release bundle
|
||||
runs-on:
|
||||
- buildjet-16vcpu-ubuntu-2204-arm
|
||||
if: |
|
||||
startsWith(github.ref, 'refs/tags/v')
|
||||
|| contains(github.event.pull_request.labels.*.name, 'run-bundling')
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
needs: [linux_tests]
|
||||
env:
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
@@ -675,7 +447,7 @@ jobs:
|
||||
run: ./script/linux
|
||||
|
||||
- name: Determine version and release channel
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
|
||||
run: |
|
||||
# This exports RELEASE_CHANNEL into env (GITHUB_ENV)
|
||||
script/determine-release-channel
|
||||
@@ -684,23 +456,12 @@ jobs:
|
||||
run: script/bundle-linux
|
||||
|
||||
- name: Upload Linux bundle to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
if: |
|
||||
github.ref == 'refs/heads/main'
|
||||
|| contains(github.event.pull_request.labels.*.name, 'run-bundling')
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
|
||||
if: ${{ github.ref == 'refs/heads/main' }} || contains(github.event.pull_request.labels.*.name, 'run-bundling') }}
|
||||
with:
|
||||
name: zed-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.tar.gz
|
||||
path: target/release/zed-*.tar.gz
|
||||
|
||||
- name: Upload Linux remote server to workflow run if main branch or specific label
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
if: |
|
||||
github.ref == 'refs/heads/main'
|
||||
|| contains(github.event.pull_request.labels.*.name, 'run-bundling')
|
||||
with:
|
||||
name: zed-remote-server-${{ github.event.pull_request.head.sha || github.sha }}-aarch64-unknown-linux-gnu.gz
|
||||
path: target/zed-remote-server-linux-aarch64.gz
|
||||
|
||||
- name: Upload app bundle to release
|
||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v1
|
||||
with:
|
||||
@@ -712,56 +473,9 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
nix-build:
|
||||
timeout-minutes: 60
|
||||
name: Nix Build
|
||||
continue-on-error: true
|
||||
if: github.repository_owner == 'zed-industries' && contains(github.event.pull_request.labels.*.name, 'run-nix')
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
system:
|
||||
- os: x86 Linux
|
||||
runner: buildjet-16vcpu-ubuntu-2204
|
||||
install_nix: true
|
||||
- os: arm Mac
|
||||
runner: [macOS, ARM64, test]
|
||||
install_nix: false
|
||||
runs-on: ${{ matrix.system.runner }}
|
||||
env:
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
|
||||
GIT_LFS_SKIP_SMUDGE: 1 # breaks the livekit rust sdk examples which we don't actually depend on
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
clean: false
|
||||
- name: Set path
|
||||
if: ${{ ! matrix.system.install_nix }}
|
||||
run: |
|
||||
echo "/nix/var/nix/profiles/default/bin" >> $GITHUB_PATH
|
||||
echo "/Users/administrator/.nix-profile/bin" >> $GITHUB_PATH
|
||||
|
||||
- uses: cachix/install-nix-action@d1ca217b388ee87b2507a9a93bf01368bde7cec2 # v31
|
||||
if: ${{ matrix.system.install_nix }}
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
name: zed-industries
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
skipPush: true
|
||||
- run: nix build .#debug
|
||||
- name: Limit /nix/store to 50GB
|
||||
run: "[ $(du -sm /nix/store | cut -f1) -gt 50000 ] && nix-collect-garbage -d"
|
||||
|
||||
auto-release-preview:
|
||||
name: Auto release preview
|
||||
if: |
|
||||
startsWith(github.ref, 'refs/tags/v')
|
||||
&& endsWith(github.ref, '-pre') && !endsWith(github.ref, '.0-pre')
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') && endsWith(github.ref, '-pre') && !endsWith(github.ref, '.0-pre') }}
|
||||
needs: [bundle-mac, bundle-linux-x86_x64, bundle-linux-aarch64]
|
||||
runs-on:
|
||||
- self-hosted
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: "Close Stale Issues"
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 7,9,11 * * 3"
|
||||
- cron: "0 11 * * 2"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
41
.github/workflows/community_release_actions.yml
vendored
@@ -13,12 +13,11 @@ jobs:
|
||||
id: get-release-url
|
||||
run: |
|
||||
if [ "${{ github.event.release.prerelease }}" == "true" ]; then
|
||||
URL="https://zed.dev/releases/preview/latest"
|
||||
URL="https://zed.dev/releases/preview/latest"
|
||||
else
|
||||
URL="https://zed.dev/releases/stable/latest"
|
||||
URL="https://zed.dev/releases/stable/latest"
|
||||
fi
|
||||
|
||||
echo "URL=$URL" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=URL::$URL"
|
||||
- name: Get content
|
||||
uses: 2428392/gh-truncate-string-action@b3ff790d21cf42af3ca7579146eedb93c8fb0757 # v1.4.1
|
||||
id: get-content
|
||||
@@ -34,37 +33,3 @@ jobs:
|
||||
with:
|
||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
content: ${{ steps.get-content.outputs.string }}
|
||||
|
||||
send_release_notes_email:
|
||||
if: github.repository_owner == 'zed-industries' && !github.event.release.prerelease
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check if release was promoted from preview
|
||||
id: check-promotion-from-preview
|
||||
run: |
|
||||
VERSION="${{ github.event.release.tag_name }}"
|
||||
PREVIEW_TAG="${VERSION}-pre"
|
||||
|
||||
if git rev-parse "$PREVIEW_TAG" > /dev/null 2>&1; then
|
||||
echo "was_promoted_from_preview=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "was_promoted_from_preview=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Send release notes email
|
||||
if: steps.check-promotion-from-preview.outputs.was_promoted_from_preview == 'true'
|
||||
run: |
|
||||
TAG="${{ github.event.release.tag_name }}"
|
||||
cat << 'EOF' > release_body.txt
|
||||
${{ github.event.release.body }}
|
||||
EOF
|
||||
jq -n --arg tag "$TAG" --rawfile body release_body.txt '{version: $tag, markdown_body: $body}' \
|
||||
> release_data.json
|
||||
curl -X POST "https://zed.dev/api/send_release_notes_email" \
|
||||
-H "Authorization: Bearer ${{ secrets.RELEASE_NOTES_API_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @release_data.json
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
name: Update All Top Ranking Issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 */12 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update_top_ranking_issues:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'zed-industries/zed'
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
|
||||
with:
|
||||
version: "latest"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: "script/update_top_ranking_issues/pyproject.toml"
|
||||
- name: Install Python 3.13
|
||||
run: uv python install 3.13
|
||||
- name: Install dependencies
|
||||
run: uv sync --project script/update_top_ranking_issues -p 3.13
|
||||
- name: Run script
|
||||
run: uv run --project script/update_top_ranking_issues script/update_top_ranking_issues/main.py --github-token ${{ secrets.GITHUB_TOKEN }} --issue-reference-number 5393
|
||||
@@ -1,25 +0,0 @@
|
||||
name: Update Weekly Top Ranking Issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 15 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update_top_ranking_issues:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'zed-industries/zed'
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
- name: Set up uv
|
||||
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
|
||||
with:
|
||||
version: "latest"
|
||||
enable-cache: true
|
||||
cache-dependency-glob: "script/update_top_ranking_issues/pyproject.toml"
|
||||
- name: Install Python 3.13
|
||||
run: uv python install 3.13
|
||||
- name: Install dependencies
|
||||
run: uv sync --project script/update_top_ranking_issues -p 3.13
|
||||
- name: Run script
|
||||
run: uv run --project script/update_top_ranking_issues script/update_top_ranking_issues/main.py --github-token ${{ secrets.GITHUB_TOKEN }} --issue-reference-number 6952 --query-day-interval 7
|
||||
2
.github/workflows/danger.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "pnpm"
|
||||
|
||||
10
.github/workflows/deploy_cloudflare.yml
vendored
@@ -37,35 +37,35 @@ jobs:
|
||||
mdbook build ./docs --dest-dir=../target/deploy/docs/
|
||||
|
||||
- name: Deploy Docs
|
||||
uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3
|
||||
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: pages deploy target/deploy --project-name=docs
|
||||
|
||||
- name: Deploy Install
|
||||
uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3
|
||||
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: r2 object put -f script/install.sh zed-open-source-website-assets/install.sh
|
||||
|
||||
- name: Deploy Docs Workers
|
||||
uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3
|
||||
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy .cloudflare/docs-proxy/src/worker.js
|
||||
|
||||
- name: Deploy Install Workers
|
||||
uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 # v3
|
||||
uses: cloudflare/wrangler-action@392082e81ffbcb9ebdde27400634aa004b35ea37 # v3
|
||||
with:
|
||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
||||
command: deploy .cloudflare/docs-proxy/src/worker.js
|
||||
|
||||
- name: Preserve Wrangler logs
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4
|
||||
if: always()
|
||||
with:
|
||||
name: wrangler_logs
|
||||
|
||||
39
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Docs
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "docs/**"
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
check_formatting:
|
||||
name: "Check formatting"
|
||||
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: Prettier Check on /docs
|
||||
working-directory: ./docs
|
||||
run: |
|
||||
pnpm dlx prettier@${PRETTIER_VERSION} . --check || {
|
||||
echo "To fix, run from the root of the zed repo:"
|
||||
echo " cd docs && pnpm dlx prettier@${PRETTIER_VERSION} . --write && cd .."
|
||||
false
|
||||
}
|
||||
env:
|
||||
PRETTIER_VERSION: 3.5.0
|
||||
|
||||
- name: Check for Typos with Typos-CLI
|
||||
uses: crate-ci/typos@8e6a4285bcbde632c5d79900a7779746e8b7ea3f # v1.24.6
|
||||
with:
|
||||
config: ./typos.toml
|
||||
files: ./docs/
|
||||
4
.github/workflows/issue_response.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
version: 9
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "20"
|
||||
cache: "pnpm"
|
||||
@@ -29,5 +29,5 @@ jobs:
|
||||
- name: Run Issue Response
|
||||
run: pnpm run --dir script/issue_response start
|
||||
env:
|
||||
ISSUE_RESPONSE_GITHUB_TOKEN: ${{ secrets.ISSUE_RESPONSE_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SLACK_ISSUE_RESPONSE_WEBHOOK_URL: ${{ secrets.SLACK_ISSUE_RESPONSE_WEBHOOK_URL }}
|
||||
|
||||
2
.github/workflows/publish_extension_cli.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
clean: false
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2
|
||||
uses: swatinem/rust-cache@f0deed1e0edfc6a9be95417288c0e1099b1eeec3 # v2
|
||||
with:
|
||||
save-if: ${{ github.ref == 'refs/heads/main' }}
|
||||
cache-provider: "github"
|
||||
|
||||
2
.github/workflows/randomized_tests.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
- buildjet-16vcpu-ubuntu-2204
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
|
||||
56
.github/workflows/release_nightly.yml
vendored
@@ -62,16 +62,15 @@ jobs:
|
||||
env:
|
||||
MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }}
|
||||
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
|
||||
APPLE_NOTARIZATION_KEY: ${{ secrets.APPLE_NOTARIZATION_KEY }}
|
||||
APPLE_NOTARIZATION_KEY_ID: ${{ secrets.APPLE_NOTARIZATION_KEY_ID }}
|
||||
APPLE_NOTARIZATION_ISSUER_ID: ${{ secrets.APPLE_NOTARIZATION_ISSUER_ID }}
|
||||
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
DIGITALOCEAN_SPACES_ACCESS_KEY: ${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }}
|
||||
DIGITALOCEAN_SPACES_SECRET_KEY: ${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }}
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
|
||||
steps:
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4
|
||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
@@ -170,55 +169,6 @@ jobs:
|
||||
- name: Upload Zed Nightly
|
||||
run: script/upload-nightly linux-targz
|
||||
|
||||
bundle-nix:
|
||||
timeout-minutes: 60
|
||||
name: (${{ matrix.system.os }}) Nix Build
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
system:
|
||||
- os: x86 Linux
|
||||
runner: buildjet-16vcpu-ubuntu-2204
|
||||
install_nix: true
|
||||
- os: arm Mac
|
||||
runner: [macOS, ARM64, test]
|
||||
install_nix: false
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
runs-on: ${{ matrix.system.runner }}
|
||||
needs: tests
|
||||
env:
|
||||
ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
|
||||
ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
|
||||
GIT_LFS_SKIP_SMUDGE: 1 # breaks the livekit rust sdk examples which we don't actually depend on
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
clean: false
|
||||
|
||||
# on our macs we manually install nix. for some reason the cachix action is running
|
||||
# under a non-login /bin/bash shell which doesn't source the proper script to add the
|
||||
# nix profile to PATH, so we manually add them here
|
||||
- name: Set path
|
||||
if: ${{ ! matrix.system.install_nix }}
|
||||
run: |
|
||||
echo "/nix/var/nix/profiles/default/bin" >> $GITHUB_PATH
|
||||
echo "/Users/administrator/.nix-profile/bin" >> $GITHUB_PATH
|
||||
|
||||
- uses: cachix/install-nix-action@d1ca217b388ee87b2507a9a93bf01368bde7cec2 # v31
|
||||
if: ${{ matrix.system.install_nix }}
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
|
||||
with:
|
||||
name: zed-industries
|
||||
authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
|
||||
- run: nix build
|
||||
- name: Limit /nix/store to 50GB
|
||||
run: '[ $(du -sm /nix/store | cut -f1) -gt 50000 ] && nix-collect-garbage -d'
|
||||
|
||||
update-nightly-tag:
|
||||
name: Update nightly tag
|
||||
if: github.repository_owner == 'zed-industries'
|
||||
|
||||
1
.gitignore
vendored
@@ -26,7 +26,6 @@
|
||||
/dev.zed.Zed*.json
|
||||
/plugins/bin
|
||||
/script/node_modules
|
||||
/snap
|
||||
/zed.xcworkspace
|
||||
DerivedData/
|
||||
Packages
|
||||
|
||||
4
.mailmap
@@ -21,8 +21,6 @@ Andrei Zvonimir Crnković <andrei@0x7f.dev>
|
||||
Andrei Zvonimir Crnković <andrei@0x7f.dev> <andreicek@0x7f.dev>
|
||||
Antonio Scandurra <me@as-cii.com>
|
||||
Antonio Scandurra <me@as-cii.com> <antonio@zed.dev>
|
||||
Ben Kunkle <ben@zed.dev>
|
||||
Ben Kunkle <ben@zed.dev> <ben.kunkle@gmail.com>
|
||||
Bennet Bo Fenner <bennet@zed.dev>
|
||||
Bennet Bo Fenner <bennet@zed.dev> <53836821+bennetbo@users.noreply.github.com>
|
||||
Bennet Bo Fenner <bennet@zed.dev> <bennetbo@gmx.de>
|
||||
@@ -114,8 +112,6 @@ Sebastijan Kelnerič <sebastijan.kelneric@sebba.dev> <sebastijan.kelneric@vichav
|
||||
Sergey Onufrienko <sergey@onufrienko.com>
|
||||
Shish <webmaster@shishnet.org>
|
||||
Shish <webmaster@shishnet.org> <shish@shishnet.org>
|
||||
Smit Barmase <0xtimsb@gmail.com>
|
||||
Smit Barmase <0xtimsb@gmail.com> <smit@zed.dev>
|
||||
Thorben Kröger <dev@thorben.net>
|
||||
Thorben Kröger <dev@thorben.net> <thorben.kroeger@hexagon.com>
|
||||
Thorsten Ball <thorsten@zed.dev>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
[
|
||||
{
|
||||
"label": "Debug Zed with LLDB",
|
||||
"adapter": "LLDB",
|
||||
"adapter": "lldb",
|
||||
"program": "$ZED_WORKTREE_ROOT/target/debug/zed",
|
||||
"request": "launch",
|
||||
"cwd": "$ZED_WORKTREE_ROOT"
|
||||
},
|
||||
{
|
||||
"label": "Debug Zed with GDB",
|
||||
"adapter": "GDB",
|
||||
"adapter": "gdb",
|
||||
"program": "$ZED_WORKTREE_ROOT/target/debug/zed",
|
||||
"request": "launch",
|
||||
"cwd": "$ZED_WORKTREE_ROOT",
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
},
|
||||
"JSON": {
|
||||
"tab_size": 2,
|
||||
"preferred_line_length": 120,
|
||||
"preferred_line_length": 100,
|
||||
"formatter": "prettier"
|
||||
},
|
||||
"JSONC": {
|
||||
"tab_size": 2,
|
||||
"preferred_line_length": 120,
|
||||
"preferred_line_length": 100,
|
||||
"formatter": "prettier"
|
||||
},
|
||||
"JavaScript": {
|
||||
|
||||
4648
Cargo.lock
generated
154
Cargo.toml
@@ -2,14 +2,11 @@
|
||||
resolver = "2"
|
||||
members = [
|
||||
"crates/activity_indicator",
|
||||
"crates/agent",
|
||||
"crates/agent_rules",
|
||||
"crates/anthropic",
|
||||
"crates/askpass",
|
||||
"crates/assets",
|
||||
"crates/assistant",
|
||||
"crates/assistant2",
|
||||
"crates/assistant_context_editor",
|
||||
"crates/agent_eval",
|
||||
"crates/assistant_settings",
|
||||
"crates/assistant_slash_command",
|
||||
"crates/assistant_slash_commands",
|
||||
@@ -18,10 +15,7 @@ members = [
|
||||
"crates/audio",
|
||||
"crates/auto_update",
|
||||
"crates/auto_update_ui",
|
||||
"crates/aws_http_client",
|
||||
"crates/bedrock",
|
||||
"crates/breadcrumbs",
|
||||
"crates/buffer_diff",
|
||||
"crates/call",
|
||||
"crates/channel",
|
||||
"crates/cli",
|
||||
@@ -37,7 +31,6 @@ members = [
|
||||
"crates/context_server",
|
||||
"crates/context_server_settings",
|
||||
"crates/copilot",
|
||||
"crates/credentials_provider",
|
||||
"crates/dap",
|
||||
"crates/dap_adapters",
|
||||
"crates/debugger_tools",
|
||||
@@ -45,6 +38,7 @@ members = [
|
||||
"crates/db",
|
||||
"crates/deepseek",
|
||||
"crates/diagnostics",
|
||||
"crates/buffer_diff",
|
||||
"crates/docs_preprocessor",
|
||||
"crates/editor",
|
||||
"crates/evals",
|
||||
@@ -70,8 +64,6 @@ members = [
|
||||
"crates/gpui_tokio",
|
||||
"crates/html_to_markdown",
|
||||
"crates/http_client",
|
||||
"crates/http_client_tls",
|
||||
"crates/icons",
|
||||
"crates/image_viewer",
|
||||
"crates/indexed_docs",
|
||||
"crates/inline_completion",
|
||||
@@ -88,6 +80,7 @@ members = [
|
||||
"crates/languages",
|
||||
"crates/livekit_api",
|
||||
"crates/livekit_client",
|
||||
"crates/livekit_client_macos",
|
||||
"crates/lmstudio",
|
||||
"crates/lsp",
|
||||
"crates/markdown",
|
||||
@@ -111,7 +104,6 @@ members = [
|
||||
"crates/project_panel",
|
||||
"crates/project_symbols",
|
||||
"crates/prompt_library",
|
||||
"crates/prompt_store",
|
||||
"crates/proto",
|
||||
"crates/recent_projects",
|
||||
"crates/refineable",
|
||||
@@ -160,7 +152,6 @@ members = [
|
||||
"crates/ui",
|
||||
"crates/ui_input",
|
||||
"crates/ui_macros",
|
||||
"crates/ui_prompt",
|
||||
"crates/util",
|
||||
"crates/util_macros",
|
||||
"crates/vim",
|
||||
@@ -171,36 +162,43 @@ members = [
|
||||
"crates/zed",
|
||||
"crates/zed_actions",
|
||||
"crates/zeta",
|
||||
"crates/zlog",
|
||||
"crates/zlog_settings",
|
||||
|
||||
#
|
||||
# Extensions
|
||||
#
|
||||
|
||||
"extensions/csharp",
|
||||
"extensions/deno",
|
||||
"extensions/elixir",
|
||||
"extensions/emmet",
|
||||
"extensions/erlang",
|
||||
"extensions/glsl",
|
||||
"extensions/haskell",
|
||||
"extensions/html",
|
||||
"extensions/lua",
|
||||
"extensions/perplexity",
|
||||
"extensions/proto",
|
||||
"extensions/purescript",
|
||||
"extensions/ruff",
|
||||
"extensions/slash-commands-example",
|
||||
"extensions/snippets",
|
||||
"extensions/terraform",
|
||||
"extensions/test-extension",
|
||||
"extensions/toml",
|
||||
"extensions/uiua",
|
||||
"extensions/zig",
|
||||
|
||||
#
|
||||
# Tooling
|
||||
#
|
||||
|
||||
"tooling/workspace-hack",
|
||||
"tooling/xtask",
|
||||
]
|
||||
default-members = ["crates/zed"]
|
||||
|
||||
[workspace.package]
|
||||
publish = false
|
||||
edition = "2024"
|
||||
edition = "2021"
|
||||
|
||||
[workspace.dependencies]
|
||||
|
||||
@@ -209,15 +207,12 @@ edition = "2024"
|
||||
#
|
||||
|
||||
activity_indicator = { path = "crates/activity_indicator" }
|
||||
agent = { path = "crates/agent" }
|
||||
agent_rules = { path = "crates/agent_rules" }
|
||||
ai = { path = "crates/ai" }
|
||||
anthropic = { path = "crates/anthropic" }
|
||||
askpass = { path = "crates/askpass" }
|
||||
assets = { path = "crates/assets" }
|
||||
assistant = { path = "crates/assistant" }
|
||||
assistant2 = { path = "crates/assistant2" }
|
||||
assistant_context_editor = { path = "crates/assistant_context_editor" }
|
||||
assistant_eval = { path = "crates/agent_eval" }
|
||||
assistant_settings = { path = "crates/assistant_settings" }
|
||||
assistant_slash_command = { path = "crates/assistant_slash_command" }
|
||||
assistant_slash_commands = { path = "crates/assistant_slash_commands" }
|
||||
@@ -226,8 +221,6 @@ assistant_tools = { path = "crates/assistant_tools" }
|
||||
audio = { path = "crates/audio" }
|
||||
auto_update = { path = "crates/auto_update" }
|
||||
auto_update_ui = { path = "crates/auto_update_ui" }
|
||||
aws_http_client = { path = "crates/aws_http_client" }
|
||||
bedrock = { path = "crates/bedrock" }
|
||||
breadcrumbs = { path = "crates/breadcrumbs" }
|
||||
call = { path = "crates/call" }
|
||||
channel = { path = "crates/channel" }
|
||||
@@ -244,7 +237,6 @@ component_preview = { path = "crates/component_preview" }
|
||||
context_server = { path = "crates/context_server" }
|
||||
context_server_settings = { path = "crates/context_server_settings" }
|
||||
copilot = { path = "crates/copilot" }
|
||||
credentials_provider = { path = "crates/credentials_provider" }
|
||||
dap = { path = "crates/dap" }
|
||||
dap_adapters = { path = "crates/dap_adapters" }
|
||||
db = { path = "crates/db" }
|
||||
@@ -276,8 +268,6 @@ gpui_macros = { path = "crates/gpui_macros" }
|
||||
gpui_tokio = { path = "crates/gpui_tokio" }
|
||||
html_to_markdown = { path = "crates/html_to_markdown" }
|
||||
http_client = { path = "crates/http_client" }
|
||||
http_client_tls = { path = "crates/http_client_tls" }
|
||||
icons = { path = "crates/icons" }
|
||||
image_viewer = { path = "crates/image_viewer" }
|
||||
indexed_docs = { path = "crates/indexed_docs" }
|
||||
inline_completion = { path = "crates/inline_completion" }
|
||||
@@ -294,6 +284,7 @@ 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" }
|
||||
lmstudio = { path = "crates/lmstudio" }
|
||||
lsp = { path = "crates/lsp" }
|
||||
markdown = { path = "crates/markdown" }
|
||||
@@ -319,7 +310,6 @@ project = { path = "crates/project" }
|
||||
project_panel = { path = "crates/project_panel" }
|
||||
project_symbols = { path = "crates/project_symbols" }
|
||||
prompt_library = { path = "crates/prompt_library" }
|
||||
prompt_store = { path = "crates/prompt_store" }
|
||||
proto = { path = "crates/proto" }
|
||||
recent_projects = { path = "crates/recent_projects" }
|
||||
refineable = { path = "crates/refineable" }
|
||||
@@ -366,7 +356,6 @@ toolchain_selector = { path = "crates/toolchain_selector" }
|
||||
ui = { path = "crates/ui" }
|
||||
ui_input = { path = "crates/ui_input" }
|
||||
ui_macros = { path = "crates/ui_macros" }
|
||||
ui_prompt = { path = "crates/ui_prompt" }
|
||||
util = { path = "crates/util" }
|
||||
util_macros = { path = "crates/util_macros" }
|
||||
vim = { path = "crates/vim" }
|
||||
@@ -377,15 +366,14 @@ worktree = { path = "crates/worktree" }
|
||||
zed = { path = "crates/zed" }
|
||||
zed_actions = { path = "crates/zed_actions" }
|
||||
zeta = { path = "crates/zeta" }
|
||||
zlog = { path = "crates/zlog" }
|
||||
zlog_settings = { path = "crates/zlog_settings" }
|
||||
|
||||
#
|
||||
# External crates
|
||||
#
|
||||
|
||||
aho-corasick = "1.1"
|
||||
alacritty_terminal = { git = "https://github.com/zed-industries/alacritty.git", branch = "add-hush-login-flag" }
|
||||
# TODO(#18342): Update to version 0.25 from crates.io when it is released.
|
||||
alacritty_terminal = { git = "https://github.com/alacritty/alacritty.git", rev = "5e78d20c709cb1ab8d44ca7a8702cc26d779227c" }
|
||||
any_vec = "0.14"
|
||||
anyhow = "1.0.86"
|
||||
arrayvec = { version = "0.7.4", features = ["serde"] }
|
||||
@@ -398,14 +386,9 @@ async-pipe = { git = "https://github.com/zed-industries/async-pipe-rs", rev = "8
|
||||
async-recursion = "1.0.0"
|
||||
async-tar = "0.5.0"
|
||||
async-trait = "0.1"
|
||||
async-tungstenite = "0.29.1"
|
||||
async-tungstenite = "0.28"
|
||||
async-watch = "0.3.1"
|
||||
async_zip = { version = "0.0.17", features = ["deflate", "deflate64"] }
|
||||
aws-config = { version = "1.6.1", features = ["behavior-version-latest"] }
|
||||
aws-credential-types = { version = "1.2.2", features = ["hardcoded-credentials"] }
|
||||
aws-sdk-bedrockruntime = { version = "1.80.0", features = ["behavior-version-latest"] }
|
||||
aws-smithy-runtime-api = { version = "1.7.4", features = ["http-1x", "client"] }
|
||||
aws-smithy-types = { version = "1.3.0", features = ["http-body-1-x"] }
|
||||
base64 = "0.22"
|
||||
bitflags = "2.6.0"
|
||||
blade-graphics = { git = "https://github.com/kvark/blade", rev = "b16f5c7bd873c7126f48c82c39e7ae64602ae74f" }
|
||||
@@ -417,17 +400,14 @@ bytes = "1.0"
|
||||
cargo_metadata = "0.19"
|
||||
cargo_toml = "0.21"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
circular-buffer = "1.0"
|
||||
clap = { version = "4.4", features = ["derive"] }
|
||||
cocoa = "0.26"
|
||||
cocoa-foundation = "0.2.0"
|
||||
core-video = { version = "0.4.3", features = ["metal"] }
|
||||
convert_case = "0.8.0"
|
||||
core-foundation = "0.10.0"
|
||||
convert_case = "0.7.0"
|
||||
core-foundation = "0.9.3"
|
||||
core-foundation-sys = "0.8.6"
|
||||
ctor = "0.4.0"
|
||||
ctor = "0.3.0"
|
||||
dashmap = "6.0"
|
||||
dap-types = { git = "https://github.com/zed-industries/dap-types", rev = "be69a016ba710191b9fdded28c8b042af4b617f7" }
|
||||
derive_more = "0.99.17"
|
||||
dirs = "4.0"
|
||||
ec4rs = "1.1"
|
||||
@@ -439,7 +419,8 @@ fork = "0.2.0"
|
||||
futures = "0.3"
|
||||
futures-batch = "0.6.1"
|
||||
futures-lite = "1.13"
|
||||
git2 = { version = "0.20.1", default-features = false }
|
||||
# TODO: get back to regular versions when https://github.com/rust-lang/git2-rs/pull/1120 is released
|
||||
git2 = { git = "https://github.com/rust-lang/git2-rs", rev = "a3b90cb3756c1bb63e2317bf9cfa57838178de5c", default-features = false }
|
||||
globset = "0.4"
|
||||
handlebars = "4.3"
|
||||
heed = { version = "0.21.0", features = ["read-txn-no-tls"] }
|
||||
@@ -449,38 +430,40 @@ hyper = "0.14"
|
||||
http = "1.1"
|
||||
ignore = "0.4.22"
|
||||
image = "0.25.1"
|
||||
imara-diff = "0.1.8"
|
||||
indexmap = { version = "2.7.0", features = ["serde"] }
|
||||
indoc = "2"
|
||||
inventory = "0.3.19"
|
||||
itertools = "0.14.0"
|
||||
jsonwebtoken = "9.3"
|
||||
jupyter-protocol = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
|
||||
jupyter-websocket-client = { git = "https://github.com/ConradIrwin/runtimed" ,rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
|
||||
jupyter-protocol = { version = "0.6.0" }
|
||||
jupyter-websocket-client = { version = "0.9.0" }
|
||||
libc = "0.2"
|
||||
libsqlite3-sys = { version = "0.30.1", features = ["bundled"] }
|
||||
linkify = "0.10.0"
|
||||
linkme = "0.3.31"
|
||||
livekit = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "811ceae29fabee455f110c56cd66b3f49a7e5003", features = [
|
||||
"dispatcher",
|
||||
"services-dispatcher",
|
||||
"rustls-tls-native-roots",
|
||||
], default-features = false }
|
||||
log = { version = "0.4.16", features = ["kv_unstable_serde", "serde"] }
|
||||
markup5ever_rcdom = "0.3.0"
|
||||
mlua = { version = "0.10", features = ["lua54", "vendored", "async", "send"] }
|
||||
nanoid = "0.4"
|
||||
nbformat = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734" }
|
||||
nbformat = { version = "0.10.0" }
|
||||
nix = "0.29"
|
||||
objc = "0.2"
|
||||
open = "5.0.0"
|
||||
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"
|
||||
pathdiff = "0.2"
|
||||
pet = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-fs = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-pixi = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-conda = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-core = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "845945b830297a50de0e24020b980a65e4820559" }
|
||||
pet = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-fs = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-pixi = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-conda = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-core = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-poetry = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
pet-reporter = { git = "https://github.com/microsoft/python-environment-tools.git", rev = "1abe5cec5ebfbe97ca71746a4cfc7fe89bddf8e0" }
|
||||
postage = { version = "0.5", features = ["futures-traits"] }
|
||||
pretty_assertions = { version = "1.3.0", features = ["unstable"] }
|
||||
proc-macro2 = "1.0.93"
|
||||
@@ -503,7 +486,7 @@ reqwest = { git = "https://github.com/zed-industries/reqwest.git", rev = "fd110f
|
||||
"stream",
|
||||
] }
|
||||
rsa = "0.9.6"
|
||||
runtimelib = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c804216b6914355d15d0b91ea91f6babd734", default-features = false, features = [
|
||||
runtimelib = { version = "0.25.0", default-features = false, features = [
|
||||
"async-dispatcher-runtime",
|
||||
] }
|
||||
rustc-demangle = "0.1.23"
|
||||
@@ -511,7 +494,6 @@ rust-embed = { version = "8.4", features = ["include-exclude"] }
|
||||
rustc-hash = "2.1.0"
|
||||
rustls = { version = "0.23.22" }
|
||||
rustls-platform-verifier = "0.5.0"
|
||||
scap = { git = "https://github.com/zed-industries/scap", rev = "08f0a01417505cc0990b9931a37e5120db92e0d0", default-features = false }
|
||||
schemars = { version = "0.8", features = ["impl_json_schema", "indexmap2"] }
|
||||
semver = "1.0"
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
@@ -526,6 +508,7 @@ sha2 = "0.10"
|
||||
shellexpand = "2.1.0"
|
||||
shlex = "1.3.0"
|
||||
signal-hook = "0.3.17"
|
||||
similar = "1.3"
|
||||
simplelog = "0.12.2"
|
||||
smallvec = { version = "1.6", features = ["union"] }
|
||||
smol = "2.0"
|
||||
@@ -539,7 +522,7 @@ sys-locale = "0.3.1"
|
||||
sysinfo = "0.31.0"
|
||||
take-until = "0.2.0"
|
||||
tempfile = "3.9.0"
|
||||
thiserror = "2.0.12"
|
||||
thiserror = "1.0.29"
|
||||
tiktoken-rs = "0.6.0"
|
||||
time = { version = "0.3", features = [
|
||||
"macros",
|
||||
@@ -551,29 +534,28 @@ time = { version = "0.3", features = [
|
||||
tiny_http = "0.8"
|
||||
toml = "0.8"
|
||||
tokio = { version = "1" }
|
||||
tokio-tungstenite = { version = "0.26", features = ["__rustls-tls"] }
|
||||
tower-http = "0.4.4"
|
||||
tree-sitter = { version = "0.25.3", features = ["wasm"] }
|
||||
tree-sitter = { version = "0.24", features = ["wasm"] }
|
||||
tree-sitter-bash = "0.23"
|
||||
tree-sitter-c = "0.23"
|
||||
tree-sitter-cpp = "0.23"
|
||||
tree-sitter-css = "0.23"
|
||||
tree-sitter-elixir = "0.3"
|
||||
tree-sitter-embedded-template = "0.23.0"
|
||||
tree-sitter-gitcommit = { git = "https://github.com/zed-industries/tree-sitter-git-commit", rev = "88309716a69dd13ab83443721ba6e0b491d37ee9" }
|
||||
tree-sitter-gitcommit = {git = "https://github.com/zed-industries/tree-sitter-git-commit", rev = "88309716a69dd13ab83443721ba6e0b491d37ee9"}
|
||||
tree-sitter-go = "0.23"
|
||||
tree-sitter-go-mod = { git = "https://github.com/camdencheek/tree-sitter-go-mod", rev = "6efb59652d30e0e9cd5f3b3a669afd6f1a926d3c", package = "tree-sitter-gomod" }
|
||||
tree-sitter-gowork = { git = "https://github.com/zed-industries/tree-sitter-go-work", rev = "acb0617bf7f4fda02c6217676cc64acb89536dc7" }
|
||||
tree-sitter-heex = { git = "https://github.com/zed-industries/tree-sitter-heex", rev = "1dd45142fbb05562e35b2040c6129c9bca346592" }
|
||||
tree-sitter-diff = "0.1.0"
|
||||
tree-sitter-html = "0.23"
|
||||
tree-sitter-html = "0.20"
|
||||
tree-sitter-jsdoc = "0.23"
|
||||
tree-sitter-json = "0.24"
|
||||
tree-sitter-md = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", rev = "9a23c1a96c0513d8fc6520972beedd419a973539" }
|
||||
tree-sitter-python = "0.23"
|
||||
tree-sitter-regex = "0.24"
|
||||
tree-sitter-ruby = "0.23"
|
||||
tree-sitter-rust = "0.24"
|
||||
tree-sitter-rust = "0.23"
|
||||
tree-sitter-typescript = "0.23"
|
||||
tree-sitter-yaml = { git = "https://github.com/zed-industries/tree-sitter-yaml", rev = "baff0b51c64ef6a1fb1f8390f3ad6015b83ec13a" }
|
||||
unicase = "2.6"
|
||||
@@ -581,25 +563,22 @@ unindent = "0.2.0"
|
||||
unicode-segmentation = "1.10"
|
||||
unicode-script = "0.5.7"
|
||||
url = "2.2"
|
||||
urlencoding = "2.1.2"
|
||||
uuid = { version = "1.1.2", features = ["v4", "v5", "v7", "serde"] }
|
||||
walkdir = "2.3"
|
||||
wasmparser = "0.221"
|
||||
wasm-encoder = "0.221"
|
||||
wasmtime = { version = "29", default-features = false, features = [
|
||||
wasmparser = "0.217"
|
||||
wasm-encoder = "0.217"
|
||||
wasmtime = { version = "25", default-features = false, features = [
|
||||
"async",
|
||||
"demangle",
|
||||
"runtime",
|
||||
"cranelift",
|
||||
"component-model",
|
||||
] }
|
||||
wasmtime-wasi = "29"
|
||||
wasmtime-wasi = "25"
|
||||
which = "6.0.0"
|
||||
wit-component = "0.221"
|
||||
workspace-hack = "0.1.0"
|
||||
wit-component = "0.201"
|
||||
zed_llm_client = "0.4"
|
||||
zstd = "0.11"
|
||||
metal = "0.29"
|
||||
metal = "0.31"
|
||||
|
||||
[workspace.dependencies.async-stripe]
|
||||
git = "https://github.com/zed-industries/async-stripe"
|
||||
@@ -616,14 +595,12 @@ features = [
|
||||
]
|
||||
|
||||
[workspace.dependencies.windows]
|
||||
version = "0.61"
|
||||
version = "0.58"
|
||||
features = [
|
||||
"Foundation_Collections",
|
||||
"implement",
|
||||
"Foundation_Numerics",
|
||||
"Storage_Search",
|
||||
"Storage_Streams",
|
||||
"Storage",
|
||||
"System_Threading",
|
||||
"UI_StartScreen",
|
||||
"UI_ViewManagement",
|
||||
"Wdk_System_SystemServices",
|
||||
"Win32_Globalization",
|
||||
@@ -640,13 +617,10 @@ features = [
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_System_Com",
|
||||
"Win32_System_Com_StructuredStorage",
|
||||
"Win32_System_Console",
|
||||
"Win32_System_DataExchange",
|
||||
"Win32_System_IO",
|
||||
"Win32_System_LibraryLoader",
|
||||
"Win32_System_Memory",
|
||||
"Win32_System_Ole",
|
||||
"Win32_System_Pipes",
|
||||
"Win32_System_SystemInformation",
|
||||
"Win32_System_SystemServices",
|
||||
"Win32_System_Threading",
|
||||
@@ -663,14 +637,11 @@ features = [
|
||||
# TODO livekit https://github.com/RustAudio/cpal/pull/891
|
||||
[patch.crates-io]
|
||||
cpal = { git = "https://github.com/zed-industries/cpal", rev = "fd8bc2fd39f1f5fdee5a0690656caff9a26d9d50" }
|
||||
notify = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }
|
||||
notify-types = { git = "https://github.com/zed-industries/notify.git", rev = "bbb9ea5ae52b253e095737847e367c30653a2e96" }
|
||||
|
||||
# Makes the workspace hack crate refer to the local one, but only when you're building locally
|
||||
workspace-hack = { path = "tooling/workspace-hack" }
|
||||
real-async-tls = { git = "https://github.com/zed-industries/async-tls", rev = "1e759a4b5e370f87dc15e40756ac4f8815b61d9d", package = "async-tls"}
|
||||
|
||||
[profile.dev]
|
||||
split-debuginfo = "unpacked"
|
||||
debug = "limited"
|
||||
codegen-units = 16
|
||||
|
||||
[profile.dev.package]
|
||||
@@ -736,9 +707,6 @@ debug = "full"
|
||||
lto = false
|
||||
codegen-units = 16
|
||||
|
||||
[workspace.lints.rust]
|
||||
unexpected_cfgs = { level = "allow" }
|
||||
|
||||
[workspace.lints.clippy]
|
||||
dbg_macro = "deny"
|
||||
todo = "deny"
|
||||
@@ -775,9 +743,5 @@ new_ret_no_self = { level = "allow" }
|
||||
should_implement_trait = { level = "allow" }
|
||||
let_underscore_future = "allow"
|
||||
|
||||
# in Rust it can be very tedious to reduce argument count without
|
||||
# running afoul of the borrow checker.
|
||||
too_many_arguments = "allow"
|
||||
|
||||
[workspace.metadata.cargo-machete]
|
||||
ignored = ["bindgen", "cbindgen", "prost_build", "serde", "component", "linkme", "workspace-hack"]
|
||||
ignored = ["bindgen", "cbindgen", "prost_build", "serde"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax = docker/dockerfile:1.2
|
||||
|
||||
FROM rust:1.86-bookworm as builder
|
||||
FROM rust:1.81-bookworm as builder
|
||||
WORKDIR app
|
||||
COPY . .
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="283.6413 127.3453 56 55.9999" width="16px" height="16px">
|
||||
<path d="M 808.592 158.131 C 807.489 158.131 806.592 157.234 806.592 156.131 C 806.592 155.028 807.489 154.131 808.592 154.131 C 809.695 154.131 810.592 155.028 810.592 156.131 C 810.592 157.234 809.695 158.131 808.592 158.131 Z M 776.705 185.039 L 773.457 183.145 L 780.122 178.979 L 779.062 177.283 L 771.505 182.006 L 765.592 178.557 L 765.592 169.666 L 771.147 165.963 L 770.037 164.299 L 764.551 167.956 L 758.592 164.551 L 758.592 159.711 L 765.088 155.999 L 764.096 154.263 L 758.592 157.408 L 758.592 153.711 L 764.592 150.283 L 770.592 153.711 L 770.592 157.565 L 766.077 160.274 L 767.107 161.988 L 771.592 159.297 L 776.077 161.988 L 777.107 160.274 L 772.592 157.565 L 772.592 153.666 L 778.147 149.963 C 778.425 149.777 778.592 149.465 778.592 149.131 L 778.592 142.131 L 776.592 142.131 L 776.592 148.596 L 771.551 151.956 L 765.592 148.551 L 765.592 139.705 L 770.592 136.789 L 770.592 145.131 L 772.592 145.131 L 772.592 135.622 L 776.705 133.223 L 784.592 135.852 L 784.592 164.565 L 770.077 173.274 L 771.107 174.988 L 784.592 166.897 L 784.592 182.41 L 776.705 185.039 Z M 806.592 169.131 C 806.592 170.234 805.695 171.131 804.592 171.131 C 803.489 171.131 802.592 170.234 802.592 169.131 C 802.592 168.028 803.489 167.131 804.592 167.131 C 805.695 167.131 806.592 168.028 806.592 169.131 Z M 796.592 179.131 C 796.592 180.234 795.695 181.131 794.592 181.131 C 793.489 181.131 792.592 180.234 792.592 179.131 C 792.592 178.028 793.489 177.131 794.592 177.131 C 795.695 177.131 796.592 178.028 796.592 179.131 Z M 795.592 139.131 C 795.592 138.028 796.489 137.131 797.592 137.131 C 798.695 137.131 799.592 138.028 799.592 139.131 C 799.592 140.234 798.695 141.131 797.592 141.131 C 796.489 141.131 795.592 140.234 795.592 139.131 Z M 808.592 152.131 C 806.733 152.131 805.181 153.411 804.734 155.131 L 786.592 155.131 L 786.592 150.131 L 797.592 150.131 C 798.145 150.131 798.592 149.683 798.592 149.131 L 798.592 142.989 C 800.312 142.542 801.592 140.989 801.592 139.131 C 801.592 136.925 799.798 135.131 797.592 135.131 C 795.386 135.131 793.592 136.925 793.592 139.131 C 793.592 140.989 794.872 142.542 796.592 142.989 L 796.592 148.131 L 786.592 148.131 L 786.592 135.131 C 786.592 134.7 786.317 134.319 785.908 134.182 L 776.908 131.182 C 776.634 131.092 776.336 131.122 776.088 131.267 L 764.088 138.267 C 763.78 138.446 763.592 138.776 763.592 139.131 L 763.592 148.551 L 757.096 152.263 C 756.784 152.441 756.592 152.772 756.592 153.131 L 756.592 165.131 C 756.592 165.49 756.784 165.821 757.096 165.999 L 763.592 169.711 L 763.592 179.131 C 763.592 179.486 763.78 179.816 764.088 179.995 L 776.088 186.995 C 776.242 187.085 776.417 187.131 776.592 187.131 C 776.698 187.131 776.805 187.114 776.908 187.08 L 785.908 184.08 C 786.317 183.943 786.592 183.562 786.592 183.131 L 786.592 171.131 L 793.592 171.131 L 793.592 175.273 C 791.872 175.72 790.592 177.273 790.592 179.131 C 790.592 181.337 792.386 183.131 794.592 183.131 C 796.798 183.131 798.592 181.337 798.592 179.131 C 798.592 177.273 797.312 175.72 795.592 175.273 L 795.592 170.131 C 795.592 169.579 795.145 169.131 794.592 169.131 L 786.592 169.131 L 786.592 164.131 L 799.092 164.131 L 801.23 166.981 C 800.831 167.603 800.592 168.338 800.592 169.131 C 800.592 171.337 802.386 173.131 804.592 173.131 C 806.798 173.131 808.592 171.337 808.592 169.131 C 808.592 166.925 806.798 165.131 804.592 165.131 C 803.908 165.131 803.274 165.319 802.711 165.623 L 800.392 162.531 C 800.203 162.279 799.906 162.131 799.592 162.131 L 786.592 162.131 L 786.592 157.131 L 804.734 157.131 C 805.181 158.851 806.733 160.131 808.592 160.131 C 810.798 160.131 812.592 158.337 812.592 156.131 C 812.592 153.925 810.798 152.131 808.592 152.131 Z" fill-rule="evenodd" fill-opacity="1" style="" id="object-0" transform="matrix(1, 0, 0, 1, -472.9506530761719, -3.7858259677886963)"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -1,10 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5871 5.40624C12.8514 5.14195 13 4.78346 13 4.40965C13 4.03583 12.8516 3.67731 12.5873 3.41295C12.323 3.14859 11.9645 3.00005 11.5907 3C11.2169 2.99995 10.8584 3.14841 10.594 3.4127L3.92098 10.0874C3.80488 10.2031 3.71903 10.3456 3.67097 10.5024L3.01047 12.6784C2.99754 12.7217 2.99657 12.7676 3.00764 12.8113C3.01872 12.8551 3.04143 12.895 3.07337 12.9269C3.1053 12.9588 3.14528 12.9815 3.18905 12.9925C3.23282 13.0035 3.27875 13.0024 3.32197 12.9894L5.49849 12.3294C5.65508 12.2818 5.79758 12.1964 5.91349 12.0809L12.5871 5.40624Z" stroke="black" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 4L12 6" stroke="black" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.38818 3.53598V2.53598" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.56982 12.6995L9.56982 13.6995" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M2.38818 6.53598H3.38818" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.5698 9.69949L12.5698 9.69949" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M4.38818 4.53598L3.38818 3.53598" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11.5698 11.6995L12.5698 12.6995" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-down-right-icon lucide-arrow-down-right"><path d="m7 7 10 10"/><path d="M17 7v10H7"/></svg>
|
||||
|
Before Width: | Height: | Size: 300 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-right-left"><path d="m16 3 4 4-4 4"/><path d="M20 7H4"/><path d="m8 21-4-4 4-4"/><path d="M4 17h16"/></svg>
|
||||
|
Before Width: | Height: | Size: 316 B |
@@ -1 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-right-icon lucide-arrow-up-right"><path d="M7 7h10v10"/><path d="M7 17 17 7"/></svg>
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 2H6.5C6.5 1.86739 6.44732 1.74021 6.35355 1.64645C6.25979 1.55268 6.13261 1.5 6 1.5V2ZM2 1.5C1.72386 1.5 1.5 1.72386 1.5 2C1.5 2.27614 1.72386 2.5 2 2.5L2 1.5ZM5.5 6C5.5 6.27614 5.72386 6.5 6 6.5C6.27614 6.5 6.5 6.27614 6.5 6H5.5ZM1.64645 5.64645C1.45118 5.84171 1.45118 6.15829 1.64645 6.35355C1.84171 6.54882 2.15829 6.54882 2.35355 6.35355L1.64645 5.64645ZM6 1.5H2L2 2.5H6V1.5ZM5.5 2V6H6.5V2H5.5ZM5.64645 1.64645L1.64645 5.64645L2.35355 6.35355L6.35355 2.35355L5.64645 1.64645Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 608 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.4 2.6H5.75C5.75 2.50717 5.71312 2.41815 5.64749 2.35251C5.58185 2.28688 5.49283 2.25 5.4 2.25V2.6ZM2.6 2.25C2.4067 2.25 2.25 2.4067 2.25 2.6C2.25 2.7933 2.4067 2.95 2.6 2.95V2.25ZM5.05 5.4C5.05 5.5933 5.2067 5.75 5.4 5.75C5.5933 5.75 5.75 5.5933 5.75 5.4H5.05ZM2.35252 5.15251C2.21583 5.2892 2.21583 5.5108 2.35252 5.64748C2.4892 5.78417 2.7108 5.78417 2.84749 5.64748L2.35252 5.15251ZM5.4 2.25H2.6V2.95H5.4V2.25ZM5.05 2.6V5.4H5.75V2.6H5.05ZM5.15252 2.35251L2.35252 5.15251L2.84749 5.64748L5.64749 2.84748L5.15252 2.35251Z" fill="black"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 650 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-brain"><path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z"/><path d="M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z"/><path d="M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4"/><path d="M17.599 6.5a3 3 0 0 0 .399-1.375"/><path d="M6.003 5.125A3 3 0 0 0 6.401 6.5"/><path d="M3.477 10.896a4 4 0 0 1 .585-.396"/><path d="M19.938 10.5a4 4 0 0 1 .585.396"/><path d="M6 18a4 4 0 0 1-1.967-.516"/><path d="M19.967 17.484A4 4 0 0 1 18 18"/></svg>
|
||||
|
Before Width: | Height: | Size: 718 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bug-off-icon lucide-bug-off"><path d="M15 7.13V6a3 3 0 0 0-5.14-2.1L8 2"/><path d="M14.12 3.88 16 2"/><path d="M22 13h-4v-2a4 4 0 0 0-4-4h-1.3"/><path d="M20.97 5c0 2.1-1.6 3.8-3.5 4"/><path d="m2 2 20 20"/><path d="M7.7 7.7A4 4 0 0 0 6 11v3a6 6 0 0 0 11.13 3.13"/><path d="M12 20v-8"/><path d="M6 13H2"/><path d="M3 21c0-2.1 1.7-3.9 3.8-4"/></svg>
|
||||
|
Before Width: | Height: | Size: 551 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-check-icon lucide-check-check"><path d="M18 6 7 17l-5-5"/><path d="m22 10-7.5 7.5L13 16"/></svg>
|
||||
|
Before Width: | Height: | Size: 305 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-off-icon lucide-circle-off"><path d="m2 2 20 20"/><path d="M8.35 2.69A10 10 0 0 1 21.3 15.65"/><path d="M19.08 19.08A10 10 0 1 1 4.92 4.92"/></svg>
|
||||
|
Before Width: | Height: | Size: 357 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-cloud"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 279 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-cog"><path d="M12 20a8 8 0 1 0 0-16 8 8 0 0 0 0 16Z"/><path d="M12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z"/><path d="M12 2v2"/><path d="M12 22v-2"/><path d="m17 20.66-1-1.73"/><path d="M11 10.27 7 3.34"/><path d="m20.66 17-1.73-1"/><path d="m3.34 7 1.73 1"/><path d="M14 12h8"/><path d="M2 12h2"/><path d="m20.66 7-1.73 1"/><path d="m3.34 17 1.73-1"/><path d="m17 3.34-1 1.73"/><path d="m11 13.73-4 6.93"/></svg>
|
||||
|
Before Width: | Height: | Size: 608 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle"><circle cx="12" cy="12" r="10"/></svg>
|
||||
|
Before Width: | Height: | Size: 249 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-circle"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 267 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.5 8.5L7.5 11.5M7.5 11.5L4.5 8.5M7.5 11.5L7.5 5.5" stroke="black" stroke-linecap="square"/>
|
||||
<path d="M5 3.5L10 3.5" stroke="black"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 248 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.5 6.5L7.5 3.5M7.5 3.5L10.5 6.5M7.5 3.5V9.5" stroke="black" stroke-linecap="square"/>
|
||||
<path d="M5 11.5H10" stroke="black"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 238 B |
@@ -1,5 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.0001 1.33334H4.00008C3.64646 1.33334 3.30732 1.47382 3.05727 1.72387C2.80722 1.97392 2.66675 2.31305 2.66675 2.66668V13.3333C2.66675 13.687 2.80722 14.0261 3.05727 14.2762C3.30732 14.5262 3.64646 14.6667 4.00008 14.6667H12.0001C12.3537 14.6667 12.6928 14.5262 12.9429 14.2762C13.1929 14.0261 13.3334 13.687 13.3334 13.3333V4.66668L10.0001 1.33334Z" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 8H10" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M8 10V6" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 762 B |
@@ -1,5 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.0001 1.33334H4.00008C3.64646 1.33334 3.30732 1.47382 3.05727 1.72387C2.80722 1.97392 2.66675 2.31305 2.66675 2.66668V13.3333C2.66675 13.687 2.80722 14.0261 3.05727 14.2762C3.30732 14.5262 3.64646 14.6667 4.00008 14.6667H12.0001C12.3537 14.6667 12.6928 14.5262 12.9429 14.2762C13.1929 14.0261 13.3334 13.687 13.3334 13.3333V4.66668L10.0001 1.33334Z" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.66659 6.5L6.33325 9.83333" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.33325 6.5L9.66659 9.83333" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 804 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.36197 1.67985C5.3748 1.41534 4.36011 2.00117 4.0956 2.98834L2.17985 10.138C1.91534 11.1252 2.50117 12.1399 3.48833 12.4044L10.638 14.3202C11.6252 14.5847 12.6399 13.9988 12.9044 13.0117L14.8202 5.86197C15.0847 4.8748 14.4988 3.86012 13.5117 3.59561L6.36197 1.67985ZM10.0457 4.58266C9.77896 4.51119 9.50479 4.66948 9.43332 4.93621L8.76235 7.44028C8.69088 7.70701 8.84917 7.98118 9.11591 8.05265L11.62 8.72362C11.8867 8.79509 12.1609 8.6368 12.2324 8.37006L12.9033 5.86599C12.9748 5.59926 12.8165 5.32509 12.5498 5.25362L10.0457 4.58266Z" fill="black"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 707 B |
@@ -1 +0,0 @@
|
||||
<svg width="16" height="16" fill="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><g style="fill:#000;fill-opacity:1" fill="#180c25"><path d="m-116.1-101.4-28.9-28.9a6.7 6.7 0 0 1-1.8-4.7v-41.2c0-2.4-2.4-4.8-4.8-4.8h-9.6a5.2 5.2 0 0 0-4.8 4.8v48c0 2.5 1 5 2.7 6.8l33.6 33.6a9.6 9.6 0 0 0 6.8 2.8h4.8c2.7 0 4.8-2.2 4.8-4.8v-4.8c0-2.5-1-5-2.8-6.8zM-79.6-176.2c0-2.4-2.4-4.8-4.8-4.8h-9.7a5.2 5.2 0 0 0-4.7 4.8v41.2c0 1.8-.8 3.5-2 4.7l-9.6 9.7a9.5 9.5 0 0 0-2.8 6.8v4.8c0 2.6 2.1 4.7 4.8 4.7h4.8c2.4 0 4.9-.9 6.7-2.8l14.4-14.3a9.6 9.6 0 0 0 2.8-6.8v-48z" style="fill:#000;fill-opacity:1;stroke-width:.255894" transform="translate(21.6 22.7) scale(.11067)"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 677 B |
@@ -1,7 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.5 13L1.5 5H11.5L6.5 13Z" fill="black"/>
|
||||
<path d="M14 9H9L11.5 5L14 9Z" fill="black" fill-opacity="0.75"/>
|
||||
<path d="M9 9L14 9L11.5 13L9 9Z" fill="black" fill-opacity="0.65"/>
|
||||
<path d="M14 5L15.25 7L12.75 7L14 5Z" fill="black" fill-opacity="0.5"/>
|
||||
<path d="M14 9L12.75 7H15.25L14 9Z" fill="black" fill-opacity="0.55"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 432 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-forward-icon lucide-forward"><polyline points="15 17 20 12 15 7"/><path d="M4 18v-2a4 4 0 0 1 4-4h12"/></svg>
|
||||
|
Before Width: | Height: | Size: 312 B |
@@ -1,6 +0,0 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 3.25C4.02614 3.25 4.25 3.02614 4.25 2.75C4.25 2.47386 4.02614 2.25 3.75 2.25C3.47386 2.25 3.25 2.47386 3.25 2.75C3.25 3.02614 3.47386 3.25 3.75 3.25ZM3.75 4.25C4.57843 4.25 5.25 3.57843 5.25 2.75C5.25 1.92157 4.57843 1.25 3.75 1.25C2.92157 1.25 2.25 1.92157 2.25 2.75C2.25 3.57843 2.92157 4.25 3.75 4.25Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.25 3.25C8.52614 3.25 8.75 3.02614 8.75 2.75C8.75 2.47386 8.52614 2.25 8.25 2.25C7.97386 2.25 7.75 2.47386 7.75 2.75C7.75 3.02614 7.97386 3.25 8.25 3.25ZM8.25 4.25C9.07843 4.25 9.75 3.57843 9.75 2.75C9.75 1.92157 9.07843 1.25 8.25 1.25C7.42157 1.25 6.75 1.92157 6.75 2.75C6.75 3.57843 7.42157 4.25 8.25 4.25Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 9.75C4.02614 9.75 4.25 9.52614 4.25 9.25C4.25 8.97386 4.02614 8.75 3.75 8.75C3.47386 8.75 3.25 8.97386 3.25 9.25C3.25 9.52614 3.47386 9.75 3.75 9.75ZM3.75 10.75C4.57843 10.75 5.25 10.0784 5.25 9.25C5.25 8.42157 4.57843 7.75 3.75 7.75C2.92157 7.75 2.25 8.42157 2.25 9.25C2.25 10.0784 2.92157 10.75 3.75 10.75Z" fill="black"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.25 3.75H4.25V5.59609C4.67823 5.35824 5.24991 5.25 6 5.25H7.25017C7.5262 5.25 7.75 5.02625 7.75 4.75V3.75H8.75V4.75C8.75 5.57832 8.07871 6.25 7.25017 6.25H6C5.14559 6.25 4.77639 6.41132 4.59684 6.56615C4.42571 6.71373 4.33877 6.92604 4.25 7.30651V8.25H3.25V3.75Z" fill="black"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,40 +0,0 @@
|
||||
<svg width="400" height="120" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="tilePattern" width="124" height="24" patternUnits="userSpaceOnUse">
|
||||
<svg width="124" height="24" viewBox="0 0 124 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.2">
|
||||
<path d="M16.666 12.0013L11.9993 16.668L7.33268 12.0013" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 7.33464L12 16.668" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29 8.33464C29.3682 8.33464 29.6667 8.03616 29.6667 7.66797C29.6667 7.29978 29.3682 7.0013 29 7.0013C28.6318 7.0013 28.3333 7.29978 28.3333 7.66797C28.3333 8.03616 28.6318 8.33464 29 8.33464ZM29 9.66797C30.1046 9.66797 31 8.77254 31 7.66797C31 6.5634 30.1046 5.66797 29 5.66797C27.8954 5.66797 27 6.5634 27 7.66797C27 8.77254 27.8954 9.66797 29 9.66797Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M35 8.33464C35.3682 8.33464 35.6667 8.03616 35.6667 7.66797C35.6667 7.29978 35.3682 7.0013 35 7.0013C34.6318 7.0013 34.3333 7.29978 34.3333 7.66797C34.3333 8.03616 34.6318 8.33464 35 8.33464ZM35 9.66797C36.1046 9.66797 37 8.77254 37 7.66797C37 6.5634 36.1046 5.66797 35 5.66797C33.8954 5.66797 33 6.5634 33 7.66797C33 8.77254 33.8954 9.66797 35 9.66797Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M29 16.9987C29.3682 16.9987 29.6667 16.7002 29.6667 16.332C29.6667 15.9638 29.3682 15.6654 29 15.6654C28.6318 15.6654 28.3333 15.9638 28.3333 16.332C28.3333 16.7002 28.6318 16.9987 29 16.9987ZM29 18.332C30.1046 18.332 31 17.4366 31 16.332C31 15.2275 30.1046 14.332 29 14.332C27.8954 14.332 27 15.2275 27 16.332C27 17.4366 27.8954 18.332 29 18.332Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M28.334 9H29.6673V11.4615C30.2383 11.1443 31.0005 11 32.0007 11H33.6675C34.0356 11 34.334 10.7017 34.334 10.3333V9H35.6673V10.3333C35.6673 11.4378 34.7723 12.3333 33.6675 12.3333H32.0007C30.8614 12.3333 30.3692 12.5484 30.1298 12.7549C29.9016 12.9516 29.7857 13.2347 29.6673 13.742V15H28.334V9Z" fill="white"/>
|
||||
<path d="M48.668 8.66406H55.3346V15.3307" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M48.668 15.3307L55.3346 8.66406" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M76.5871 9.40624C76.8514 9.14195 77 8.78346 77 8.40965C77 8.03583 76.8516 7.67731 76.5873 7.41295C76.323 7.14859 75.9645 7.00005 75.5907 7C75.2169 6.99995 74.8584 7.14841 74.594 7.4127L67.921 14.0874C67.8049 14.2031 67.719 14.3456 67.671 14.5024L67.0105 16.6784C66.9975 16.7217 66.9966 16.7676 67.0076 16.8113C67.0187 16.8551 67.0414 16.895 67.0734 16.9269C67.1053 16.9588 67.1453 16.9815 67.1891 16.9925C67.2328 17.0035 67.2788 17.0024 67.322 16.9894L69.4985 16.3294C69.6551 16.2818 69.7976 16.1964 69.9135 16.0809L76.5871 9.40624Z" stroke="white" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M74 8L76 10" stroke="white" stroke-width="1.33" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M70.3877 7.53516V6.53516" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M73.5693 16.6992V17.6992" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M66.3877 10.5352H67.3877" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M77.5693 13.6992H76.5693" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M68.3877 8.53516L67.3877 7.53516" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M75.5693 15.6992L76.5693 16.6992" stroke="white" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M87.334 11.9987L92.0007 7.33203L96.6673 11.9987" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M92 16.6654V7.33203" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M117 12C117 10.6739 116.473 9.40215 115.536 8.46447C114.598 7.52678 113.326 7 112 7C110.602 7.00526 109.261 7.55068 108.256 8.52222L107 9.77778" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M107 7V9.77778H109.778" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M107 12C107 13.3261 107.527 14.5979 108.464 15.5355C109.402 16.4732 110.674 17 112 17C113.398 16.9947 114.739 16.4493 115.744 15.4778L117 14.2222" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M114.223 14.2188H117V16.9965" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
</pattern>
|
||||
<linearGradient id="fade" y2="1" x2="0">
|
||||
<stop offset="0" stop-color="white" stop-opacity=".52"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<mask id="fadeMask" maskContentUnits="objectBoundingBox">
|
||||
<rect width="1" height="1" fill="url(#fade)"/>
|
||||
</mask>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#tilePattern)" mask="url(#fadeMask)"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 5.4 KiB |
@@ -1,5 +1,12 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 14C11.3137 14 14 11.3137 14 8C14 4.68629 11.3137 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14Z" stroke="black" stroke-width="1.5"/>
|
||||
<path d="M7 11H8M8 11H9M8 11V8.1C8 8.04477 7.95523 8 7.9 8H7" stroke="black" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<path d="M8 6.5C8.55228 6.5 9 6.05228 9 5.5C9 4.94772 8.55228 4.5 8 4.5C7.44772 4.5 7 4.94772 7 5.5C7 6.05228 7.44772 6.5 8 6.5Z" fill="black"/>
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2131_1193)">
|
||||
<circle cx="7" cy="7" r="6" stroke="black" stroke-width="1.5"/>
|
||||
<path d="M6 10H7M8 10H7M7 10V7.1C7 7.04477 6.95523 7 6.9 7H6" stroke="black" stroke-width="1.5" stroke-linecap="round"/>
|
||||
<circle cx="7" cy="4.5" r="1" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2131_1193">
|
||||
<rect width="14" height="14" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 524 B After Width: | Height: | Size: 479 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.1331 11.3776C10.2754 10.6665 10.1331 9.78593 11.1998 8.53327C11.82 7.80489 12.2664 6.96894 12.2664 6.04456C12.2664 4.91305 11.8169 3.82788 11.0168 3.02778C10.2167 2.22769 9.13152 1.7782 8.00001 1.7782C6.8685 1.7782 5.78334 2.22769 4.98324 3.02778C4.18314 3.82788 3.73364 4.91305 3.73364 6.04456C3.73364 6.75562 3.87586 7.6089 4.80024 8.53327C5.86683 9.80679 5.72462 10.6665 5.86683 11.3776M10.1331 11.3776V12.8821C10.1331 13.622 9.53341 14.2218 8.79353 14.2218H7.2065C6.46662 14.2218 5.86683 13.622 5.86683 12.8821V11.3776M10.1331 11.3776H5.86683" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 751 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clipboard"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-circle-more"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/><path d="M8 12h.01"/><path d="M12 12h.01"/><path d="M16 12h.01"/></svg>
|
||||
|
Before Width: | Height: | Size: 358 B After Width: | Height: | Size: 337 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-power-icon lucide-power"><path d="M12 2v10"/><path d="M18.4 6.6a9 9 0 1 1-12.77.04"/></svg>
|
||||
|
Before Width: | Height: | Size: 294 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.09666 3.02263C3.0567 3.00312 3.01178 2.9961 2.96778 3.0025C2.92377 3.00889 2.88271 3.02839 2.84995 3.05847C2.8172 3.08854 2.79426 3.12778 2.78413 3.17108C2.77401 3.21439 2.77716 3.25973 2.79319 3.30121L4.05638 6.69C4.13088 6.89005 4.13088 7.11022 4.05638 7.31027L2.79363 10.6991C2.77769 10.7405 2.77457 10.7858 2.78469 10.829C2.79481 10.8722 2.8177 10.9114 2.85038 10.9414C2.88306 10.9715 2.92402 10.991 2.96794 10.9975C3.01186 11.0039 3.05671 10.997 3.09666 10.9776L11.0943 7.20097C11.1324 7.18297 11.1645 7.15455 11.187 7.11899C11.2096 7.08344 11.2215 7.04222 11.2215 7.00014C11.2215 6.95805 11.2096 6.91683 11.187 6.88128C11.1645 6.84573 11.1324 6.8173 11.0943 6.79931L3.09666 3.02263Z" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M4.11255 7.00014H11.2216" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1014 B |
@@ -1,6 +1,6 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 4H8" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 10L11 10" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="4" cy="10" r="1.875" stroke="black" stroke-width="1.5"/>
|
||||
<circle cx="10" cy="4" r="1.875" stroke="black" stroke-width="1.5"/>
|
||||
<path d="M3 4H8" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 10L11 10" stroke="black" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<circle cx="4" cy="10" r="1.875" stroke="black" stroke-width="1.75"/>
|
||||
<circle cx="10" cy="4" r="1.875" stroke="black" stroke-width="1.75"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 450 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 9.8V4.2C4 4.08954 4.08954 4 4.2 4H9.8C9.91046 4 10 4.08954 10 4.2V9.8C10 9.91046 9.91046 10 9.8 10H4.2C4.08954 10 4 9.91046 4 9.8Z" fill="#C56757" stroke="#C56757" stroke-width="1.25" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 325 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-user-round-pen-icon lucide-user-round-pen"><path d="M2 21a8 8 0 0 1 10.821-7.487"/><path d="M21.378 16.626a1 1 0 0 0-3.004-3.004l-4.01 4.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"/><circle cx="10" cy="8" r="5"/></svg>
|
||||
|
Before Width: | Height: | Size: 461 B |
5
assets/icons/zed_assistant_2.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.27772 1.38585L4.39187 4.07909C4.34653 4.21692 4.26946 4.34219 4.16685 4.44479C4.06425 4.5474 3.93898 4.62447 3.80115 4.66981L1.10791 5.55566L3.80115 6.44151C3.93898 6.48685 4.06425 6.56392 4.16685 6.66653C4.26946 6.76913 4.34653 6.8944 4.39187 7.03223L5.27772 9.72547L6.16357 7.03223C6.20891 6.8944 6.28598 6.76913 6.38859 6.66653C6.49119 6.56392 6.61646 6.48685 6.7543 6.44151L9.44753 5.55566L6.7543 4.66981C6.61646 4.62447 6.49119 4.5474 6.38859 4.44479C6.28598 4.34219 6.20891 4.21692 6.16357 4.07909L5.27772 1.38585Z" fill="black" fill-opacity="0.15" stroke="black" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M8.35938 12.3555C8.35938 12.0664 8.52734 11.8086 9.00781 11.3594L10.2031 10.2344C10.6094 9.85156 10.7891 9.60156 10.7891 9.34375C10.7891 9.05469 10.5781 8.85938 10.2734 8.85938C10.0391 8.85938 9.87109 8.95312 9.66406 9.21094C9.42578 9.50781 9.25391 9.60938 8.99219 9.60938C8.61719 9.60938 8.35156 9.35938 8.35156 9.01172C8.35156 8.25 9.26953 7.57812 10.3594 7.57812C11.4961 7.57812 12.3438 8.26172 12.3438 9.17969C12.3438 9.75391 12.0391 10.3008 11.418 10.8516L10.4961 11.6719V11.7344H11.8047C12.2578 11.7344 12.5391 11.9766 12.5391 12.3711C12.5391 12.7656 12.2656 13 11.8047 13H9.08203C8.65234 13 8.35938 12.7383 8.35938 12.3555Z" fill="black"/>
|
||||
<path d="M11.0834 1.38585V3.71918M9.91675 2.55248H12.2501" stroke="black" stroke-opacity="0.75" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -1,4 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.6" d="M7.5 8.9V11C5.43097 11 4.56903 11 2.5 11V10.4L7.5 5.6V5H2.5V7.1" stroke="black" stroke-width="1.5"/>
|
||||
<path d="M14 8L10 12M14 12L10 8" stroke="black" stroke-width="1.5"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 296 B |
@@ -10,8 +10,8 @@
|
||||
"pagedown": "menu::SelectLast",
|
||||
"ctrl-n": "menu::SelectNext",
|
||||
"tab": "menu::SelectNext",
|
||||
"ctrl-p": "menu::SelectPrevious",
|
||||
"shift-tab": "menu::SelectPrevious",
|
||||
"ctrl-p": "menu::SelectPrev",
|
||||
"shift-tab": "menu::SelectPrev",
|
||||
"enter": "menu::Confirm",
|
||||
"ctrl-enter": "menu::SecondaryConfirm",
|
||||
"ctrl-escape": "menu::Cancel",
|
||||
@@ -30,13 +30,6 @@
|
||||
"ctrl-0": ["zed::ResetBufferFontSize", { "persist": false }],
|
||||
"ctrl-,": "zed::OpenSettings",
|
||||
"ctrl-q": "zed::Quit",
|
||||
"f4": "debugger::Start",
|
||||
"f5": "debugger::Continue",
|
||||
"shift-f5": "debugger::Stop",
|
||||
"f6": "debugger::Pause",
|
||||
"f7": "debugger::StepOver",
|
||||
"cmd-f11": "debugger::StepInto",
|
||||
"shift-f11": "debugger::StepOut",
|
||||
"f11": "zed::ToggleFullScreen",
|
||||
"ctrl-alt-z": "edit_prediction::RateCompletions",
|
||||
"ctrl-shift-i": "edit_prediction::ToggleMenu"
|
||||
@@ -45,17 +38,15 @@
|
||||
{
|
||||
"context": "Picker || menu",
|
||||
"bindings": {
|
||||
"up": "menu::SelectPrevious",
|
||||
"up": "menu::SelectPrev",
|
||||
"down": "menu::SelectNext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Prompt",
|
||||
"bindings": {
|
||||
"left": "menu::SelectPrevious",
|
||||
"right": "menu::SelectNext",
|
||||
"h": "menu::SelectPrevious",
|
||||
"l": "menu::SelectNext"
|
||||
"left": "menu::SelectPrev",
|
||||
"right": "menu::SelectNext"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -66,7 +57,7 @@
|
||||
"backspace": "editor::Backspace",
|
||||
"delete": "editor::Delete",
|
||||
"tab": "editor::Tab",
|
||||
"shift-tab": "editor::Backtab",
|
||||
"shift-tab": "editor::TabPrev",
|
||||
"ctrl-k": "editor::CutToEndOfLine",
|
||||
// "ctrl-t": "editor::Transpose",
|
||||
"ctrl-k ctrl-q": "editor::Rewrap",
|
||||
@@ -93,12 +84,12 @@
|
||||
"pageup": "editor::MovePageUp",
|
||||
"alt-pageup": "editor::PageUp",
|
||||
"shift-pageup": "editor::SelectPageUp",
|
||||
"home": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
"home": "editor::MoveToBeginningOfLine",
|
||||
"down": "editor::MoveDown",
|
||||
"pagedown": "editor::MovePageDown",
|
||||
"alt-pagedown": "editor::PageDown",
|
||||
"shift-pagedown": "editor::SelectPageDown",
|
||||
"end": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
"end": "editor::MoveToEndOfLine",
|
||||
"left": "editor::MoveLeft",
|
||||
"right": "editor::MoveRight",
|
||||
"ctrl-left": "editor::MoveToPreviousWordStart",
|
||||
@@ -116,41 +107,23 @@
|
||||
"ctrl-a": "editor::SelectAll",
|
||||
"ctrl-l": "editor::SelectLine",
|
||||
"ctrl-shift-i": "editor::Format",
|
||||
"alt-shift-o": "editor::OrganizeImports",
|
||||
// "cmd-shift-left": ["editor::SelectToBeginningOfLine", {"stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
// "ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
// "cmd-shift-left": ["editor::SelectToBeginningOfLine", {"stop_at_soft_wraps": true }],
|
||||
// "ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
|
||||
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
|
||||
// "cmd-shift-right": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
// "ctrl-shift-e": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
// "alt-v": ["editor::MovePageUp", { "center_cursor": true }],
|
||||
"ctrl-alt-space": "editor::ShowCharacterPalette",
|
||||
"ctrl-;": "editor::ToggleLineNumbers",
|
||||
"ctrl-k ctrl-r": "editor::RevertSelectedHunks",
|
||||
"ctrl-'": "editor::ToggleSelectedDiffHunks",
|
||||
"ctrl-\"": "editor::ExpandAllDiffHunks",
|
||||
"ctrl-\"": "editor::ExpandAllHunkDiffs",
|
||||
"ctrl-i": "editor::ShowSignatureHelp",
|
||||
"alt-g b": "editor::ToggleGitBlame",
|
||||
"menu": "editor::OpenContextMenu",
|
||||
"shift-f10": "editor::OpenContextMenu",
|
||||
"ctrl-shift-e": "editor::ToggleEditPrediction",
|
||||
"f9": "editor::ToggleBreakpoint",
|
||||
"shift-f9": "editor::EditLogBreakpoint"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && !agent_diff",
|
||||
"bindings": {
|
||||
"ctrl-k ctrl-r": "git::Restore",
|
||||
"ctrl-alt-y": "git::ToggleStaged",
|
||||
"alt-y": "git::StageAndNext",
|
||||
"alt-shift-y": "git::UnstageAndNext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentDiff",
|
||||
"bindings": {
|
||||
"ctrl-y": "agent::Keep",
|
||||
"ctrl-n": "agent::Reject"
|
||||
"ctrl-shift-e": "editor::ToggleEditPrediction"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -207,13 +180,12 @@
|
||||
"ctrl-k c": "assistant::CopyCode",
|
||||
"ctrl-shift-e": "project_panel::ToggleFocus",
|
||||
"ctrl-g": "search::SelectNextMatch",
|
||||
"ctrl-shift-g": "search::SelectPreviousMatch",
|
||||
"ctrl-shift-g": "search::SelectPrevMatch",
|
||||
"ctrl-alt-/": "assistant::ToggleModelSelector",
|
||||
"ctrl-k h": "assistant::DeployHistory",
|
||||
"ctrl-k l": "assistant::OpenPromptLibrary",
|
||||
"new": "assistant::NewChat",
|
||||
"ctrl-t": "assistant::NewChat",
|
||||
"ctrl-n": "assistant::NewChat"
|
||||
"ctrl-k l": "assistant::DeployPromptLibrary",
|
||||
"new": "assistant::NewContext",
|
||||
"ctrl-n": "assistant::NewContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -230,7 +202,7 @@
|
||||
"escape": "buffer_search::Dismiss",
|
||||
"tab": "buffer_search::FocusEditor",
|
||||
"enter": "search::SelectNextMatch",
|
||||
"shift-enter": "search::SelectPreviousMatch",
|
||||
"shift-enter": "search::SelectPrevMatch",
|
||||
"alt-enter": "search::SelectAllMatches",
|
||||
"find": "search::FocusSearch",
|
||||
"ctrl-f": "search::FocusSearch",
|
||||
@@ -299,7 +271,7 @@
|
||||
"alt-8": ["pane::ActivateItem", 7],
|
||||
"alt-9": ["pane::ActivateItem", 8],
|
||||
"alt-0": "pane::ActivateLastItem",
|
||||
"ctrl-pageup": "pane::ActivatePreviousItem",
|
||||
"ctrl-pageup": "pane::ActivatePrevItem",
|
||||
"ctrl-pagedown": "pane::ActivateNextItem",
|
||||
"ctrl-shift-pageup": "pane::SwapItemLeft",
|
||||
"ctrl-shift-pagedown": "pane::SwapItemRight",
|
||||
@@ -311,15 +283,14 @@
|
||||
"ctrl-k t": ["pane::CloseItemsToTheRight", { "close_pinned": false }],
|
||||
"ctrl-k u": ["pane::CloseCleanItems", { "close_pinned": false }],
|
||||
"ctrl-k w": ["pane::CloseAllItems", { "close_pinned": false }],
|
||||
"ctrl-k ctrl-w": "workspace::CloseAllItemsAndPanes",
|
||||
"back": "pane::GoBack",
|
||||
"ctrl-alt--": "pane::GoBack",
|
||||
"ctrl-alt-_": "pane::GoForward",
|
||||
"forward": "pane::GoForward",
|
||||
"ctrl-alt-g": "search::SelectNextMatch",
|
||||
"f3": "search::SelectNextMatch",
|
||||
"ctrl-alt-shift-g": "search::SelectPreviousMatch",
|
||||
"shift-f3": "search::SelectPreviousMatch",
|
||||
"ctrl-alt-shift-g": "search::SelectPrevMatch",
|
||||
"shift-f3": "search::SelectPrevMatch",
|
||||
"shift-find": "project_search::ToggleFocus",
|
||||
"ctrl-shift-f": "project_search::ToggleFocus",
|
||||
"ctrl-alt-shift-h": "search::ToggleReplace",
|
||||
@@ -362,7 +333,7 @@
|
||||
"ctrl-u": "editor::UndoSelection",
|
||||
"ctrl-shift-u": "editor::RedoSelection",
|
||||
"f8": "editor::GoToDiagnostic",
|
||||
"shift-f8": "editor::GoToPreviousDiagnostic",
|
||||
"shift-f8": "editor::GoToPrevDiagnostic",
|
||||
"f2": "editor::Rename",
|
||||
"f12": "editor::GoToDefinition",
|
||||
"alt-f12": "editor::GoToDefinitionSplit",
|
||||
@@ -372,9 +343,9 @@
|
||||
"alt-ctrl-f12": "editor::GoToTypeDefinitionSplit",
|
||||
"alt-shift-f12": "editor::FindAllReferences",
|
||||
"ctrl-m": "editor::MoveToEnclosingBracket",
|
||||
"ctrl-|": "editor::MoveToEnclosingBracket",
|
||||
"ctrl-{": "editor::Fold",
|
||||
"ctrl-}": "editor::UnfoldLines",
|
||||
"ctrl-shift-\\": "editor::MoveToEnclosingBracket",
|
||||
"ctrl-shift-[": "editor::Fold",
|
||||
"ctrl-shift-]": "editor::UnfoldLines",
|
||||
"ctrl-k ctrl-l": "editor::ToggleFold",
|
||||
"ctrl-k ctrl-[": "editor::FoldRecursive",
|
||||
"ctrl-k ctrl-]": "editor::UnfoldRecursive",
|
||||
@@ -390,16 +361,13 @@
|
||||
"ctrl-k ctrl-0": "editor::FoldAll",
|
||||
"ctrl-k ctrl-j": "editor::UnfoldAll",
|
||||
"ctrl-space": "editor::ShowCompletions",
|
||||
"ctrl-shift-space": "editor::ShowWordCompletions",
|
||||
"ctrl-.": "editor::ToggleCodeActions",
|
||||
"ctrl-k r": "editor::RevealInFileManager",
|
||||
"ctrl-k p": "editor::CopyPath",
|
||||
"ctrl-\\": "pane::SplitRight",
|
||||
"ctrl-k v": "markdown::OpenPreviewToTheSide",
|
||||
"ctrl-shift-v": "markdown::OpenPreview",
|
||||
"ctrl-alt-shift-c": "editor::DisplayCursorNames",
|
||||
"alt-.": "editor::GoToHunk",
|
||||
"alt-,": "editor::GoToPreviousHunk"
|
||||
"ctrl-alt-shift-c": "editor::DisplayCursorNames"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -419,7 +387,6 @@
|
||||
"alt-shift-open": "projects::OpenRemote",
|
||||
"alt-ctrl-shift-o": "projects::OpenRemote",
|
||||
"alt-ctrl-shift-b": "branches::OpenRecent",
|
||||
"alt-shift-enter": "toast::RunAction",
|
||||
"ctrl-~": "workspace::NewTerminal",
|
||||
"save": "workspace::Save",
|
||||
"ctrl-s": "workspace::Save",
|
||||
@@ -482,8 +449,6 @@
|
||||
"alt-shift-r": ["task::Spawn", { "reveal_target": "center" }]
|
||||
// also possible to spawn tasks by name:
|
||||
// "foo-bar": ["task::Spawn", { "task_name": "MyTask", "reveal_target": "dock" }]
|
||||
// or by tag:
|
||||
// "foo-bar": ["task::Spawn", { "task_tag": "MyTag" }],
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -504,7 +469,9 @@
|
||||
"ctrl-alt-delete": "editor::DeleteToNextSubwordEnd",
|
||||
"ctrl-alt-d": "editor::DeleteToNextSubwordEnd",
|
||||
"ctrl-alt-left": "editor::MoveToPreviousSubwordStart",
|
||||
// "ctrl-alt-b": "editor::MoveToPreviousSubwordStart",
|
||||
"ctrl-alt-right": "editor::MoveToNextSubwordEnd",
|
||||
"ctrl-alt-f": "editor::MoveToNextSubwordEnd",
|
||||
"ctrl-alt-shift-left": "editor::SelectToPreviousSubwordStart",
|
||||
"ctrl-alt-shift-b": "editor::SelectToPreviousSubwordStart",
|
||||
"ctrl-alt-shift-right": "editor::SelectToNextSubwordEnd",
|
||||
@@ -532,7 +499,6 @@
|
||||
"context": "Editor && showing_completions",
|
||||
"bindings": {
|
||||
"enter": "editor::ConfirmCompletion",
|
||||
"shift-enter": "editor::ConfirmCompletionReplace",
|
||||
"tab": "editor::ComposeCompletion"
|
||||
}
|
||||
},
|
||||
@@ -564,8 +530,8 @@
|
||||
{
|
||||
"context": "Editor && (showing_code_actions || showing_completions)",
|
||||
"bindings": {
|
||||
"ctrl-p": "editor::ContextMenuPrevious",
|
||||
"up": "editor::ContextMenuPrevious",
|
||||
"ctrl-p": "editor::ContextMenuPrev",
|
||||
"up": "editor::ContextMenuPrev",
|
||||
"ctrl-n": "editor::ContextMenuNext",
|
||||
"down": "editor::ContextMenuNext",
|
||||
"pageup": "editor::ContextMenuFirst",
|
||||
@@ -593,11 +559,18 @@
|
||||
"ctrl-alt-enter": "editor::OpenExcerptsSplit",
|
||||
"ctrl-shift-e": "pane::RevealInProjectPanel",
|
||||
"ctrl-f8": "editor::GoToHunk",
|
||||
"ctrl-shift-f8": "editor::GoToPreviousHunk",
|
||||
"ctrl-shift-f8": "editor::GoToPrevHunk",
|
||||
"ctrl-enter": "assistant::InlineAssist",
|
||||
"ctrl-:": "editor::ToggleInlayHints"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ProposedChangesEditor",
|
||||
"bindings": {
|
||||
"ctrl-shift-y": "editor::ApplyDiffHunk",
|
||||
"ctrl-alt-a": "editor::ApplyAllDiffHunks"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && jupyter && !ContextEditor",
|
||||
"bindings": {
|
||||
@@ -614,7 +587,6 @@
|
||||
"save": "workspace::Save",
|
||||
"ctrl->": "assistant::QuoteSelection",
|
||||
"ctrl-<": "assistant::InsertIntoEditor",
|
||||
"ctrl-alt-/": "assistant::ToggleModelSelector",
|
||||
"shift-enter": "assistant::Split",
|
||||
"ctrl-r": "assistant::CycleMessageRole",
|
||||
"enter": "assistant::ConfirmCommand",
|
||||
@@ -622,75 +594,38 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentPanel",
|
||||
"context": "AssistantPanel2",
|
||||
"bindings": {
|
||||
"ctrl-n": "agent::NewThread",
|
||||
"ctrl-alt-n": "agent::NewPromptEditor",
|
||||
"ctrl-shift-h": "agent::OpenHistory",
|
||||
"ctrl-alt-c": "agent::OpenConfiguration",
|
||||
"ctrl-i": "agent::ToggleProfileSelector",
|
||||
"ctrl-alt-/": "assistant::ToggleModelSelector",
|
||||
"ctrl-shift-a": "agent::ToggleContextPicker",
|
||||
"ctrl-e": "agent::ChatMode",
|
||||
"ctrl-alt-e": "agent::RemoveAllContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentPanel > Markdown",
|
||||
"bindings": {
|
||||
"copy": "markdown::CopyAsMarkdown",
|
||||
"ctrl-c": "markdown::CopyAsMarkdown"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentPanel && prompt_editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-n": "agent::NewPromptEditor",
|
||||
"cmd-alt-t": "agent::NewThread"
|
||||
"ctrl-n": "assistant2::NewThread",
|
||||
"new": "assistant2::NewThread",
|
||||
"ctrl-shift-h": "assistant2::OpenHistory",
|
||||
"ctrl-alt-/": "assistant2::ToggleModelSelector",
|
||||
"ctrl-shift-a": "assistant2::ToggleContextPicker",
|
||||
"ctrl-e": "assistant2::ChatMode",
|
||||
"ctrl-alt-e": "assistant2::RemoveAllContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "MessageEditor > Editor",
|
||||
"bindings": {
|
||||
"enter": "agent::Chat",
|
||||
"ctrl-i": "agent::ToggleProfileSelector",
|
||||
"shift-ctrl-r": "agent::OpenAgentDiff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "EditMessageEditor > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"escape": "menu::Cancel",
|
||||
"enter": "menu::Confirm",
|
||||
"alt-enter": "editor::Newline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentFeedbackMessageEditor > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"escape": "menu::Cancel",
|
||||
"enter": "menu::Confirm",
|
||||
"alt-enter": "editor::Newline"
|
||||
"enter": "assistant2::Chat"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ContextStrip",
|
||||
"bindings": {
|
||||
"up": "agent::FocusUp",
|
||||
"right": "agent::FocusRight",
|
||||
"left": "agent::FocusLeft",
|
||||
"down": "agent::FocusDown",
|
||||
"backspace": "agent::RemoveFocusedContext",
|
||||
"enter": "agent::AcceptSuggestedContext"
|
||||
"up": "assistant2::FocusUp",
|
||||
"right": "assistant2::FocusRight",
|
||||
"left": "assistant2::FocusLeft",
|
||||
"down": "assistant2::FocusDown",
|
||||
"backspace": "assistant2::RemoveFocusedContext",
|
||||
"enter": "assistant2::AcceptSuggestedContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ThreadHistory",
|
||||
"bindings": {
|
||||
"backspace": "agent::RemoveSelectedThread"
|
||||
"backspace": "assistant2::RemoveSelectedThread"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -698,7 +633,7 @@
|
||||
"bindings": {
|
||||
"ctrl-[": "assistant::CyclePreviousInlineAssist",
|
||||
"ctrl-]": "assistant::CycleNextInlineAssist",
|
||||
"ctrl-alt-e": "agent::RemoveAllContext"
|
||||
"ctrl-alt-e": "assistant2::RemoveAllContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -720,7 +655,7 @@
|
||||
"alt-ctrl-r": "outline_panel::RevealInFileManager",
|
||||
"space": "outline_panel::Open",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-up": "menu::SelectPrev",
|
||||
"alt-enter": "editor::OpenExcerpts",
|
||||
"ctrl-alt-enter": "editor::OpenExcerptsSplit"
|
||||
}
|
||||
@@ -758,7 +693,7 @@
|
||||
"shift-find": "project_panel::NewSearchInDirectory",
|
||||
"ctrl-shift-f": "project_panel::NewSearchInDirectory",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-up": "menu::SelectPrev",
|
||||
"escape": "menu::Cancel"
|
||||
}
|
||||
},
|
||||
@@ -768,76 +703,34 @@
|
||||
"space": "project_panel::Open"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && !CommitEditor",
|
||||
"bindings": {
|
||||
"escape": "git_panel::Close"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitPanel && ChangesList",
|
||||
"bindings": {
|
||||
"up": "menu::SelectPrevious",
|
||||
"up": "menu::SelectPrev",
|
||||
"down": "menu::SelectNext",
|
||||
"enter": "menu::Confirm",
|
||||
"alt-y": "git::StageFile",
|
||||
"alt-shift-y": "git::UnstageFile",
|
||||
"ctrl-alt-y": "git::ToggleStaged",
|
||||
"space": "git::ToggleStaged",
|
||||
"ctrl-space": "git::StageAll",
|
||||
"ctrl-shift-space": "git::UnstageAll",
|
||||
"tab": "git_panel::FocusEditor",
|
||||
"shift-tab": "git_panel::FocusEditor",
|
||||
"escape": "git_panel::ToggleFocus",
|
||||
"ctrl-enter": "git::Commit",
|
||||
"alt-enter": "menu::SecondaryConfirm",
|
||||
"delete": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"backspace": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"shift-delete": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"ctrl-backspace": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"ctrl-delete": ["git::RestoreFile", { "skip_prompt": false }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitCommit > Editor",
|
||||
"bindings": {
|
||||
"escape": "menu::Cancel",
|
||||
"enter": "editor::Newline",
|
||||
"ctrl-enter": "git::Commit",
|
||||
"alt-l": "git::GenerateCommitMessage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitPanel",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"ctrl-g ctrl-g": "git::Fetch",
|
||||
"ctrl-g up": "git::Push",
|
||||
"ctrl-g down": "git::Pull",
|
||||
"ctrl-g shift-up": "git::ForcePush",
|
||||
"ctrl-g d": "git::Diff",
|
||||
"ctrl-g backspace": "git::RestoreTrackedFiles",
|
||||
"ctrl-g shift-backspace": "git::TrashUntrackedFiles",
|
||||
"ctrl-space": "git::StageAll",
|
||||
"ctrl-shift-space": "git::UnstageAll"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitDiff > Editor",
|
||||
"bindings": {
|
||||
"ctrl-enter": "git::Commit",
|
||||
"ctrl-space": "git::StageAll",
|
||||
"ctrl-shift-space": "git::UnstageAll"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AskPass > Editor",
|
||||
"bindings": {
|
||||
"enter": "menu::Confirm"
|
||||
"escape": "git_panel::ToggleFocus"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitPanel > Editor",
|
||||
"bindings": {
|
||||
"escape": "git_panel::FocusChanges",
|
||||
"ctrl-enter": "git::Commit",
|
||||
"tab": "git_panel::FocusChanges",
|
||||
"shift-tab": "git_panel::FocusChanges",
|
||||
"enter": "editor::Newline",
|
||||
"ctrl-enter": "git::Commit",
|
||||
"alt-up": "git_panel::FocusChanges",
|
||||
"alt-l": "git::GenerateCommitMessage"
|
||||
"alt-up": "git_panel::FocusChanges"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -862,9 +755,6 @@
|
||||
{
|
||||
"context": "Picker > Editor",
|
||||
"bindings": {
|
||||
"escape": "menu::Cancel",
|
||||
"up": "menu::SelectPrevious",
|
||||
"down": "menu::SelectNext",
|
||||
"tab": "picker::ConfirmCompletion",
|
||||
"alt-enter": ["picker::ConfirmInput", { "secondary": false }]
|
||||
}
|
||||
@@ -876,20 +766,35 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder || (FileFinder > Picker > Editor) || (FileFinder > Picker > menu)",
|
||||
"context": "FileFinder",
|
||||
"bindings": {
|
||||
"ctrl-shift-p": "file_finder::SelectPrevious",
|
||||
"ctrl": "file_finder::ToggleMenu"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && !menu_open",
|
||||
"bindings": {
|
||||
"ctrl-shift-p": "file_finder::SelectPrev",
|
||||
"ctrl-j": "pane::SplitDown",
|
||||
"ctrl-k": "pane::SplitUp",
|
||||
"ctrl-h": "pane::SplitLeft",
|
||||
"ctrl-l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && menu_open",
|
||||
"bindings": {
|
||||
"j": "pane::SplitDown",
|
||||
"k": "pane::SplitUp",
|
||||
"h": "pane::SplitLeft",
|
||||
"l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "TabSwitcher",
|
||||
"bindings": {
|
||||
"ctrl-shift-tab": "menu::SelectPrevious",
|
||||
"ctrl-up": "menu::SelectPrevious",
|
||||
"ctrl-shift-tab": "menu::SelectPrev",
|
||||
"ctrl-up": "menu::SelectPrev",
|
||||
"ctrl-down": "menu::SelectNext",
|
||||
"ctrl-backspace": "tab_switcher::CloseSelectedItem"
|
||||
}
|
||||
@@ -908,22 +813,20 @@
|
||||
"alt-b": ["terminal::SendText", "\u001bb"],
|
||||
"alt-f": ["terminal::SendText", "\u001bf"],
|
||||
// Overrides for conflicting keybindings
|
||||
"ctrl-b": ["terminal::SendKeystroke", "ctrl-b"],
|
||||
"ctrl-c": ["terminal::SendKeystroke", "ctrl-c"],
|
||||
"ctrl-e": ["terminal::SendKeystroke", "ctrl-e"],
|
||||
"ctrl-o": ["terminal::SendKeystroke", "ctrl-o"],
|
||||
"ctrl-w": ["terminal::SendKeystroke", "ctrl-w"],
|
||||
"ctrl-shift-a": "editor::SelectAll",
|
||||
"find": "buffer_search::Deploy",
|
||||
"ctrl-shift-f": "buffer_search::Deploy",
|
||||
"ctrl-shift-l": "terminal::Clear",
|
||||
"ctrl-shift-w": "pane::CloseActiveItem",
|
||||
"ctrl-e": ["terminal::SendKeystroke", "ctrl-e"],
|
||||
"up": ["terminal::SendKeystroke", "up"],
|
||||
"pageup": ["terminal::SendKeystroke", "pageup"],
|
||||
"down": ["terminal::SendKeystroke", "down"],
|
||||
"pagedown": ["terminal::SendKeystroke", "pagedown"],
|
||||
"escape": ["terminal::SendKeystroke", "escape"],
|
||||
"enter": ["terminal::SendKeystroke", "enter"],
|
||||
"ctrl-c": ["terminal::SendKeystroke", "ctrl-c"],
|
||||
"shift-pageup": "terminal::ScrollPageUp",
|
||||
"shift-pagedown": "terminal::ScrollPageDown",
|
||||
"shift-up": "terminal::ScrollLineUp",
|
||||
|
||||
@@ -1,26 +1,8 @@
|
||||
[
|
||||
// Moved before Standard macOS bindings so that `cmd-w` is not the last binding for
|
||||
// `workspace::CloseWindow` and displayed/intercepted by macOS
|
||||
{
|
||||
"context": "PromptLibrary",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-n": "prompt_library::NewPrompt",
|
||||
"cmd-shift-s": "prompt_library::ToggleDefaultPrompt",
|
||||
"cmd-w": "workspace::CloseWindow"
|
||||
}
|
||||
},
|
||||
// Standard macOS bindings
|
||||
{
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"f4": "debugger::Start",
|
||||
"f5": "debugger::Continue",
|
||||
"shift-f5": "debugger::Stop",
|
||||
"f6": "debugger::Pause",
|
||||
"f7": "debugger::StepOver",
|
||||
"f11": "debugger::StepInto",
|
||||
"shift-f11": "debugger::StepOut",
|
||||
"home": "menu::SelectFirst",
|
||||
"shift-pageup": "menu::SelectFirst",
|
||||
"pageup": "menu::SelectFirst",
|
||||
@@ -32,14 +14,14 @@
|
||||
"tab": "menu::SelectNext",
|
||||
"ctrl-n": "menu::SelectNext",
|
||||
"down": "menu::SelectNext",
|
||||
"shift-tab": "menu::SelectPrevious",
|
||||
"ctrl-p": "menu::SelectPrevious",
|
||||
"up": "menu::SelectPrevious",
|
||||
"shift-tab": "menu::SelectPrev",
|
||||
"ctrl-p": "menu::SelectPrev",
|
||||
"up": "menu::SelectPrev",
|
||||
"enter": "menu::Confirm",
|
||||
"ctrl-enter": "menu::SecondaryConfirm",
|
||||
"cmd-enter": "menu::SecondaryConfirm",
|
||||
"cmd-escape": "menu::Cancel",
|
||||
"ctrl-escape": "menu::Cancel",
|
||||
"cmd-escape": "menu::Cancel",
|
||||
"ctrl-c": "menu::Cancel",
|
||||
"escape": "menu::Cancel",
|
||||
"alt-shift-enter": "menu::Restart",
|
||||
@@ -72,7 +54,7 @@
|
||||
"ctrl-d": "editor::Delete",
|
||||
"delete": "editor::Delete",
|
||||
"tab": "editor::Tab",
|
||||
"shift-tab": "editor::Backtab",
|
||||
"shift-tab": "editor::TabPrev",
|
||||
"ctrl-t": "editor::Transpose",
|
||||
"ctrl-k": "editor::KillRingCut",
|
||||
"ctrl-y": "editor::KillRingYank",
|
||||
@@ -109,16 +91,14 @@
|
||||
"ctrl-l": "editor::ScrollCursorCenter",
|
||||
"alt-left": "editor::MoveToPreviousWordStart",
|
||||
"alt-right": "editor::MoveToNextWordEnd",
|
||||
"cmd-left": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
"ctrl-a": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": false, "stop_at_indent": true }],
|
||||
"home": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
"cmd-right": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
"ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }],
|
||||
"end": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
"cmd-left": "editor::MoveToBeginningOfLine",
|
||||
"ctrl-a": "editor::MoveToBeginningOfLine",
|
||||
"home": "editor::MoveToBeginningOfLine",
|
||||
"cmd-right": "editor::MoveToEndOfLine",
|
||||
"ctrl-e": "editor::MoveToEndOfLine",
|
||||
"end": "editor::MoveToEndOfLine",
|
||||
"cmd-up": "editor::MoveToBeginning",
|
||||
"cmd-down": "editor::MoveToEnd",
|
||||
"cmd-home": "editor::MoveToBeginning", // Typed via `cmd-fn-left`
|
||||
"cmd-end": "editor::MoveToEnd", // Typed via `cmd-fn-right`
|
||||
"shift-up": "editor::SelectUp",
|
||||
"ctrl-shift-p": "editor::SelectUp",
|
||||
"shift-down": "editor::SelectDown",
|
||||
@@ -136,10 +116,9 @@
|
||||
"cmd-a": "editor::SelectAll",
|
||||
"cmd-l": "editor::SelectLine",
|
||||
"cmd-shift-i": "editor::Format",
|
||||
"alt-shift-o": "editor::OrganizeImports",
|
||||
"cmd-shift-left": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
"ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true, "stop_at_indent": true }],
|
||||
"cmd-shift-left": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
|
||||
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
|
||||
"ctrl-shift-a": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": true }],
|
||||
"cmd-shift-right": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
"ctrl-shift-e": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": true }],
|
||||
@@ -147,12 +126,11 @@
|
||||
"ctrl-shift-v": ["editor::MovePageUp", { "center_cursor": true }],
|
||||
"ctrl-cmd-space": "editor::ShowCharacterPalette",
|
||||
"cmd-;": "editor::ToggleLineNumbers",
|
||||
"cmd-alt-z": "editor::RevertSelectedHunks",
|
||||
"cmd-'": "editor::ToggleSelectedDiffHunks",
|
||||
"cmd-\"": "editor::ExpandAllDiffHunks",
|
||||
"cmd-\"": "editor::ExpandAllHunkDiffs",
|
||||
"cmd-alt-g b": "editor::ToggleGitBlame",
|
||||
"cmd-i": "editor::ShowSignatureHelp",
|
||||
"f9": "editor::ToggleBreakpoint",
|
||||
"shift-f9": "editor::EditLogBreakpoint",
|
||||
"ctrl-f12": "editor::GoToDeclaration",
|
||||
"alt-ctrl-f12": "editor::GoToDeclarationSplit",
|
||||
"ctrl-cmd-e": "editor::ToggleEditPrediction"
|
||||
@@ -177,16 +155,6 @@
|
||||
"alt-enter": "editor::OpenSelectionsInMultibuffer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && multibuffer",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-up": "editor::MoveToStartOfExcerpt",
|
||||
"cmd-down": "editor::MoveToStartOfNextExcerpt",
|
||||
"cmd-shift-up": "editor::SelectToStartOfExcerpt",
|
||||
"cmd-shift-down": "editor::SelectToStartOfNextExcerpt"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && mode == full && edit_prediction",
|
||||
"use_key_equivalents": true,
|
||||
@@ -227,24 +195,6 @@
|
||||
"ctrl-alt-enter": "repl::RunInPlace"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && !agent_diff",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-alt-z": "git::Restore",
|
||||
"cmd-alt-y": "git::ToggleStaged",
|
||||
"cmd-y": "git::StageAndNext",
|
||||
"cmd-shift-y": "git::UnstageAndNext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentDiff",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-y": "agent::Keep",
|
||||
"cmd-n": "agent::Reject"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AssistantPanel",
|
||||
"use_key_equivalents": true,
|
||||
@@ -252,12 +202,11 @@
|
||||
"cmd-k c": "assistant::CopyCode",
|
||||
"cmd-shift-e": "project_panel::ToggleFocus",
|
||||
"cmd-g": "search::SelectNextMatch",
|
||||
"cmd-shift-g": "search::SelectPreviousMatch",
|
||||
"cmd-shift-g": "search::SelectPrevMatch",
|
||||
"cmd-alt-/": "assistant::ToggleModelSelector",
|
||||
"cmd-k h": "assistant::DeployHistory",
|
||||
"cmd-k l": "assistant::OpenPromptLibrary",
|
||||
"cmd-t": "assistant::NewChat",
|
||||
"cmd-n": "assistant::NewChat"
|
||||
"cmd-k l": "assistant::DeployPromptLibrary",
|
||||
"cmd-n": "assistant::NewContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -269,7 +218,6 @@
|
||||
"cmd-s": "workspace::Save",
|
||||
"cmd->": "assistant::QuoteSelection",
|
||||
"cmd-<": "assistant::InsertIntoEditor",
|
||||
"cmd-alt-/": "assistant::ToggleModelSelector",
|
||||
"shift-enter": "assistant::Split",
|
||||
"ctrl-r": "assistant::CycleMessageRole",
|
||||
"enter": "assistant::ConfirmCommand",
|
||||
@@ -277,96 +225,50 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentPanel",
|
||||
"context": "AssistantPanel2",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-n": "agent::NewThread",
|
||||
"cmd-alt-n": "agent::NewPromptEditor",
|
||||
"cmd-shift-h": "agent::OpenHistory",
|
||||
"cmd-alt-c": "agent::OpenConfiguration",
|
||||
"cmd-i": "agent::ToggleProfileSelector",
|
||||
"cmd-alt-/": "assistant::ToggleModelSelector",
|
||||
"cmd-shift-a": "agent::ToggleContextPicker",
|
||||
"cmd-e": "agent::ChatMode",
|
||||
"cmd-alt-e": "agent::RemoveAllContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentPanel > Markdown",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-c": "markdown::CopyAsMarkdown"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentPanel && prompt_editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-n": "agent::NewPromptEditor",
|
||||
"cmd-alt-t": "agent::NewThread"
|
||||
"cmd-n": "assistant2::NewThread",
|
||||
"cmd-alt-p": "assistant2::NewPromptEditor",
|
||||
"cmd-shift-h": "assistant2::OpenHistory",
|
||||
"cmd-alt-/": "assistant2::ToggleModelSelector",
|
||||
"cmd-shift-a": "assistant2::ToggleContextPicker",
|
||||
"cmd-e": "assistant2::ChatMode",
|
||||
"cmd-alt-e": "assistant2::RemoveAllContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "MessageEditor > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"enter": "agent::Chat",
|
||||
"cmd-i": "agent::ToggleProfileSelector",
|
||||
"shift-ctrl-r": "agent::OpenAgentDiff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "EditMessageEditor > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"escape": "menu::Cancel",
|
||||
"enter": "menu::Confirm",
|
||||
"alt-enter": "editor::Newline"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentFeedbackMessageEditor > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"escape": "menu::Cancel",
|
||||
"enter": "menu::Confirm",
|
||||
"alt-enter": "editor::Newline"
|
||||
"enter": "assistant2::Chat"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ContextStrip",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"up": "agent::FocusUp",
|
||||
"right": "agent::FocusRight",
|
||||
"left": "agent::FocusLeft",
|
||||
"down": "agent::FocusDown",
|
||||
"backspace": "agent::RemoveFocusedContext",
|
||||
"enter": "agent::AcceptSuggestedContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "AgentConfiguration",
|
||||
"bindings": {
|
||||
"ctrl--": "pane::GoBack"
|
||||
"up": "assistant2::FocusUp",
|
||||
"right": "assistant2::FocusRight",
|
||||
"left": "assistant2::FocusLeft",
|
||||
"down": "assistant2::FocusDown",
|
||||
"backspace": "assistant2::RemoveFocusedContext",
|
||||
"enter": "assistant2::AcceptSuggestedContext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ThreadHistory",
|
||||
"bindings": {
|
||||
"ctrl--": "pane::GoBack"
|
||||
"backspace": "assistant2::RemoveSelectedThread"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ThreadHistory",
|
||||
"context": "PromptLibrary",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"ctrl--": "pane::GoBack"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ThreadHistory > Editor",
|
||||
"bindings": {
|
||||
"shift-backspace": "agent::RemoveSelectedThread"
|
||||
"cmd-n": "prompt_library::NewPrompt",
|
||||
"cmd-shift-s": "prompt_library::ToggleDefaultPrompt",
|
||||
"cmd-w": "workspace::CloseWindow"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -376,12 +278,11 @@
|
||||
"escape": "buffer_search::Dismiss",
|
||||
"tab": "buffer_search::FocusEditor",
|
||||
"enter": "search::SelectNextMatch",
|
||||
"shift-enter": "search::SelectPreviousMatch",
|
||||
"shift-enter": "search::SelectPrevMatch",
|
||||
"alt-enter": "search::SelectAllMatches",
|
||||
"cmd-f": "search::FocusSearch",
|
||||
"cmd-alt-f": "search::ToggleReplace",
|
||||
"cmd-alt-l": "search::ToggleSelection",
|
||||
"cmd-shift-o": "outline::Toggle"
|
||||
"cmd-alt-l": "search::ToggleSelection"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -443,8 +344,8 @@
|
||||
"context": "Pane",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"alt-cmd-left": "pane::ActivatePreviousItem",
|
||||
"cmd-{": "pane::ActivatePreviousItem",
|
||||
"alt-cmd-left": "pane::ActivatePrevItem",
|
||||
"cmd-{": "pane::ActivatePrevItem",
|
||||
"alt-cmd-right": "pane::ActivateNextItem",
|
||||
"cmd-}": "pane::ActivateNextItem",
|
||||
"ctrl-shift-pageup": "pane::SwapItemLeft",
|
||||
@@ -455,11 +356,10 @@
|
||||
"cmd-k e": ["pane::CloseItemsToTheLeft", { "close_pinned": false }],
|
||||
"cmd-k t": ["pane::CloseItemsToTheRight", { "close_pinned": false }],
|
||||
"cmd-k u": ["pane::CloseCleanItems", { "close_pinned": false }],
|
||||
"cmd-k w": ["pane::CloseAllItems", { "close_pinned": false }],
|
||||
"cmd-k cmd-w": "workspace::CloseAllItemsAndPanes",
|
||||
"cmd-k cmd-w": ["pane::CloseAllItems", { "close_pinned": false }],
|
||||
"cmd-f": "project_search::ToggleFocus",
|
||||
"cmd-g": "search::SelectNextMatch",
|
||||
"cmd-shift-g": "search::SelectPreviousMatch",
|
||||
"cmd-shift-g": "search::SelectPrevMatch",
|
||||
"cmd-shift-h": "search::ToggleReplace",
|
||||
"cmd-alt-l": "search::ToggleSelection",
|
||||
"alt-enter": "search::SelectAllMatches",
|
||||
@@ -499,7 +399,7 @@
|
||||
"cmd-u": "editor::UndoSelection",
|
||||
"cmd-shift-u": "editor::RedoSelection",
|
||||
"f8": "editor::GoToDiagnostic",
|
||||
"shift-f8": "editor::GoToPreviousDiagnostic",
|
||||
"shift-f8": "editor::GoToPrevDiagnostic",
|
||||
"f2": "editor::Rename",
|
||||
"f12": "editor::GoToDefinition",
|
||||
"alt-f12": "editor::GoToDefinitionSplit",
|
||||
@@ -525,10 +425,9 @@
|
||||
"cmd-k cmd-9": ["editor::FoldAtLevel", 9],
|
||||
"cmd-k cmd-0": "editor::FoldAll",
|
||||
"cmd-k cmd-j": "editor::UnfoldAll",
|
||||
// Using `ctrl-space` / `ctrl-shift-space` in Zed requires disabling the macOS global shortcut.
|
||||
// Using `ctrl-space` in Zed requires disabling the macOS global shortcut.
|
||||
// System Preferences->Keyboard->Keyboard Shortcuts->Input Sources->Select the previous input source (uncheck)
|
||||
"ctrl-space": "editor::ShowCompletions",
|
||||
"ctrl-shift-space": "editor::ShowWordCompletions",
|
||||
"cmd-.": "editor::ToggleCodeActions",
|
||||
"cmd-k r": "editor::RevealInFileManager",
|
||||
"cmd-k p": "editor::CopyPath",
|
||||
@@ -561,7 +460,7 @@
|
||||
"ctrl-9": ["pane::ActivateItem", 8],
|
||||
"ctrl-0": "pane::ActivateLastItem",
|
||||
"ctrl--": "pane::GoBack",
|
||||
"ctrl-_": "pane::GoForward",
|
||||
"ctrl-shift--": "pane::GoForward",
|
||||
"cmd-shift-f": "pane::DeploySearch"
|
||||
}
|
||||
},
|
||||
@@ -577,7 +476,6 @@
|
||||
"ctrl-~": "workspace::NewTerminal",
|
||||
"cmd-s": "workspace::Save",
|
||||
"cmd-k s": "workspace::SaveWithoutFormat",
|
||||
"alt-shift-enter": "toast::RunAction",
|
||||
"cmd-shift-s": "workspace::SaveAs",
|
||||
"cmd-shift-n": "workspace::NewWindow",
|
||||
"ctrl-`": "terminal_panel::ToggleFocus",
|
||||
@@ -633,8 +531,6 @@
|
||||
"ctrl-alt-shift-r": ["task::Spawn", { "reveal_target": "center" }]
|
||||
// also possible to spawn tasks by name:
|
||||
// "foo-bar": ["task::Spawn", { "task_name": "MyTask", "reveal_target": "dock" }]
|
||||
// or by tag:
|
||||
// "foo-bar": ["task::Spawn", { "task_tag": "MyTag" }],
|
||||
}
|
||||
},
|
||||
// Bindings from Sublime Text
|
||||
@@ -681,7 +577,6 @@
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"enter": "editor::ConfirmCompletion",
|
||||
"shift-enter": "editor::ConfirmCompletionReplace",
|
||||
"tab": "editor::ComposeCompletion"
|
||||
}
|
||||
},
|
||||
@@ -710,8 +605,8 @@
|
||||
"context": "Editor && (showing_code_actions || showing_completions)",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"up": "editor::ContextMenuPrevious",
|
||||
"ctrl-p": "editor::ContextMenuPrevious",
|
||||
"up": "editor::ContextMenuPrev",
|
||||
"ctrl-p": "editor::ContextMenuPrev",
|
||||
"down": "editor::ContextMenuNext",
|
||||
"ctrl-n": "editor::ContextMenuNext",
|
||||
"pageup": "editor::ContextMenuFirst",
|
||||
@@ -737,32 +632,30 @@
|
||||
"cmd-alt-enter": "editor::OpenExcerptsSplit",
|
||||
"cmd-shift-e": "pane::RevealInProjectPanel",
|
||||
"cmd-f8": "editor::GoToHunk",
|
||||
"cmd-shift-f8": "editor::GoToPreviousHunk",
|
||||
"cmd-shift-f8": "editor::GoToPrevHunk",
|
||||
"ctrl-enter": "assistant::InlineAssist",
|
||||
"ctrl-:": "editor::ToggleInlayHints"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ProposedChangesEditor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-shift-y": "editor::ApplyDiffHunk",
|
||||
"cmd-shift-a": "editor::ApplyAllDiffHunks"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "PromptEditor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-shift-a": "agent::ToggleContextPicker",
|
||||
"cmd-alt-/": "assistant::ToggleModelSelector",
|
||||
"cmd-alt-e": "agent::RemoveAllContext",
|
||||
"cmd-shift-a": "assistant2::ToggleContextPicker",
|
||||
"cmd-alt-/": "assistant2::ToggleModelSelector",
|
||||
"cmd-alt-e": "assistant2::RemoveAllContext",
|
||||
"ctrl-[": "assistant::CyclePreviousInlineAssist",
|
||||
"ctrl-]": "assistant::CycleNextInlineAssist"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Prompt",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"left": "menu::SelectPrevious",
|
||||
"right": "menu::SelectNext",
|
||||
"h": "menu::SelectPrevious",
|
||||
"l": "menu::SelectNext"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "ProjectSearchBar && !in_replace",
|
||||
"use_key_equivalents": true,
|
||||
@@ -782,7 +675,7 @@
|
||||
"alt-cmd-r": "outline_panel::RevealInFileManager",
|
||||
"space": "outline_panel::Open",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-up": "menu::SelectPrev",
|
||||
"alt-enter": "editor::OpenExcerpts",
|
||||
"cmd-alt-enter": "editor::OpenExcerptsSplit"
|
||||
}
|
||||
@@ -812,7 +705,7 @@
|
||||
"cmd-alt-backspace": ["project_panel::Delete", { "skip_prompt": false }],
|
||||
"cmd-shift-f": "project_panel::NewSearchInDirectory",
|
||||
"shift-down": "menu::SelectNext",
|
||||
"shift-up": "menu::SelectPrevious",
|
||||
"shift-up": "menu::SelectPrev",
|
||||
"escape": "menu::Cancel"
|
||||
}
|
||||
},
|
||||
@@ -835,33 +728,18 @@
|
||||
"context": "GitPanel && ChangesList",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"up": "menu::SelectPrevious",
|
||||
"up": "menu::SelectPrev",
|
||||
"down": "menu::SelectNext",
|
||||
"cmd-up": "menu::SelectFirst",
|
||||
"cmd-down": "menu::SelectLast",
|
||||
"enter": "menu::Confirm",
|
||||
"cmd-alt-y": "git::ToggleStaged",
|
||||
"space": "git::ToggleStaged",
|
||||
"cmd-y": "git::StageFile",
|
||||
"cmd-shift-y": "git::UnstageFile",
|
||||
"cmd-shift-space": "git::StageAll",
|
||||
"ctrl-shift-space": "git::UnstageAll",
|
||||
"alt-down": "git_panel::FocusEditor",
|
||||
"tab": "git_panel::FocusEditor",
|
||||
"shift-tab": "git_panel::FocusEditor",
|
||||
"escape": "git_panel::ToggleFocus",
|
||||
"cmd-enter": "git::Commit",
|
||||
"backspace": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"delete": ["git::RestoreFile", { "skip_prompt": false }],
|
||||
"cmd-backspace": ["git::RestoreFile", { "skip_prompt": true }],
|
||||
"cmd-delete": ["git::RestoreFile", { "skip_prompt": true }]
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitDiff > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-enter": "git::Commit",
|
||||
"cmd-ctrl-y": "git::StageAll",
|
||||
"cmd-ctrl-shift-y": "git::UnstageAll"
|
||||
"escape": "git_panel::ToggleFocus"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -872,34 +750,7 @@
|
||||
"cmd-enter": "git::Commit",
|
||||
"tab": "git_panel::FocusChanges",
|
||||
"shift-tab": "git_panel::FocusChanges",
|
||||
"alt-up": "git_panel::FocusChanges",
|
||||
"shift-escape": "git::ExpandCommitEditor",
|
||||
"alt-tab": "git::GenerateCommitMessage"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitPanel",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"ctrl-g ctrl-g": "git::Fetch",
|
||||
"ctrl-g up": "git::Push",
|
||||
"ctrl-g down": "git::Pull",
|
||||
"ctrl-g shift-up": "git::ForcePush",
|
||||
"ctrl-g d": "git::Diff",
|
||||
"ctrl-g backspace": "git::RestoreTrackedFiles",
|
||||
"ctrl-g shift-backspace": "git::TrashUntrackedFiles",
|
||||
"cmd-ctrl-y": "git::StageAll",
|
||||
"cmd-ctrl-shift-y": "git::UnstageAll"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "GitCommit > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"enter": "editor::Newline",
|
||||
"escape": "menu::Cancel",
|
||||
"cmd-enter": "git::Commit",
|
||||
"alt-tab": "git::GenerateCommitMessage"
|
||||
"alt-up": "git_panel::FocusChanges"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -928,9 +779,6 @@
|
||||
"context": "Picker > Editor",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"escape": "menu::Cancel",
|
||||
"up": "menu::SelectPrevious",
|
||||
"down": "menu::SelectNext",
|
||||
"tab": "picker::ConfirmCompletion",
|
||||
"alt-enter": ["picker::ConfirmInput", { "secondary": false }],
|
||||
"cmd-alt-enter": ["picker::ConfirmInput", { "secondary": true }]
|
||||
@@ -944,22 +792,39 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder || (FileFinder > Picker > Editor) || (FileFinder > Picker > menu)",
|
||||
"context": "FileFinder",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-shift-p": "file_finder::SelectPrevious",
|
||||
"cmd": "file_finder::ToggleMenu"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && !menu_open",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"cmd-shift-p": "file_finder::SelectPrev",
|
||||
"cmd-j": "pane::SplitDown",
|
||||
"cmd-k": "pane::SplitUp",
|
||||
"cmd-h": "pane::SplitLeft",
|
||||
"cmd-l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "FileFinder && menu_open",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"j": "pane::SplitDown",
|
||||
"k": "pane::SplitUp",
|
||||
"h": "pane::SplitLeft",
|
||||
"l": "pane::SplitRight"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "TabSwitcher",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"ctrl-shift-tab": "menu::SelectPrevious",
|
||||
"ctrl-up": "menu::SelectPrevious",
|
||||
"ctrl-shift-tab": "menu::SelectPrev",
|
||||
"ctrl-up": "menu::SelectPrev",
|
||||
"ctrl-down": "menu::SelectNext",
|
||||
"ctrl-backspace": "tab_switcher::CloseSelectedItem"
|
||||
}
|
||||
@@ -975,7 +840,6 @@
|
||||
"cmd-k": "terminal::Clear",
|
||||
"cmd-n": "workspace::NewTerminal",
|
||||
"ctrl-enter": "assistant::InlineAssist",
|
||||
"ctrl-_": null, // emacs undo
|
||||
// Some nice conveniences
|
||||
"cmd-backspace": ["terminal::SendText", "\u0015"],
|
||||
"cmd-right": ["terminal::SendText", "\u0005"],
|
||||
@@ -1004,8 +868,6 @@
|
||||
"cmd-home": "terminal::ScrollToTop",
|
||||
"shift-end": "terminal::ScrollToBottom",
|
||||
"cmd-end": "terminal::ScrollToBottom",
|
||||
// Using `ctrl-shift-space` in Zed requires disabling the macOS global shortcut.
|
||||
// System Preferences->Keyboard->Keyboard Shortcuts->Input Sources->Select the previous input source (uncheck)
|
||||
"ctrl-shift-space": "terminal::ToggleViMode",
|
||||
"ctrl-k up": "pane::SplitUp",
|
||||
"ctrl-k down": "pane::SplitDown",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"context": "BufferSearchBar",
|
||||
"bindings": {
|
||||
"ctrl-f3": "search::SelectNextMatch", // find-and-replace:find-next-selected
|
||||
"ctrl-shift-f3": "search::SelectPreviousMatch" // find-and-replace:find-previous-selected
|
||||
"ctrl-shift-f3": "search::SelectPrevMatch" // find-and-replace:find-previous-selected
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
"ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
|
||||
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": false }], // move-beginning-of-line
|
||||
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
|
||||
"alt-m": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": false, "stop_at_indent": true }], // back-to-indentation
|
||||
"alt-f": "editor::MoveToNextSubwordEnd", // forward-word
|
||||
"alt-b": "editor::MoveToPreviousSubwordStart", // backward-word
|
||||
"alt-u": "editor::ConvertToUpperCase", // upcase-word
|
||||
@@ -49,8 +48,6 @@
|
||||
"ctrl-_": "editor::Undo", // undo
|
||||
"ctrl-/": "editor::Undo", // undo
|
||||
"ctrl-x u": "editor::Undo", // undo
|
||||
"alt-{": "editor::MoveToStartOfParagraph", // backward-paragraph
|
||||
"alt-}": "editor::MoveToEndOfParagraph", // forward-paragraph
|
||||
"ctrl-v": "editor::MovePageDown", // scroll-up
|
||||
"alt-v": "editor::MovePageUp", // scroll-down
|
||||
"ctrl-x [": "editor::MoveToBeginning", // beginning-of-buffer
|
||||
@@ -122,7 +119,7 @@
|
||||
"context": "BufferSearchBar > Editor",
|
||||
"bindings": {
|
||||
"ctrl-s": "search::SelectNextMatch",
|
||||
"ctrl-r": "search::SelectPreviousMatch",
|
||||
"ctrl-r": "search::SelectPrevMatch",
|
||||
"ctrl-g": "buffer_search::Dismiss"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,15 +2,8 @@
|
||||
{
|
||||
"bindings": {
|
||||
"ctrl-alt-s": "zed::OpenSettings",
|
||||
"ctrl-{": "pane::ActivatePreviousItem",
|
||||
"ctrl-}": "pane::ActivateNextItem",
|
||||
"ctrl-f2": "debugger::Stop",
|
||||
"f6": "debugger::Pause",
|
||||
"f7": "debugger::StepInto",
|
||||
"f8": "debugger::StepOver",
|
||||
"shift-f8": "debugger::StepOut",
|
||||
"f9": "debugger::Continue",
|
||||
"alt-shift-f9": "debugger::Start"
|
||||
"ctrl-shift-[": "pane::ActivatePrevItem",
|
||||
"ctrl-shift-]": "pane::ActivateNextItem"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -38,7 +31,6 @@
|
||||
"shift-alt-up": "editor::MoveLineUp",
|
||||
"shift-alt-down": "editor::MoveLineDown",
|
||||
"ctrl-alt-l": "editor::Format",
|
||||
"ctrl-alt-o": "editor::OrganizeImports",
|
||||
"shift-f6": "editor::Rename",
|
||||
"ctrl-alt-left": "pane::GoBack",
|
||||
"ctrl-alt-right": "pane::GoForward",
|
||||
@@ -49,17 +41,14 @@
|
||||
"ctrl-shift-b": "editor::GoToTypeDefinition",
|
||||
"ctrl-alt-shift-b": "editor::GoToTypeDefinitionSplit",
|
||||
"f2": "editor::GoToDiagnostic",
|
||||
"shift-f2": "editor::GoToPreviousDiagnostic",
|
||||
"shift-f2": "editor::GoToPrevDiagnostic",
|
||||
"ctrl-alt-shift-down": "editor::GoToHunk",
|
||||
"ctrl-alt-shift-up": "editor::GoToPreviousHunk",
|
||||
"ctrl-alt-z": "git::Restore",
|
||||
"ctrl-alt-shift-up": "editor::GoToPrevHunk",
|
||||
"ctrl-alt-z": "editor::RevertSelectedHunks",
|
||||
"ctrl-home": "editor::MoveToBeginning",
|
||||
"ctrl-end": "editor::MoveToEnd",
|
||||
"ctrl-shift-home": "editor::SelectToBeginning",
|
||||
"ctrl-shift-end": "editor::SelectToEnd",
|
||||
"ctrl-f8": "editor::ToggleBreakpoint",
|
||||
"ctrl-shift-f8": "editor::EditLogBreakpoint",
|
||||
"ctrl-shift-u": "editor::ToggleCase"
|
||||
"ctrl-shift-end": "editor::SelectToEnd"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[
|
||||
{
|
||||
"bindings": {
|
||||
"ctrl-{": "pane::ActivatePreviousItem",
|
||||
"ctrl-}": "pane::ActivateNextItem",
|
||||
"ctrl-pageup": "pane::ActivatePreviousItem",
|
||||
"ctrl-shift-[": "pane::ActivatePrevItem",
|
||||
"ctrl-shift-]": "pane::ActivateNextItem",
|
||||
"ctrl-pageup": "pane::ActivatePrevItem",
|
||||
"ctrl-pagedown": "pane::ActivateNextItem",
|
||||
"ctrl-1": ["workspace::ActivatePane", 0],
|
||||
"ctrl-2": ["workspace::ActivatePane", 1],
|
||||
@@ -14,15 +14,15 @@
|
||||
"ctrl-7": ["workspace::ActivatePane", 6],
|
||||
"ctrl-8": ["workspace::ActivatePane", 7],
|
||||
"ctrl-9": ["workspace::ActivatePane", 8],
|
||||
"ctrl-!": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
|
||||
"ctrl-@": ["workspace::MoveItemToPane", { "destination": 1 }],
|
||||
"ctrl-#": ["workspace::MoveItemToPane", { "destination": 2 }],
|
||||
"ctrl-$": ["workspace::MoveItemToPane", { "destination": 3 }],
|
||||
"ctrl-%": ["workspace::MoveItemToPane", { "destination": 4 }],
|
||||
"ctrl-^": ["workspace::MoveItemToPane", { "destination": 5 }],
|
||||
"ctrl-&": ["workspace::MoveItemToPane", { "destination": 6 }],
|
||||
"ctrl-*": ["workspace::MoveItemToPane", { "destination": 7 }],
|
||||
"ctrl-(": ["workspace::MoveItemToPane", { "destination": 8 }]
|
||||
"ctrl-shift-1": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
|
||||
"ctrl-shift-2": ["workspace::MoveItemToPane", { "destination": 1 }],
|
||||
"ctrl-shift-3": ["workspace::MoveItemToPane", { "destination": 2 }],
|
||||
"ctrl-shift-4": ["workspace::MoveItemToPane", { "destination": 3 }],
|
||||
"ctrl-shift-5": ["workspace::MoveItemToPane", { "destination": 4 }],
|
||||
"ctrl-shift-6": ["workspace::MoveItemToPane", { "destination": 5 }],
|
||||
"ctrl-shift-7": ["workspace::MoveItemToPane", { "destination": 6 }],
|
||||
"ctrl-shift-8": ["workspace::MoveItemToPane", { "destination": 7 }],
|
||||
"ctrl-shift-9": ["workspace::MoveItemToPane", { "destination": 8 }]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -44,7 +44,7 @@
|
||||
"shift-f12": "editor::FindAllReferences",
|
||||
"ctrl-shift-f12": "editor::FindAllReferences",
|
||||
"ctrl-.": "editor::GoToHunk",
|
||||
"ctrl-,": "editor::GoToPreviousHunk",
|
||||
"ctrl-,": "editor::GoToPrevHunk",
|
||||
"ctrl-k ctrl-u": "editor::ConvertToUpperCase",
|
||||
"ctrl-k ctrl-l": "editor::ConvertToLowerCase",
|
||||
"shift-alt-m": "markdown::OpenPreviewToTheSide",
|
||||
@@ -58,17 +58,11 @@
|
||||
"ctrl-r": "outline::Toggle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && !agent_diff",
|
||||
"bindings": {
|
||||
"ctrl-k ctrl-z": "git::Restore"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Pane",
|
||||
"bindings": {
|
||||
"f4": "search::SelectNextMatch",
|
||||
"shift-f4": "search::SelectPreviousMatch",
|
||||
"shift-f4": "search::SelectPrevMatch",
|
||||
"alt-1": ["pane::ActivateItem", 0],
|
||||
"alt-2": ["pane::ActivateItem", 1],
|
||||
"alt-3": ["pane::ActivateItem", 2],
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"context": "BufferSearchBar",
|
||||
"bindings": {
|
||||
"cmd-f3": "search::SelectNextMatch",
|
||||
"cmd-shift-f3": "search::SelectPreviousMatch"
|
||||
"cmd-shift-f3": "search::SelectPrevMatch"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
"ctrl-e": ["editor::MoveToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
|
||||
"shift-home": ["editor::SelectToBeginningOfLine", { "stop_at_soft_wraps": false }], // move-beginning-of-line
|
||||
"shift-end": ["editor::SelectToEndOfLine", { "stop_at_soft_wraps": false }], // move-end-of-line
|
||||
"alt-m": ["editor::MoveToBeginningOfLine", { "stop_at_soft_wraps": false, "stop_at_indent": true }], // back-to-indentation
|
||||
"alt-f": "editor::MoveToNextSubwordEnd", // forward-word
|
||||
"alt-b": "editor::MoveToPreviousSubwordStart", // backward-word
|
||||
"alt-u": "editor::ConvertToUpperCase", // upcase-word
|
||||
@@ -49,8 +48,6 @@
|
||||
"ctrl-_": "editor::Undo", // undo
|
||||
"ctrl-/": "editor::Undo", // undo
|
||||
"ctrl-x u": "editor::Undo", // undo
|
||||
"alt-{": "editor::MoveToStartOfParagraph", // backward-paragraph
|
||||
"alt-}": "editor::MoveToEndOfParagraph", // forward-paragraph
|
||||
"ctrl-v": "editor::MovePageDown", // scroll-up
|
||||
"alt-v": "editor::MovePageUp", // scroll-down
|
||||
"ctrl-x [": "editor::MoveToBeginning", // beginning-of-buffer
|
||||
@@ -122,7 +119,7 @@
|
||||
"context": "BufferSearchBar > Editor",
|
||||
"bindings": {
|
||||
"ctrl-s": "search::SelectNextMatch",
|
||||
"ctrl-r": "search::SelectPreviousMatch",
|
||||
"ctrl-r": "search::SelectPrevMatch",
|
||||
"ctrl-g": "buffer_search::Dismiss"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
[
|
||||
{
|
||||
"bindings": {
|
||||
"cmd-{": "pane::ActivatePreviousItem",
|
||||
"cmd-}": "pane::ActivateNextItem",
|
||||
"ctrl-f2": "debugger::Stop",
|
||||
"f6": "debugger::Pause",
|
||||
"f7": "debugger::StepInto",
|
||||
"f8": "debugger::StepOver",
|
||||
"shift-f8": "debugger::StepOut",
|
||||
"f9": "debugger::Continue",
|
||||
"alt-shift-f9": "debugger::Start"
|
||||
"cmd-shift-[": "pane::ActivatePrevItem",
|
||||
"cmd-shift-]": "pane::ActivateNextItem"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -36,7 +29,6 @@
|
||||
"shift-alt-up": "editor::MoveLineUp",
|
||||
"shift-alt-down": "editor::MoveLineDown",
|
||||
"cmd-alt-l": "editor::Format",
|
||||
"ctrl-alt-o": "editor::OrganizeImports",
|
||||
"shift-f6": "editor::Rename",
|
||||
"cmd-[": "pane::GoBack",
|
||||
"cmd-]": "pane::GoForward",
|
||||
@@ -47,16 +39,13 @@
|
||||
"cmd-shift-b": "editor::GoToTypeDefinition",
|
||||
"cmd-alt-shift-b": "editor::GoToTypeDefinitionSplit",
|
||||
"f2": "editor::GoToDiagnostic",
|
||||
"shift-f2": "editor::GoToPreviousDiagnostic",
|
||||
"shift-f2": "editor::GoToPrevDiagnostic",
|
||||
"ctrl-alt-shift-down": "editor::GoToHunk",
|
||||
"ctrl-alt-shift-up": "editor::GoToPreviousHunk",
|
||||
"ctrl-alt-shift-up": "editor::GoToPrevHunk",
|
||||
"cmd-home": "editor::MoveToBeginning",
|
||||
"cmd-end": "editor::MoveToEnd",
|
||||
"cmd-shift-home": "editor::SelectToBeginning",
|
||||
"cmd-shift-end": "editor::SelectToEnd",
|
||||
"ctrl-f8": "editor::ToggleBreakpoint",
|
||||
"ctrl-shift-f8": "editor::EditLogBreakpoint",
|
||||
"cmd-shift-u": "editor::ToggleCase"
|
||||
"cmd-shift-end": "editor::SelectToEnd"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -72,7 +61,7 @@
|
||||
{
|
||||
"context": "BufferSearchBar > Editor",
|
||||
"bindings": {
|
||||
"shift-enter": "search::SelectPreviousMatch"
|
||||
"shift-enter": "search::SelectPrevMatch"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[
|
||||
{
|
||||
"bindings": {
|
||||
"cmd-{": "pane::ActivatePreviousItem",
|
||||
"cmd-}": "pane::ActivateNextItem",
|
||||
"ctrl-pageup": "pane::ActivatePreviousItem",
|
||||
"cmd-shift-[": "pane::ActivatePrevItem",
|
||||
"cmd-shift-]": "pane::ActivateNextItem",
|
||||
"ctrl-pageup": "pane::ActivatePrevItem",
|
||||
"ctrl-pagedown": "pane::ActivateNextItem",
|
||||
"ctrl-1": ["workspace::ActivatePane", 0],
|
||||
"ctrl-2": ["workspace::ActivatePane", 1],
|
||||
@@ -14,15 +14,15 @@
|
||||
"ctrl-7": ["workspace::ActivatePane", 6],
|
||||
"ctrl-8": ["workspace::ActivatePane", 7],
|
||||
"ctrl-9": ["workspace::ActivatePane", 8],
|
||||
"ctrl-!": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
|
||||
"ctrl-@": ["workspace::MoveItemToPane", { "destination": 1 }],
|
||||
"ctrl-#": ["workspace::MoveItemToPane", { "destination": 2 }],
|
||||
"ctrl-$": ["workspace::MoveItemToPane", { "destination": 3 }],
|
||||
"ctrl-%": ["workspace::MoveItemToPane", { "destination": 4 }],
|
||||
"ctrl-^": ["workspace::MoveItemToPane", { "destination": 5 }],
|
||||
"ctrl-&": ["workspace::MoveItemToPane", { "destination": 6 }],
|
||||
"ctrl-*": ["workspace::MoveItemToPane", { "destination": 7 }],
|
||||
"ctrl-(": ["workspace::MoveItemToPane", { "destination": 8 }]
|
||||
"ctrl-shift-1": ["workspace::MoveItemToPane", { "destination": 0, "focus": true }],
|
||||
"ctrl-shift-2": ["workspace::MoveItemToPane", { "destination": 1 }],
|
||||
"ctrl-shift-3": ["workspace::MoveItemToPane", { "destination": 2 }],
|
||||
"ctrl-shift-4": ["workspace::MoveItemToPane", { "destination": 3 }],
|
||||
"ctrl-shift-5": ["workspace::MoveItemToPane", { "destination": 4 }],
|
||||
"ctrl-shift-6": ["workspace::MoveItemToPane", { "destination": 5 }],
|
||||
"ctrl-shift-7": ["workspace::MoveItemToPane", { "destination": 6 }],
|
||||
"ctrl-shift-8": ["workspace::MoveItemToPane", { "destination": 7 }],
|
||||
"ctrl-shift-9": ["workspace::MoveItemToPane", { "destination": 8 }]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -45,7 +45,7 @@
|
||||
"ctrl-alt-cmd-down": "editor::GoToDefinitionSplit",
|
||||
"alt-shift-cmd-down": "editor::FindAllReferences",
|
||||
"ctrl-.": "editor::GoToHunk",
|
||||
"ctrl-,": "editor::GoToPreviousHunk",
|
||||
"ctrl-,": "editor::GoToPrevHunk",
|
||||
"cmd-k cmd-u": "editor::ConvertToUpperCase",
|
||||
"cmd-k cmd-l": "editor::ConvertToLowerCase",
|
||||
"cmd-shift-j": "editor::JoinLines",
|
||||
@@ -60,17 +60,11 @@
|
||||
"cmd-r": "outline::Toggle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Editor && !agent_diff",
|
||||
"bindings": {
|
||||
"cmd-k cmd-z": "git::Restore"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "Pane",
|
||||
"bindings": {
|
||||
"f4": "search::SelectNextMatch",
|
||||
"shift-f4": "search::SelectPreviousMatch",
|
||||
"shift-f4": "search::SelectPrevMatch",
|
||||
"cmd-1": ["pane::ActivateItem", 0],
|
||||
"cmd-2": ["pane::ActivateItem", 1],
|
||||
"cmd-3": ["pane::ActivateItem", 2],
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
"context": "BufferSearchBar",
|
||||
"bindings": {
|
||||
"ctrl-s": "search::SelectNextMatch",
|
||||
"ctrl-shift-s": "search::SelectPreviousMatch"
|
||||
"ctrl-shift-s": "search::SelectPrevMatch"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
"tab": "menu::SelectNext",
|
||||
"ctrl-n": "menu::SelectNext",
|
||||
"down": "menu::SelectNext",
|
||||
"shift-tab": "menu::SelectPrevious",
|
||||
"ctrl-p": "menu::SelectPrevious",
|
||||
"up": "menu::SelectPrevious",
|
||||
"shift-tab": "menu::SelectPrev",
|
||||
"ctrl-p": "menu::SelectPrev",
|
||||
"up": "menu::SelectPrev",
|
||||
"enter": "menu::Confirm",
|
||||
"ctrl-enter": "menu::SecondaryConfirm",
|
||||
"cmd-enter": "menu::SecondaryConfirm",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"a": ["vim::PushObject", { "around": true }],
|
||||
"left": "vim::Left",
|
||||
"h": "vim::Left",
|
||||
"backspace": "vim::WrappingLeft",
|
||||
"backspace": "vim::Backspace",
|
||||
"down": "vim::Down",
|
||||
"ctrl-j": "vim::Down",
|
||||
"j": "vim::Down",
|
||||
@@ -20,7 +20,7 @@
|
||||
"k": "vim::Up",
|
||||
"right": "vim::Right",
|
||||
"l": "vim::Right",
|
||||
"space": "vim::WrappingRight",
|
||||
"space": "vim::Space",
|
||||
"end": "vim::EndOfLine",
|
||||
"$": "vim::EndOfLine",
|
||||
"^": "vim::FirstNonWhitespace",
|
||||
@@ -44,12 +44,6 @@
|
||||
"[ /": "vim::PreviousComment",
|
||||
"] *": "vim::NextComment",
|
||||
"] /": "vim::NextComment",
|
||||
"[ -": "vim::PreviousLesserIndent",
|
||||
"[ +": "vim::PreviousGreaterIndent",
|
||||
"[ =": "vim::PreviousSameIndent",
|
||||
"] -": "vim::NextLesserIndent",
|
||||
"] +": "vim::NextGreaterIndent",
|
||||
"] =": "vim::NextSameIndent",
|
||||
// Word motions
|
||||
"w": "vim::NextWordStart",
|
||||
"e": "vim::NextWordEnd",
|
||||
@@ -68,9 +62,9 @@
|
||||
"g /": "pane::DeploySearch",
|
||||
"?": ["vim::Search", { "backwards": true }],
|
||||
"*": "vim::MoveToNext",
|
||||
"#": "vim::MoveToPrevious",
|
||||
"#": "vim::MoveToPrev",
|
||||
"n": "vim::MoveToNextMatch",
|
||||
"shift-n": "vim::MoveToPreviousMatch",
|
||||
"shift-n": "vim::MoveToPrevMatch",
|
||||
"%": "vim::Matching",
|
||||
"] }": ["vim::UnmatchedForward", { "char": "}" }],
|
||||
"[ {": ["vim::UnmatchedBackward", { "char": "{" }],
|
||||
@@ -112,7 +106,7 @@
|
||||
"g g": "vim::StartOfDocument",
|
||||
"g h": "editor::Hover",
|
||||
"g t": "pane::ActivateNextItem",
|
||||
"g shift-t": "pane::ActivatePreviousItem",
|
||||
"g shift-t": "pane::ActivatePrevItem",
|
||||
"g d": "editor::GoToDefinition",
|
||||
"g shift-d": "editor::GoToDeclaration",
|
||||
"g y": "editor::GoToTypeDefinition",
|
||||
@@ -132,7 +126,7 @@
|
||||
"g shift-a": "editor::FindAllReferences", // zed specific
|
||||
"g space": "editor::OpenExcerpts", // zed specific
|
||||
"g *": ["vim::MoveToNext", { "partial_word": true }],
|
||||
"g #": ["vim::MoveToPrevious", { "partial_word": true }],
|
||||
"g #": ["vim::MoveToPrev", { "partial_word": true }],
|
||||
"g j": ["vim::Down", { "display_lines": true }],
|
||||
"g down": ["vim::Down", { "display_lines": true }],
|
||||
"g k": ["vim::Up", { "display_lines": true }],
|
||||
@@ -144,7 +138,7 @@
|
||||
"g ^": ["vim::FirstNonWhitespace", { "display_lines": true }],
|
||||
"g v": "vim::RestoreVisualSelection",
|
||||
"g ]": "editor::GoToDiagnostic",
|
||||
"g [": "editor::GoToPreviousDiagnostic",
|
||||
"g [": "editor::GoToPrevDiagnostic",
|
||||
"g i": "vim::InsertAtPrevious",
|
||||
"g ,": "vim::ChangeListNewer",
|
||||
"g ;": "vim::ChangeListOlder",
|
||||
@@ -233,21 +227,19 @@
|
||||
"g u": "vim::PushLowercase",
|
||||
"g shift-u": "vim::PushUppercase",
|
||||
"g ~": "vim::PushOppositeCase",
|
||||
"g ?": "vim::PushRot13",
|
||||
// "g ?": "vim::PushRot47",
|
||||
"\"": "vim::PushRegister",
|
||||
"g w": "vim::PushRewrap",
|
||||
"g q": "vim::PushRewrap",
|
||||
"ctrl-pagedown": "pane::ActivateNextItem",
|
||||
"ctrl-pageup": "pane::ActivatePreviousItem",
|
||||
"ctrl-pageup": "pane::ActivatePrevItem",
|
||||
"insert": "vim::InsertBefore",
|
||||
// tree-sitter related commands
|
||||
"[ x": "vim::SelectLargerSyntaxNode",
|
||||
"] x": "vim::SelectSmallerSyntaxNode",
|
||||
"] d": "editor::GoToDiagnostic",
|
||||
"[ d": "editor::GoToPreviousDiagnostic",
|
||||
"[ d": "editor::GoToPrevDiagnostic",
|
||||
"] c": "editor::GoToHunk",
|
||||
"[ c": "editor::GoToPreviousHunk",
|
||||
"[ c": "editor::GoToPrevHunk",
|
||||
"g c": "vim::PushToggleComments"
|
||||
}
|
||||
},
|
||||
@@ -255,8 +247,7 @@
|
||||
"context": "VimControl && VimCount",
|
||||
"bindings": {
|
||||
"0": ["vim::Number", 0],
|
||||
":": "vim::CountCommand",
|
||||
"%": "vim::GoToPercentage"
|
||||
":": "vim::CountCommand"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -266,10 +257,9 @@
|
||||
"u": "vim::ConvertToLowerCase",
|
||||
"shift-u": "vim::ConvertToUpperCase",
|
||||
"shift-o": "vim::OtherEnd",
|
||||
"o": "vim::OtherEndRowAware",
|
||||
"o": "vim::OtherEnd",
|
||||
"d": "vim::VisualDelete",
|
||||
"x": "vim::VisualDelete",
|
||||
"delete": "vim::VisualDelete",
|
||||
"shift-d": "vim::VisualDeleteLine",
|
||||
"shift-x": "vim::VisualDeleteLine",
|
||||
"y": "vim::VisualYank",
|
||||
@@ -282,7 +272,7 @@
|
||||
"shift-s": "vim::SubstituteLine",
|
||||
"~": "vim::ChangeCase",
|
||||
"*": ["vim::MoveToNext", { "partial_word": true }],
|
||||
"#": ["vim::MoveToPrevious", { "partial_word": true }],
|
||||
"#": ["vim::MoveToPrev", { "partial_word": true }],
|
||||
"ctrl-a": "vim::Increment",
|
||||
"ctrl-x": "vim::Decrement",
|
||||
"g ctrl-a": ["vim::Increment", { "step": true }],
|
||||
@@ -303,11 +293,8 @@
|
||||
"!": "vim::ShellCommand",
|
||||
"i": ["vim::PushObject", { "around": false }],
|
||||
"a": ["vim::PushObject", { "around": true }],
|
||||
"g r": ["vim::Paste", { "preserve_clipboard": true }],
|
||||
"g c": "vim::ToggleComments",
|
||||
"g q": "vim::Rewrap",
|
||||
"g ?": "vim::ConvertToRot13",
|
||||
// "g ?": "vim::ConvertToRot47",
|
||||
"\"": "vim::PushRegister",
|
||||
// tree-sitter related commands
|
||||
"[ x": "editor::SelectLargerSyntaxNode",
|
||||
@@ -341,106 +328,27 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_mode == helix_normal && !menu",
|
||||
"context": "vim_mode == helix_normal",
|
||||
"bindings": {
|
||||
"escape": "editor::Cancel",
|
||||
"ctrl-[": "editor::Cancel",
|
||||
":": "command_palette::Toggle",
|
||||
"shift-d": "vim::DeleteToEndOfLine",
|
||||
"shift-j": "vim::JoinLines",
|
||||
"y": "editor::Copy",
|
||||
"shift-y": "vim::YankLine",
|
||||
"i": "vim::InsertBefore",
|
||||
"shift-i": "vim::InsertFirstNonWhitespace",
|
||||
"a": "vim::InsertAfter",
|
||||
"shift-a": "vim::InsertEndOfLine",
|
||||
"o": "vim::InsertLineBelow",
|
||||
"shift-o": "vim::InsertLineAbove",
|
||||
"~": "vim::ChangeCase",
|
||||
"ctrl-a": "vim::Increment",
|
||||
"ctrl-x": "vim::Decrement",
|
||||
"p": "vim::Paste",
|
||||
"shift-p": ["vim::Paste", { "before": true }],
|
||||
"u": "vim::Undo",
|
||||
"ctrl-r": "vim::Redo",
|
||||
"r": "vim::PushReplace",
|
||||
"s": "vim::Substitute",
|
||||
"shift-s": "vim::SubstituteLine",
|
||||
">": "vim::Indent",
|
||||
"<": "vim::Outdent",
|
||||
"=": "vim::AutoIndent",
|
||||
"g u": "vim::PushLowercase",
|
||||
"g shift-u": "vim::PushUppercase",
|
||||
"g ~": "vim::PushOppositeCase",
|
||||
"\"": "vim::PushRegister",
|
||||
"g q": "vim::PushRewrap",
|
||||
"g w": "vim::PushRewrap",
|
||||
"ctrl-pagedown": "pane::ActivateNextItem",
|
||||
"ctrl-pageup": "pane::ActivatePreviousItem",
|
||||
"insert": "vim::InsertBefore",
|
||||
// tree-sitter related commands
|
||||
"[ x": "editor::SelectLargerSyntaxNode",
|
||||
"] x": "editor::SelectSmallerSyntaxNode",
|
||||
"] d": "editor::GoToDiagnostic",
|
||||
"[ d": "editor::GoToPreviousDiagnostic",
|
||||
"] c": "editor::GoToHunk",
|
||||
"[ c": "editor::GoToPreviousHunk",
|
||||
// Goto mode
|
||||
"g n": "pane::ActivateNextItem",
|
||||
"g p": "pane::ActivatePreviousItem",
|
||||
// "tab": "pane::ActivateNextItem",
|
||||
// "shift-tab": "pane::ActivatePrevItem",
|
||||
"shift-h": "pane::ActivatePreviousItem",
|
||||
"shift-l": "pane::ActivateNextItem",
|
||||
"g l": "vim::EndOfLine",
|
||||
"g h": "vim::StartOfLine",
|
||||
"g s": "vim::FirstNonWhitespace", // "g s" default behavior is "space s"
|
||||
"g e": "vim::EndOfDocument",
|
||||
"g y": "editor::GoToTypeDefinition",
|
||||
"g r": "editor::FindAllReferences", // zed specific
|
||||
"g t": "vim::WindowTop",
|
||||
"g c": "vim::WindowMiddle",
|
||||
"g b": "vim::WindowBottom",
|
||||
|
||||
"x": "editor::SelectLine",
|
||||
"shift-x": "editor::SelectLine",
|
||||
// Window mode
|
||||
"space w h": "workspace::ActivatePaneLeft",
|
||||
"space w l": "workspace::ActivatePaneRight",
|
||||
"space w k": "workspace::ActivatePaneUp",
|
||||
"space w j": "workspace::ActivatePaneDown",
|
||||
"space w q": "pane::CloseActiveItem",
|
||||
"space w s": "pane::SplitRight",
|
||||
"space w r": "pane::SplitRight",
|
||||
"space w v": "pane::SplitDown",
|
||||
"space w d": "pane::SplitDown",
|
||||
// Space mode
|
||||
"space f": "file_finder::Toggle",
|
||||
"space k": "editor::Hover",
|
||||
"space s": "outline::Toggle",
|
||||
"space shift-s": "project_symbols::Toggle",
|
||||
"space d": "editor::GoToDiagnostic",
|
||||
"space r": "editor::Rename",
|
||||
"space a": "editor::ToggleCodeActions",
|
||||
"space h": "editor::SelectAllMatches",
|
||||
"space c": "editor::ToggleComments",
|
||||
"space y": "editor::Copy",
|
||||
"space p": "editor::Paste",
|
||||
// Match mode
|
||||
"m m": "vim::Matching",
|
||||
"m i w": ["workspace::SendKeystrokes", "v i w"],
|
||||
"shift-u": "editor::Redo",
|
||||
"ctrl-c": "editor::ToggleComments",
|
||||
"d": "vim::HelixDelete",
|
||||
"c": "vim::Substitute",
|
||||
"shift-c": "editor::AddSelectionBelow"
|
||||
"w": "vim::NextWordStart",
|
||||
"e": "vim::NextWordEnd",
|
||||
"b": "vim::PreviousWordStart",
|
||||
|
||||
"h": "vim::Left",
|
||||
"j": "vim::Down",
|
||||
"k": "vim::Up",
|
||||
"l": "vim::Right"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"context": "vim_mode == insert && !(showing_code_actions || showing_completions)",
|
||||
"bindings": {
|
||||
"ctrl-p": "editor::ShowWordCompletions",
|
||||
"ctrl-n": "editor::ShowWordCompletions"
|
||||
"ctrl-p": "editor::ShowCompletions",
|
||||
"ctrl-n": "editor::ShowCompletions"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -528,7 +436,6 @@
|
||||
"context": "vim_operator == c",
|
||||
"bindings": {
|
||||
"c": "vim::CurrentLine",
|
||||
"x": "vim::Exchange",
|
||||
"d": "editor::Rename", // zed specific
|
||||
"s": ["vim::PushChangeSurrounds", {}]
|
||||
}
|
||||
@@ -539,10 +446,7 @@
|
||||
"d": "vim::CurrentLine",
|
||||
"s": "vim::PushDeleteSurrounds",
|
||||
"o": "editor::ToggleSelectedDiffHunks", // "d o"
|
||||
"shift-o": "git::ToggleStaged",
|
||||
"p": "git::Restore", // "d p"
|
||||
"u": "git::StageAndNext", // "d u"
|
||||
"shift-u": "git::UnstageAndNext" // "d shift-u"
|
||||
"p": "editor::RevertSelectedHunks" // "d p"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -566,13 +470,6 @@
|
||||
"~": "vim::CurrentLine"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_operator == g?",
|
||||
"bindings": {
|
||||
"g ?": "vim::CurrentLine",
|
||||
"?": "vim::CurrentLine"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_operator == gq",
|
||||
"bindings": {
|
||||
@@ -625,19 +522,6 @@
|
||||
"c": "vim::CurrentLine"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_operator == gr",
|
||||
"bindings": {
|
||||
"r": "vim::CurrentLine"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_operator == cx",
|
||||
"bindings": {
|
||||
"x": "vim::CurrentLine",
|
||||
"c": "vim::ClearExchange"
|
||||
}
|
||||
},
|
||||
{
|
||||
"context": "vim_mode == literal",
|
||||
"bindings": {
|
||||
@@ -721,8 +605,8 @@
|
||||
"ctrl-w =": "vim::ResetPaneSizes",
|
||||
"ctrl-w g t": "pane::ActivateNextItem",
|
||||
"ctrl-w ctrl-g t": "pane::ActivateNextItem",
|
||||
"ctrl-w g shift-t": "pane::ActivatePreviousItem",
|
||||
"ctrl-w ctrl-g shift-t": "pane::ActivatePreviousItem",
|
||||
"ctrl-w g shift-t": "pane::ActivatePrevItem",
|
||||
"ctrl-w ctrl-g shift-t": "pane::ActivatePrevItem",
|
||||
"ctrl-w w": "workspace::ActivateNextPane",
|
||||
"ctrl-w ctrl-w": "workspace::ActivateNextPane",
|
||||
"ctrl-w p": "workspace::ActivatePreviousPane",
|
||||
@@ -765,7 +649,7 @@
|
||||
"escape": "project_panel::ToggleFocus",
|
||||
"h": "project_panel::CollapseSelectedEntry",
|
||||
"j": "menu::SelectNext",
|
||||
"k": "menu::SelectPrevious",
|
||||
"k": "menu::SelectPrev",
|
||||
"l": "project_panel::ExpandSelectedEntry",
|
||||
"o": "project_panel::OpenPermanent",
|
||||
"shift-d": "project_panel::Delete",
|
||||
@@ -791,7 +675,7 @@
|
||||
"context": "OutlinePanel && not_editing",
|
||||
"bindings": {
|
||||
"j": "menu::SelectNext",
|
||||
"k": "menu::SelectPrevious",
|
||||
"k": "menu::SelectPrev",
|
||||
"shift-g": "menu::SelectLast",
|
||||
"g g": "menu::SelectFirst"
|
||||
}
|
||||
@@ -800,7 +684,7 @@
|
||||
"context": "GitPanel && ChangesList",
|
||||
"use_key_equivalents": true,
|
||||
"bindings": {
|
||||
"k": "menu::SelectPrevious",
|
||||
"k": "menu::SelectPrev",
|
||||
"j": "menu::SelectNext",
|
||||
"g g": "menu::SelectFirst",
|
||||
"shift-g": "menu::SelectLast",
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
You are an AI assistant integrated into a code editor. You have the programming ability of an expert programmer who takes pride in writing high-quality code and is driven to the point of obsession about solving problems effectively. Your goal is to do one of the following two things:
|
||||
|
||||
1. Help users answer questions and perform tasks related to their codebase.
|
||||
2. Answer general-purpose questions unrelated to their particular codebase.
|
||||
|
||||
It will be up to you to decide which of these you are doing based on what the user has told you. When unclear, ask clarifying questions to understand the user's intent before proceeding.
|
||||
|
||||
You should only perform actions that modify the user's system if explicitly requested by the user:
|
||||
- If the user asks a question about how to accomplish a task, provide guidance or information, and use read-only tools (e.g., search) to assist. You may suggest potential actions, but do not directly modify the user's system without explicit instruction.
|
||||
- If the user clearly requests that you perform an action, carry out the action directly without explaining why you are doing so.
|
||||
|
||||
When answering questions, it's okay to give incomplete examples containing comments about what would go there in a real version. When being asked to directly perform tasks on the code base, you must ALWAYS make fully working code. You may never "simplify" the code by omitting or deleting functionality you know the user has requested, and you must NEVER write comments like "in a full version, this would..." - instead, you must actually implement the real version. Don't be lazy!
|
||||
|
||||
Note that project files are automatically backed up. The user can always get them back later if anything goes wrong, so there's
|
||||
no need to create backup files (e.g. `.bak` files) because these files will just take up unnecessary space on the user's disk.
|
||||
|
||||
When attempting to resolve issues around failing tests, never simply remove the failing tests. Unless the user explicitly asks you to remove tests, ALWAYS attempt to fix the code causing the tests to fail.
|
||||
|
||||
Ignore "TODO"-type comments unless they're relevant to the user's explicit request or the user specifically asks you to address them. It is, however, okay to include them in codebase summaries.
|
||||
|
||||
<style>
|
||||
Editing code:
|
||||
- Make sure to take previous edits into account.
|
||||
- The edits you perform might lead to errors or warnings. At the end of your changes, check whether you introduced any problems, and fix them before providing a summary of the changes you made.
|
||||
- You may only attempt to fix these up to 3 times. If you have tried 3 times to fix them, and there are still problems remaining, you must not continue trying to fix them, and must instead tell the user that there are problems remaining - and ask if the user would like you to attempt to solve them further.
|
||||
- Do not fix errors unrelated to your changes unless the user explicitly asks you to do so.
|
||||
- Prefer to move files over recreating them. The move can be followed by minor edits if required.
|
||||
- If you seem to be stuck, never go back and "simplify the implementation" by deleting the parts of the implementation you're stuck on and replacing them with comments. If you ever feel the urge to do this, instead immediately stop whatever you're doing (even if the code is in a broken state), report that you are stuck, explain what you're stuck on, and ask the user how to proceed.
|
||||
|
||||
Tool use:
|
||||
- Make sure to adhere to the tools schema.
|
||||
- Provide every required argument.
|
||||
- DO NOT use tools to access items that are already available in the context section.
|
||||
- Use only the tools that are currently available.
|
||||
- DO NOT use a tool that is not available just because it appears in the conversation. This means the user turned it off.
|
||||
|
||||
Responding:
|
||||
- Be concise and direct in your responses.
|
||||
- Never apologize or thank the user.
|
||||
- Don't comment that you have just realized or understood something.
|
||||
- When you are going to make a tool call, tersely explain your reasoning for choosing to use that tool, with no flourishes or commentary beyond that information.
|
||||
For example, rather than saying "You're absolutely right! Thank you for providing that context. Now I understand that we're missing a dependency, and I need to add it:" say "I'll add that missing dependency:" instead.
|
||||
- Also, don't restate what a tool call is about to do (or just did).
|
||||
For example, don't say "Now I'm going to check diagnostics to see if there are any warnings or errors," followed by running a tool which checks diagnostics and reports warnings or errors; instead, just request the tool call without saying anything.
|
||||
- All tool results are provided to you automatically, so DO NOT thank the user when this happens.
|
||||
|
||||
Whenever you mention a code block, you MUST use ONLY the following format:
|
||||
|
||||
```language path/to/Something.blah#L123-456
|
||||
(code goes here)
|
||||
```
|
||||
|
||||
The `#L123-456` means the line number range 123 through 456, and the path/to/Something.blah
|
||||
is a path in the project. (If there is no valid path in the project, then you can use
|
||||
/dev/null/path.extension for its path.) This is the ONLY valid way to format code blocks, because the Markdown parser
|
||||
does not understand the more common ```language syntax, or bare ``` blocks. It only
|
||||
understands this path-based syntax, and if the path is missing, then it will error and you will have to do it over again.
|
||||
|
||||
Just to be really clear about this, if you ever find yourself writing three backticks followed by a language name, STOP!
|
||||
You have made a mistake. You can only ever put paths after triple backticks!
|
||||
|
||||
<example>
|
||||
Based on all the information I've gathered, here's a summary of how this system works:
|
||||
1. The README file is loaded into the system.
|
||||
2. The system finds the first two headers, including everything in between. In this case, that would be:
|
||||
|
||||
```path/to/README.md#L8-12
|
||||
# First Header
|
||||
|
||||
This is the info under the first header.
|
||||
|
||||
## Sub-header
|
||||
```
|
||||
|
||||
3. Then the system finds the last header in the README:
|
||||
|
||||
```path/to/README.md#L27-29
|
||||
## Last Header
|
||||
|
||||
This is the last header in the README.
|
||||
```
|
||||
|
||||
4. Finally, it passes this information on to the next process.
|
||||
</example>
|
||||
|
||||
<example>
|
||||
In Markdown, hash marks signify headings. For example:
|
||||
|
||||
```/dev/null/example.md#L1-3
|
||||
# Level 1 heading
|
||||
## Level 2 heading
|
||||
### Level 3 heading
|
||||
```
|
||||
</example>
|
||||
|
||||
Here are examples of ways you must never render code blocks:
|
||||
|
||||
<bad_example_do_not_do_this>
|
||||
In Markdown, hash marks signify headings. For example:
|
||||
|
||||
```
|
||||
# Level 1 heading
|
||||
## Level 2 heading
|
||||
### Level 3 heading
|
||||
```
|
||||
</bad_example_do_not_do_this>
|
||||
|
||||
This example is unacceptable because it does not include the path.
|
||||
|
||||
<bad_example_do_not_do_this>
|
||||
In Markdown, hash marks signify headings. For example:
|
||||
|
||||
```markdown
|
||||
# Level 1 heading
|
||||
## Level 2 heading
|
||||
### Level 3 heading
|
||||
```
|
||||
</bad_example_do_not_do_this>
|
||||
|
||||
This example is unacceptable because it has the language instead of the path.
|
||||
|
||||
<bad_example_do_not_do_this>
|
||||
In Markdown, hash marks signify headings. For example:
|
||||
|
||||
# Level 1 heading
|
||||
## Level 2 heading
|
||||
### Level 3 heading
|
||||
</bad_example_do_not_do_this>
|
||||
|
||||
This example is unacceptable because it uses indentation to mark the code block
|
||||
instead of backticks with a path.
|
||||
|
||||
<bad_example_do_not_do_this>
|
||||
In Markdown, hash marks signify headings. For example:
|
||||
|
||||
```markdown
|
||||
/dev/null/example.md#L1-3
|
||||
# Level 1 heading
|
||||
## Level 2 heading
|
||||
### Level 3 heading
|
||||
```
|
||||
</bad_example_do_not_do_this>
|
||||
|
||||
This example is unacceptable because the path is in the wrong place. The path must be directly after the opening backticks.
|
||||
</style>
|
||||
|
||||
The user has opened a project that contains the following root directories/files. Whenever you specify a path in the project, it must be a relative path which begins with one of these root directories/files:
|
||||
|
||||
{{#each worktrees}}
|
||||
- `{{root_name}}` (absolute path: `{{abs_path}}`)
|
||||
{{/each}}
|
||||
{{#if has_rules}}
|
||||
|
||||
There are rules that apply to these root directories:
|
||||
{{#each worktrees}}
|
||||
{{#if rules_file}}
|
||||
|
||||
`{{root_name}}/{{rules_file.path_in_worktree}}`:
|
||||
|
||||
``````
|
||||
{{{rules_file.text}}}
|
||||
``````
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
@@ -1 +0,0 @@
|
||||
In your response, make sure to remember and follow my instructions about how to format code blocks (and don't mention that you are remembering it, just follow the instructions).
|
||||
8
assets/prompts/project_slash_command.hbs
Normal file
@@ -0,0 +1,8 @@
|
||||
A software developer is asking a question about their project. The source files in their project have been indexed into a database of semantic text embeddings.
|
||||
Your task is to generate a list of 4 diverse search queries that can be run on this embedding database, in order to retrieve a list of code snippets
|
||||
that are relevant to the developer's question. Redundant search queries will be heavily penalized, so only include another query if it's sufficiently
|
||||
distinct from previous ones.
|
||||
|
||||
Here is the question that's been asked, together with context that the developer has added manually:
|
||||
|
||||
{{{context_buffer}}}
|
||||
@@ -25,7 +25,7 @@
|
||||
// Features that can be globally enabled or disabled
|
||||
"features": {
|
||||
// Which edit prediction provider to use.
|
||||
"edit_prediction_provider": "zed"
|
||||
"edit_prediction_provider": "copilot"
|
||||
},
|
||||
// The name of a font to use for rendering text in the editor
|
||||
"buffer_font_family": "Zed Plex Mono",
|
||||
@@ -115,15 +115,6 @@
|
||||
"confirm_quit": false,
|
||||
// Whether to restore last closed project when fresh Zed instance is opened.
|
||||
"restore_on_startup": "last_session",
|
||||
// Whether to attempt to restore previous file's state when opening it again.
|
||||
// The state is stored per pane.
|
||||
// When disabled, defaults are applied instead of the state restoration.
|
||||
//
|
||||
// E.g. for editors, selections, folds and scroll positions are restored, if the same file is closed and, later, opened again in the same pane.
|
||||
// When disabled, a single selection in the very beginning of the file, zero scroll position and no folds state is used as a default.
|
||||
//
|
||||
// Default: true
|
||||
"restore_on_file_reopen": true,
|
||||
// Size of the drop target in the editor.
|
||||
"drop_target_size": 0.2,
|
||||
// Whether the window should be closed when using 'close active item' on a window with no tabs.
|
||||
@@ -135,21 +126,9 @@
|
||||
// 3. Never close the window
|
||||
// "when_closing_with_no_tabs": "keep_window_open",
|
||||
"when_closing_with_no_tabs": "platform_default",
|
||||
// What to do when the last window is closed.
|
||||
// May take 2 values:
|
||||
// 1. Use the current platform's convention
|
||||
// "on_last_window_closed": "platform_default"
|
||||
// 2. Always quit the application
|
||||
// "on_last_window_closed": "quit_app",
|
||||
"on_last_window_closed": "platform_default",
|
||||
// Whether to use the system provided dialogs for Open and Save As.
|
||||
// When set to false, Zed will use the built-in keyboard-first pickers.
|
||||
"use_system_path_prompts": true,
|
||||
// Whether to use the system provided dialogs for prompts, such as confirmation
|
||||
// prompts.
|
||||
// When set to false, Zed will use its built-in prompts. Note that on Linux,
|
||||
// this option is ignored and Zed will always use the built-in prompts.
|
||||
"use_system_prompts": true,
|
||||
// Whether the cursor blinks in the editor.
|
||||
"cursor_blink": true,
|
||||
// Cursor shape for the default editor.
|
||||
@@ -164,8 +143,6 @@
|
||||
//
|
||||
// Default: not set, defaults to "bar"
|
||||
"cursor_shape": null,
|
||||
// Determines when the mouse cursor should be hidden in an editor or input box.
|
||||
"hide_mouse": "on_typing_and_movement",
|
||||
// How to highlight the current line in the editor.
|
||||
//
|
||||
// 1. Don't highlight the current line:
|
||||
@@ -177,10 +154,6 @@
|
||||
// 4. Highlight the full line (default):
|
||||
// "all"
|
||||
"current_line_highlight": "all",
|
||||
// Whether to highlight all occurrences of the selected text in an editor.
|
||||
"selection_highlight": true,
|
||||
// The debounce delay before querying highlights based on the selected text.
|
||||
"selection_highlight_debounce": 50,
|
||||
// The debounce delay before querying highlights from the language
|
||||
// server based on the current cursor location.
|
||||
"lsp_highlight_debounce": 75,
|
||||
@@ -192,14 +165,9 @@
|
||||
"show_completion_documentation": true,
|
||||
// Show method signatures in the editor, when inside parentheses.
|
||||
"auto_signature_help": false,
|
||||
// Whether to show the signature help after completion or a bracket pair inserted.
|
||||
// If `auto_signature_help` is enabled, this setting will be treated as enabled also.
|
||||
/// Whether to show the signature help after completion or a bracket pair inserted.
|
||||
/// If `auto_signature_help` is enabled, this setting will be treated as enabled also.
|
||||
"show_signature_help_after_edits": false,
|
||||
// What to do when go to definition yields no results.
|
||||
//
|
||||
// 1. Do nothing: `none`
|
||||
// 2. Find references for the same symbol: `find_all_references` (default)
|
||||
"go_to_definition_fallback": "find_all_references",
|
||||
// Whether to show wrap guides (vertical rulers) in the editor.
|
||||
// Setting this to true will show a guide at the 'preferred_line_length' value
|
||||
// if 'soft_wrap' is set to 'preferred_line_length', and will show any
|
||||
@@ -232,23 +200,6 @@
|
||||
// Otherwise(when `true`), the closing characters are always skipped over and auto-removed
|
||||
// no matter how they were inserted.
|
||||
"always_treat_brackets_as_autoclosed": false,
|
||||
// Controls where the `editor::Rewrap` action is allowed in the current language scope.
|
||||
//
|
||||
// This setting can take three values:
|
||||
//
|
||||
// 1. Only allow rewrapping in comments:
|
||||
// "in_comments"
|
||||
// 2. Only allow rewrapping in the current selection(s):
|
||||
// "in_selections"
|
||||
// 3. Allow rewrapping anywhere:
|
||||
// "anywhere"
|
||||
//
|
||||
// When using values other than `in_comments`, it is possible for the rewrapping to produce code
|
||||
// that is syntactically invalid. Keep this in mind when selecting which behavior you would like
|
||||
// to use.
|
||||
//
|
||||
// Note: This setting has no effect in Vim mode, as rewrap is already allowed everywhere.
|
||||
"allow_rewrap": "in_comments",
|
||||
// Controls whether edit predictions are shown immediately (true)
|
||||
// or manually by triggering `editor::ShowEditPrediction` (false).
|
||||
"show_edit_predictions": true,
|
||||
@@ -308,8 +259,6 @@
|
||||
"git_diff": true,
|
||||
// Whether to show buffer search results in the scrollbar.
|
||||
"search_results": true,
|
||||
// Whether to show selected text occurrences in the scrollbar.
|
||||
"selected_text": true,
|
||||
// Whether to show selected symbol occurrences in the scrollbar.
|
||||
"selected_symbol": true,
|
||||
// Which diagnostic indicators to show in the scrollbar:
|
||||
@@ -319,11 +268,11 @@
|
||||
// - "information": show only errors, warnings, and information
|
||||
// - "all" or true: show all diagnostics
|
||||
"diagnostics": "all",
|
||||
// Forcefully enable or disable the scrollbar for each axis
|
||||
/// Forcefully enable or disable the scrollbar for each axis
|
||||
"axes": {
|
||||
// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings.
|
||||
/// When false, forcefully disables the horizontal scrollbar. Otherwise, obey other settings.
|
||||
"horizontal": true,
|
||||
// When false, forcefully disables the vertical scrollbar. Otherwise, obey other settings.
|
||||
/// When false, forcefully disables the vertical scrollbar. Otherwise, obey other settings.
|
||||
"vertical": true
|
||||
}
|
||||
},
|
||||
@@ -345,30 +294,28 @@
|
||||
"code_actions": true,
|
||||
// Whether to show runnables buttons in the gutter.
|
||||
"runnables": true,
|
||||
// Whether to show breakpoints in the gutter.
|
||||
"breakpoints": true,
|
||||
// Whether to show fold buttons in the gutter.
|
||||
"folds": true
|
||||
},
|
||||
"indent_guides": {
|
||||
// Whether to show indent guides in the editor.
|
||||
/// Whether to show indent guides in the editor.
|
||||
"enabled": true,
|
||||
// The width of the indent guides in pixels, between 1 and 10.
|
||||
/// The width of the indent guides in pixels, between 1 and 10.
|
||||
"line_width": 1,
|
||||
// The width of the active indent guide in pixels, between 1 and 10.
|
||||
/// The width of the active indent guide in pixels, between 1 and 10.
|
||||
"active_line_width": 1,
|
||||
// Determines how indent guides are colored.
|
||||
// This setting can take the following three values:
|
||||
//
|
||||
// 1. "disabled"
|
||||
// 2. "fixed"
|
||||
// 3. "indent_aware"
|
||||
/// Determines how indent guides are colored.
|
||||
/// This setting can take the following three values:
|
||||
///
|
||||
/// 1. "disabled"
|
||||
/// 2. "fixed"
|
||||
/// 3. "indent_aware"
|
||||
"coloring": "fixed",
|
||||
// Determines how indent guide backgrounds are colored.
|
||||
// This setting can take the following two values:
|
||||
//
|
||||
// 1. "disabled"
|
||||
// 2. "indent_aware"
|
||||
/// Determines how indent guide backgrounds are colored.
|
||||
/// This setting can take the following two values:
|
||||
///
|
||||
/// 1. "disabled"
|
||||
/// 2. "indent_aware"
|
||||
"background_coloring": "disabled"
|
||||
},
|
||||
// Whether the editor will scroll beyond the last line.
|
||||
@@ -402,9 +349,6 @@
|
||||
// 3. Never populate the search query
|
||||
// "never"
|
||||
"seed_search_query_from_cursor": "always",
|
||||
// When enabled, automatically adjusts search case sensitivity based on your query.
|
||||
// If your search query contains any uppercase letters, the search becomes case-sensitive;
|
||||
// if it contains only lowercase letters, the search becomes case-insensitive.
|
||||
"use_smartcase_search": false,
|
||||
// Inlay hint related settings
|
||||
"inlay_hints": {
|
||||
@@ -424,22 +368,11 @@
|
||||
"edit_debounce_ms": 700,
|
||||
// Time to wait after scrolling the buffer, before requesting the hints,
|
||||
// set to 0 to disable debouncing.
|
||||
"scroll_debounce_ms": 50,
|
||||
// A set of modifiers which, when pressed, will toggle the visibility of inlay hints.
|
||||
// If the set if empty or not all the modifiers specified are pressed, inlay hints will not be toggled.
|
||||
"toggle_on_modifiers_press": {
|
||||
"control": false,
|
||||
"shift": false,
|
||||
"alt": false,
|
||||
"platform": false,
|
||||
"function": false
|
||||
}
|
||||
"scroll_debounce_ms": 50
|
||||
},
|
||||
"project_panel": {
|
||||
// Whether to show the project panel button in the status bar
|
||||
"button": true,
|
||||
// Whether to hide the gitignore entries in the project panel.
|
||||
"hide_gitignore": false,
|
||||
// Default width of the project panel.
|
||||
"default_width": 240,
|
||||
// Where to dock the project panel. Can be 'left' or 'right'.
|
||||
@@ -461,32 +394,32 @@
|
||||
// Whether to fold directories automatically and show compact folders
|
||||
// (e.g. "a/b/c" ) when a directory has only one subdirectory inside.
|
||||
"auto_fold_dirs": true,
|
||||
// Scrollbar-related settings
|
||||
/// Scrollbar-related settings
|
||||
"scrollbar": {
|
||||
// When to show the scrollbar in the project panel.
|
||||
// This setting can take five values:
|
||||
//
|
||||
// 1. null (default): Inherit editor settings
|
||||
// 2. Show the scrollbar if there's important information or
|
||||
// follow the system's configured behavior (default):
|
||||
// "auto"
|
||||
// 3. Match the system's configured behavior:
|
||||
// "system"
|
||||
// 4. Always show the scrollbar:
|
||||
// "always"
|
||||
// 5. Never show the scrollbar:
|
||||
// "never"
|
||||
/// When to show the scrollbar in the project panel.
|
||||
/// This setting can take five values:
|
||||
///
|
||||
/// 1. null (default): Inherit editor settings
|
||||
/// 2. Show the scrollbar if there's important information or
|
||||
/// follow the system's configured behavior (default):
|
||||
/// "auto"
|
||||
/// 3. Match the system's configured behavior:
|
||||
/// "system"
|
||||
/// 4. Always show the scrollbar:
|
||||
/// "always"
|
||||
/// 5. Never show the scrollbar:
|
||||
/// "never"
|
||||
"show": null
|
||||
},
|
||||
// Which files containing diagnostic errors/warnings to mark in the project panel.
|
||||
// This setting can take the following three values:
|
||||
//
|
||||
// 1. Do not mark any files:
|
||||
// "off"
|
||||
// 2. Only mark files with errors:
|
||||
// "errors"
|
||||
// 3. Mark files with errors and warnings:
|
||||
// "all"
|
||||
/// Which files containing diagnostic errors/warnings to mark in the project panel.
|
||||
/// This setting can take the following three values:
|
||||
///
|
||||
/// 1. Do not mark any files:
|
||||
/// "off"
|
||||
/// 2. Only mark files with errors:
|
||||
/// "errors"
|
||||
/// 3. Mark files with errors and warnings:
|
||||
/// "all"
|
||||
"show_diagnostics": "all",
|
||||
// Settings related to indent guides in the project panel.
|
||||
"indent_guides": {
|
||||
@@ -519,8 +452,8 @@
|
||||
// when a corresponding outline entry becomes active.
|
||||
// Gitignored entries are never auto revealed.
|
||||
"auto_reveal_entries": true,
|
||||
// Whether to fold directories automatically
|
||||
// when a directory has only one directory inside.
|
||||
/// Whether to fold directories automatically
|
||||
/// when a directory has only one directory inside.
|
||||
"auto_fold_dirs": true,
|
||||
// Settings related to indent guides in the outline panel.
|
||||
"indent_guides": {
|
||||
@@ -533,21 +466,21 @@
|
||||
// "never"
|
||||
"show": "always"
|
||||
},
|
||||
// Scrollbar-related settings
|
||||
/// Scrollbar-related settings
|
||||
"scrollbar": {
|
||||
// When to show the scrollbar in the project panel.
|
||||
// This setting can take five values:
|
||||
//
|
||||
// 1. null (default): Inherit editor settings
|
||||
// 2. Show the scrollbar if there's important information or
|
||||
// follow the system's configured behavior (default):
|
||||
// "auto"
|
||||
// 3. Match the system's configured behavior:
|
||||
// "system"
|
||||
// 4. Always show the scrollbar:
|
||||
// "always"
|
||||
// 5. Never show the scrollbar:
|
||||
// "never"
|
||||
/// When to show the scrollbar in the project panel.
|
||||
/// This setting can take five values:
|
||||
///
|
||||
/// 1. null (default): Inherit editor settings
|
||||
/// 2. Show the scrollbar if there's important information or
|
||||
/// follow the system's configured behavior (default):
|
||||
/// "auto"
|
||||
/// 3. Match the system's configured behavior:
|
||||
/// "system"
|
||||
/// 4. Always show the scrollbar:
|
||||
/// "always"
|
||||
/// 5. Never show the scrollbar:
|
||||
/// "never"
|
||||
"show": null
|
||||
}
|
||||
},
|
||||
@@ -572,7 +505,7 @@
|
||||
"git_panel": {
|
||||
// Whether to show the git panel button in the status bar.
|
||||
"button": true,
|
||||
// Where to show the git panel. Can be 'left' or 'right'.
|
||||
// Where to the git panel. Can be 'left' or 'right'.
|
||||
"dock": "left",
|
||||
// Default width of the git panel.
|
||||
"default_width": 360,
|
||||
@@ -580,12 +513,6 @@
|
||||
//
|
||||
// Default: icon
|
||||
"status_style": "icon",
|
||||
// What branch name to use if init.defaultBranch
|
||||
// is not set
|
||||
//
|
||||
// Default: main
|
||||
"fallback_branch_name": "main",
|
||||
|
||||
"scrollbar": {
|
||||
// When to show the scrollbar in the git panel.
|
||||
//
|
||||
@@ -624,65 +551,8 @@
|
||||
// The provider to use.
|
||||
"provider": "zed.dev",
|
||||
// The model to use.
|
||||
"model": "claude-3-5-sonnet-latest"
|
||||
},
|
||||
// The model to use when applying edits from the assistant.
|
||||
"editor_model": {
|
||||
// The provider to use.
|
||||
"provider": "zed.dev",
|
||||
// The model to use.
|
||||
"model": "claude-3-5-sonnet-latest"
|
||||
},
|
||||
// When enabled, the agent can run potentially destructive actions without asking for your confirmation.
|
||||
"always_allow_tool_actions": false,
|
||||
"default_profile": "write",
|
||||
"profiles": {
|
||||
"ask": {
|
||||
"name": "Ask",
|
||||
// We don't know which of the context server tools are safe for the "Ask" profile, so we don't enable them by default.
|
||||
// "enable_all_context_servers": true,
|
||||
"tools": {
|
||||
"diagnostics": true,
|
||||
"fetch": true,
|
||||
"list_directory": false,
|
||||
"now": true,
|
||||
"path_search": true,
|
||||
"read_file": true,
|
||||
"regex_search": true,
|
||||
"thinking": true
|
||||
}
|
||||
},
|
||||
"write": {
|
||||
"name": "Write",
|
||||
"enable_all_context_servers": true,
|
||||
"tools": {
|
||||
"bash": true,
|
||||
"batch_tool": true,
|
||||
"code_symbols": true,
|
||||
"copy_path": false,
|
||||
"create_file": true,
|
||||
"delete_path": false,
|
||||
"diagnostics": true,
|
||||
"find_replace_file": true,
|
||||
"fetch": true,
|
||||
"list_directory": false,
|
||||
"move_path": false,
|
||||
"now": true,
|
||||
"path_search": true,
|
||||
"read_file": true,
|
||||
"regex_search": true,
|
||||
"symbol_info": true,
|
||||
"thinking": true
|
||||
}
|
||||
}
|
||||
},
|
||||
// Where to show notifications when an agent has either completed
|
||||
// its response, or else needs confirmation before it can run a
|
||||
// tool action.
|
||||
// "primary_screen" - Show the notification only on your primary screen (default)
|
||||
// "all_screens" - Show these notifications on all screens
|
||||
// "never" - Never show these notifications
|
||||
"notify_when_agent_waiting": "primary_screen"
|
||||
"model": "claude-3-5-sonnet"
|
||||
}
|
||||
},
|
||||
// The settings for slash commands.
|
||||
"slash_commands": {
|
||||
@@ -728,7 +598,7 @@
|
||||
"show": true,
|
||||
// Whether or not to show the navigation history buttons.
|
||||
"show_nav_history_buttons": true,
|
||||
// Whether or not to show the tab bar buttons.
|
||||
/// Whether or not to show the tab bar buttons.
|
||||
"show_tab_bar_buttons": true
|
||||
},
|
||||
// Settings related to the editor's tabs
|
||||
@@ -736,19 +606,11 @@
|
||||
// Show git status colors in the editor tabs.
|
||||
"git_status": false,
|
||||
// Position of the close button on the editor tabs.
|
||||
// One of: ["right", "left", "hidden"]
|
||||
"close_position": "right",
|
||||
// Whether to show the file icon for a tab.
|
||||
"file_icons": false,
|
||||
// Controls the appearance behavior of the tab's close button.
|
||||
//
|
||||
// 1. Show it just upon hovering the tab. (default)
|
||||
// "hover"
|
||||
// 2. Show it persistently.
|
||||
// "always"
|
||||
// 3. Never show it, even if hovering it.
|
||||
// "hidden"
|
||||
"show_close_button": "hover",
|
||||
// Whether to always show the close button on tabs.
|
||||
"always_show_close_button": false,
|
||||
// What to do after closing the current tab.
|
||||
//
|
||||
// 1. Activate the tab that was open previously (default)
|
||||
@@ -758,16 +620,16 @@
|
||||
// 3. Activate the left neighbour tab if present
|
||||
// "left_neighbour"
|
||||
"activate_on_close": "history",
|
||||
// Which files containing diagnostic errors/warnings to mark in the tabs.
|
||||
// Diagnostics are only shown when file icons are also active.
|
||||
// This setting only works when can take the following three values:
|
||||
//
|
||||
// 1. Do not mark any files:
|
||||
// "off"
|
||||
// 2. Only mark files with errors:
|
||||
// "errors"
|
||||
// 3. Mark files with errors and warnings:
|
||||
// "all"
|
||||
/// Which files containing diagnostic errors/warnings to mark in the tabs.
|
||||
/// Diagnostics are only shown when file icons are also active.
|
||||
/// This setting only works when can take the following three values:
|
||||
///
|
||||
/// 1. Do not mark any files:
|
||||
/// "off"
|
||||
/// 2. Only mark files with errors:
|
||||
/// "errors"
|
||||
/// 3. Mark files with errors and warnings:
|
||||
/// "all"
|
||||
"show_diagnostics": "off"
|
||||
},
|
||||
// Settings related to preview tabs.
|
||||
@@ -808,8 +670,8 @@
|
||||
"remove_trailing_whitespace_on_save": true,
|
||||
// Whether to start a new line with a comment when a previous line is a comment as well.
|
||||
"extend_comment_on_newline": true,
|
||||
// Removes any lines containing only whitespace at the end of the file and
|
||||
// ensures just one newline at the end.
|
||||
// Whether or not to ensure there's a single newline at the end of a buffer
|
||||
// when saving it.
|
||||
"ensure_final_newline_on_save": true,
|
||||
// Whether or not to perform a buffer format before saving
|
||||
//
|
||||
@@ -866,28 +728,11 @@
|
||||
// Diagnostics configuration.
|
||||
"diagnostics": {
|
||||
// Whether to show warnings or not by default.
|
||||
"include_warnings": true,
|
||||
// Settings for inline diagnostics
|
||||
"inline": {
|
||||
// Whether to show diagnostics inline or not
|
||||
"enabled": false,
|
||||
// The delay in milliseconds to show inline diagnostics after the
|
||||
// last diagnostic update.
|
||||
"update_debounce_ms": 150,
|
||||
// The amount of padding between the end of the source line and the start
|
||||
// of the inline diagnostic in units of em widths.
|
||||
"padding": 4,
|
||||
// The minimum column to display inline diagnostics. This setting can be
|
||||
// used to horizontally align inline diagnostics at some column. Lines
|
||||
// longer than this value will still push diagnostics further to the right.
|
||||
"min_column": 0,
|
||||
// The minimum severity of the diagnostics to show inline.
|
||||
// Shows all diagnostics when not specified.
|
||||
"max_severity": null
|
||||
}
|
||||
"include_warnings": true
|
||||
},
|
||||
// Files or globs of files that will be excluded by Zed entirely. They will be skipped during file
|
||||
// scans, file searches, and not be displayed in the project file tree. Takes precedence over `file_scan_inclusions`.
|
||||
// Add files or globs of files that will be excluded by Zed entirely:
|
||||
// they will be skipped during FS scan(s), file tree and file search
|
||||
// will lack the corresponding file entries. Overrides `file_scan_inclusions`.
|
||||
"file_scan_exclusions": [
|
||||
"**/.git",
|
||||
"**/.svn",
|
||||
@@ -899,10 +744,10 @@
|
||||
"**/.classpath",
|
||||
"**/.settings"
|
||||
],
|
||||
// Files or globs of files that will be included by Zed, even when ignored by git. This is useful
|
||||
// for files that are not tracked by git, but are still important to your project. Note that globs
|
||||
// that are overly broad can slow down Zed's file scanning. `file_scan_exclusions` takes
|
||||
// precedence over these inclusions.
|
||||
// Add files or globs of files that will be included by Zed, even when
|
||||
// ignored by git. This is useful for files that are not tracked by git,
|
||||
// but are still important to your project. Note that globs that are
|
||||
// overly broad can slow down Zed's file scanning. Overridden by `file_scan_exclusions`.
|
||||
"file_scan_inclusions": [".env*"],
|
||||
// Git gutter behavior configuration.
|
||||
"git": {
|
||||
@@ -925,24 +770,8 @@
|
||||
//
|
||||
// The minimum column number to show the inline blame information at
|
||||
// "min_column": 0
|
||||
},
|
||||
// How git hunks are displayed visually in the editor.
|
||||
// This setting can take two values:
|
||||
//
|
||||
// 1. Show unstaged hunks filled and staged hunks hollow:
|
||||
// "hunk_style": "staged_hollow"
|
||||
// 2. Show unstaged hunks hollow and staged hunks filled:
|
||||
// "hunk_style": "unstaged_hollow"
|
||||
"hunk_style": "staged_hollow"
|
||||
}
|
||||
},
|
||||
// The list of custom Git hosting providers.
|
||||
"git_hosting_providers": [
|
||||
// {
|
||||
// "provider": "github",
|
||||
// "name": "BigCorp GitHub",
|
||||
// "base_url": "https://code.big-corp.com"
|
||||
// }
|
||||
],
|
||||
// Configuration for how direnv configuration should be loaded. May take 2 values:
|
||||
// 1. Load direnv configuration using `direnv export json` directly.
|
||||
// "load_direnv": "direct"
|
||||
@@ -953,19 +782,22 @@
|
||||
// A list of globs representing files that edit predictions should be disabled for.
|
||||
// There's a sensible default list of globs already included.
|
||||
// Any addition to this list will be merged with the default list.
|
||||
// Globs are matched relative to the worktree root,
|
||||
// except when starting with a slash (/) or equivalent in Windows.
|
||||
"disabled_globs": ["**/.env*", "**/*.pem", "**/*.key", "**/*.cert", "**/*.crt", "**/.dev.vars", "**/secrets.yml"],
|
||||
"disabled_globs": [
|
||||
"**/.env*",
|
||||
"**/*.pem",
|
||||
"**/*.key",
|
||||
"**/*.cert",
|
||||
"**/*.crt",
|
||||
"**/.dev.vars",
|
||||
"**/secrets.yml"
|
||||
],
|
||||
// When to show edit predictions previews in buffer.
|
||||
// This setting takes two possible values:
|
||||
// 1. Display predictions inline when there are no language server completions available.
|
||||
// "mode": "eager"
|
||||
// 2. Display predictions inline only when holding a modifier key (alt by default).
|
||||
// "mode": "subtle"
|
||||
"mode": "eager",
|
||||
// Whether edit predictions are enabled in the assistant panel.
|
||||
// This setting has no effect if globally disabled.
|
||||
"enabled_in_assistant": true
|
||||
// 1. Display inline when there are no language server completions available.
|
||||
// "mode": "eager_preview"
|
||||
// 2. Display inline when holding modifier key (alt by default).
|
||||
// "mode": "auto"
|
||||
"mode": "eager_preview"
|
||||
},
|
||||
// Settings specific to journaling
|
||||
"journal": {
|
||||
@@ -1049,7 +881,7 @@
|
||||
// "alternate_scroll": "on",
|
||||
// 2. Default alternate scroll mode to off
|
||||
// "alternate_scroll": "off",
|
||||
"alternate_scroll": "on",
|
||||
"alternate_scroll": "off",
|
||||
// Set whether the option key behaves as the meta key.
|
||||
// May take 2 values:
|
||||
// 1. Rely on default platform handling of option key, on macOS
|
||||
@@ -1101,21 +933,21 @@
|
||||
// Example: `echo -e "\e]2;New Title\007";`
|
||||
"breadcrumbs": true
|
||||
},
|
||||
// Scrollbar-related settings
|
||||
/// Scrollbar-related settings
|
||||
"scrollbar": {
|
||||
// When to show the scrollbar in the terminal.
|
||||
// This setting can take five values:
|
||||
//
|
||||
// 1. null (default): Inherit editor settings
|
||||
// 2. Show the scrollbar if there's important information or
|
||||
// follow the system's configured behavior (default):
|
||||
// "auto"
|
||||
// 3. Match the system's configured behavior:
|
||||
// "system"
|
||||
// 4. Always show the scrollbar:
|
||||
// "always"
|
||||
// 5. Never show the scrollbar:
|
||||
// "never"
|
||||
/// When to show the scrollbar in the terminal.
|
||||
/// This setting can take five values:
|
||||
///
|
||||
/// 1. null (default): Inherit editor settings
|
||||
/// 2. Show the scrollbar if there's important information or
|
||||
/// follow the system's configured behavior (default):
|
||||
/// "auto"
|
||||
/// 3. Match the system's configured behavior:
|
||||
/// "system"
|
||||
/// 4. Always show the scrollbar:
|
||||
/// "always"
|
||||
/// 5. Never show the scrollbar:
|
||||
/// "never"
|
||||
"show": null
|
||||
}
|
||||
// Set the terminal's font size. If this option is not included,
|
||||
@@ -1134,10 +966,9 @@
|
||||
// "max_scroll_history_lines": 10000,
|
||||
},
|
||||
"code_actions_on_format": {},
|
||||
// Settings related to running tasks.
|
||||
/// Settings related to running tasks.
|
||||
"tasks": {
|
||||
"variables": {},
|
||||
"enabled": true
|
||||
"variables": {}
|
||||
},
|
||||
// An object whose keys are language names, and whose values
|
||||
// are arrays of filenames or extensions of files that should
|
||||
@@ -1152,23 +983,24 @@
|
||||
// }
|
||||
//
|
||||
"file_types": {
|
||||
"Plain Text": ["txt"],
|
||||
"JSONC": ["**/.zed/**/*.json", "**/zed/**/*.json", "**/Zed/**/*.json", "**/.vscode/**/*.json"],
|
||||
"Shell Script": [".env.*"]
|
||||
},
|
||||
// By default use a recent system version of node, or install our own.
|
||||
// You can override this to use a version of node that is not in $PATH with:
|
||||
// {
|
||||
// "node": {
|
||||
// "path": "/path/to/node"
|
||||
// "npm_path": "/path/to/npm" (defaults to node_path/../npm)
|
||||
// }
|
||||
// }
|
||||
// or to ensure Zed always downloads and installs an isolated version of node:
|
||||
// {
|
||||
// "node": {
|
||||
// "ignore_system_version": true,
|
||||
// }
|
||||
// NOTE: changing this setting currently requires restarting Zed.
|
||||
/// By default use a recent system version of node, or install our own.
|
||||
/// You can override this to use a version of node that is not in $PATH with:
|
||||
/// {
|
||||
/// "node": {
|
||||
/// "path": "/path/to/node"
|
||||
/// "npm_path": "/path/to/npm" (defaults to node_path/../npm)
|
||||
/// }
|
||||
/// }
|
||||
/// or to ensure Zed always downloads and installs an isolated version of node:
|
||||
/// {
|
||||
/// "node": {
|
||||
/// "ignore_system_version": true,
|
||||
/// }
|
||||
/// NOTE: changing this setting currently requires restarting Zed.
|
||||
"node": {},
|
||||
// The extensions that Zed should automatically install on startup.
|
||||
//
|
||||
@@ -1177,52 +1009,6 @@
|
||||
"auto_install_extensions": {
|
||||
"html": true
|
||||
},
|
||||
// Controls how completions are processed for this language.
|
||||
"completions": {
|
||||
// Controls how words are completed.
|
||||
// For large documents, not all words may be fetched for completion.
|
||||
//
|
||||
// May take 3 values:
|
||||
// 1. "enabled"
|
||||
// Always fetch document's words for completions along with LSP completions.
|
||||
// 2. "fallback"
|
||||
// Only if LSP response errors or times out, use document's words to show completions.
|
||||
// 3. "disabled"
|
||||
// Never fetch or complete document's words for completions.
|
||||
// (Word-based completions can still be queried via a separate action)
|
||||
//
|
||||
// Default: fallback
|
||||
"words": "fallback",
|
||||
// Whether to fetch LSP completions or not.
|
||||
//
|
||||
// Default: true
|
||||
"lsp": true,
|
||||
// When fetching LSP completions, determines how long to wait for a response of a particular server.
|
||||
// When set to 0, waits indefinitely.
|
||||
//
|
||||
// Default: 0
|
||||
"lsp_fetch_timeout_ms": 0,
|
||||
// Controls what range to replace when accepting LSP completions.
|
||||
//
|
||||
// When LSP servers give an `InsertReplaceEdit` completion, they provides two ranges: `insert` and `replace`. Usually, `insert`
|
||||
// contains the word prefix before your cursor and `replace` contains the whole word.
|
||||
//
|
||||
// Effectively, this setting just changes whether Zed will use the received range for `insert` or `replace`, so the results may
|
||||
// differ depending on the underlying LSP server.
|
||||
//
|
||||
// Possible values:
|
||||
// 1. "insert"
|
||||
// Replaces text before the cursor, using the `insert` range described in the LSP specification.
|
||||
// 2. "replace"
|
||||
// Replaces text before and after the cursor, using the `replace` range described in the LSP specification.
|
||||
// 3. "replace_subsequence"
|
||||
// Behaves like `"replace"` if the text that would be replaced is a subsequence of the completion text,
|
||||
// and like `"insert"` otherwise.
|
||||
// 4. "replace_suffix"
|
||||
// Behaves like `"replace"` if the text after the cursor is a suffix of the completion, and like
|
||||
// `"insert"` otherwise.
|
||||
"lsp_insert_mode": "replace_suffix"
|
||||
},
|
||||
// Different settings for specific languages.
|
||||
"languages": {
|
||||
"Astro": {
|
||||
@@ -1260,7 +1046,6 @@
|
||||
"tab_size": 2
|
||||
},
|
||||
"Diff": {
|
||||
"show_edit_predictions": false,
|
||||
"remove_trailing_whitespace_on_save": false,
|
||||
"ensure_final_newline_on_save": false
|
||||
},
|
||||
@@ -1270,9 +1055,6 @@
|
||||
"Erlang": {
|
||||
"language_servers": ["erlang-ls", "!elp", "..."]
|
||||
},
|
||||
"Git Commit": {
|
||||
"allow_rewrap": "anywhere"
|
||||
},
|
||||
"Go": {
|
||||
"code_actions_on_format": {
|
||||
"source.organizeImports": true
|
||||
@@ -1313,19 +1095,9 @@
|
||||
"allowed": true
|
||||
}
|
||||
},
|
||||
"LaTeX": {
|
||||
"format_on_save": "on",
|
||||
"formatter": "language_server",
|
||||
"language_servers": ["texlab", "..."],
|
||||
"prettier": {
|
||||
"allowed": false
|
||||
}
|
||||
},
|
||||
"Markdown": {
|
||||
"format_on_save": "off",
|
||||
"use_on_type_format": false,
|
||||
"allow_rewrap": "anywhere",
|
||||
"soft_wrap": "editor_width",
|
||||
"prettier": {
|
||||
"allowed": true
|
||||
}
|
||||
@@ -1338,9 +1110,6 @@
|
||||
"parser": "php"
|
||||
}
|
||||
},
|
||||
"Plain Text": {
|
||||
"allow_rewrap": "anywhere"
|
||||
},
|
||||
"Ruby": {
|
||||
"language_servers": ["solargraph", "!ruby-lsp", "!rubocop", "..."]
|
||||
},
|
||||
@@ -1449,16 +1218,10 @@
|
||||
// "semi": false,
|
||||
// "singleQuote": true
|
||||
},
|
||||
// Settings for auto-closing of JSX tags.
|
||||
"jsx_tag_auto_close": {
|
||||
"enabled": true
|
||||
},
|
||||
// LSP Specific settings.
|
||||
"lsp": {
|
||||
// Specify the LSP name as a key here.
|
||||
// "rust-analyzer": {
|
||||
// // A special flag for rust-analyzer integration, to use server-provided tasks
|
||||
// enable_lsp_tasks": true,
|
||||
// // These initialization options are merged into Zed's defaults
|
||||
// "initialization_options": {
|
||||
// "check": {
|
||||
@@ -1478,7 +1241,6 @@
|
||||
},
|
||||
// Vim settings
|
||||
"vim": {
|
||||
"default_mode": "normal",
|
||||
"toggle_relative_line_numbers": false,
|
||||
"use_system_clipboard": "always",
|
||||
"use_multiline_find": false,
|
||||
@@ -1509,6 +1271,11 @@
|
||||
"dev": {
|
||||
// "theme": "Andromeda"
|
||||
},
|
||||
// Task-related settings.
|
||||
"task": {
|
||||
// Whether to show task status indicator in the status bar. Default: true
|
||||
"show_status_indicator": true
|
||||
},
|
||||
// Whether to show full labels in line indicator or short ones
|
||||
//
|
||||
// Values:
|
||||
|
||||
@@ -43,8 +43,6 @@
|
||||
// "args": ["--login"]
|
||||
// }
|
||||
// }
|
||||
"shell": "system",
|
||||
// Represents the tags for inline runnable indicators, or spawning multiple tasks at once.
|
||||
"tags": []
|
||||
"shell": "system"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -6,7 +6,15 @@
|
||||
{
|
||||
"name": "Gruvbox Dark",
|
||||
"appearance": "dark",
|
||||
"accents": ["#cc241dff", "#98971aff", "#d79921ff", "#458588ff", "#b16286ff", "#689d6aff", "#d65d0eff"],
|
||||
"accents": [
|
||||
"#cc241dff",
|
||||
"#98971aff",
|
||||
"#d79921ff",
|
||||
"#458588ff",
|
||||
"#b16286ff",
|
||||
"#689d6aff",
|
||||
"#d65d0eff"
|
||||
],
|
||||
"style": {
|
||||
"border": "#5b534dff",
|
||||
"border.variant": "#494340ff",
|
||||
@@ -87,9 +95,9 @@
|
||||
"terminal.ansi.blue": "#83a598ff",
|
||||
"terminal.ansi.bright_blue": "#414f4aff",
|
||||
"terminal.ansi.dim_blue": "#c0d2cbff",
|
||||
"terminal.ansi.magenta": "#d3869bff",
|
||||
"terminal.ansi.bright_magenta": "#8e5868ff",
|
||||
"terminal.ansi.dim_magenta": "#ff9ebbff",
|
||||
"terminal.ansi.magenta": "#a89984ff",
|
||||
"terminal.ansi.bright_magenta": "#514a41ff",
|
||||
"terminal.ansi.dim_magenta": "#d2cabfff",
|
||||
"terminal.ansi.cyan": "#8ec07cff",
|
||||
"terminal.ansi.bright_cyan": "#45603eff",
|
||||
"terminal.ansi.dim_cyan": "#c7dfbdff",
|
||||
@@ -98,8 +106,15 @@
|
||||
"terminal.ansi.dim_white": "#b0a189ff",
|
||||
"link_text.hover": "#83a598ff",
|
||||
"version_control.added": "#b7bb26ff",
|
||||
"version_control.modified": "#f9bd2fff",
|
||||
"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",
|
||||
@@ -371,11 +386,6 @@
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#ebdbb2ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
@@ -391,7 +401,15 @@
|
||||
{
|
||||
"name": "Gruvbox Dark Hard",
|
||||
"appearance": "dark",
|
||||
"accents": ["#cc241dff", "#98971aff", "#d79921ff", "#458588ff", "#b16286ff", "#689d6aff", "#d65d0eff"],
|
||||
"accents": [
|
||||
"#cc241dff",
|
||||
"#98971aff",
|
||||
"#d79921ff",
|
||||
"#458588ff",
|
||||
"#b16286ff",
|
||||
"#689d6aff",
|
||||
"#d65d0eff"
|
||||
],
|
||||
"style": {
|
||||
"border": "#5b534dff",
|
||||
"border.variant": "#494340ff",
|
||||
@@ -472,9 +490,9 @@
|
||||
"terminal.ansi.blue": "#83a598ff",
|
||||
"terminal.ansi.bright_blue": "#414f4aff",
|
||||
"terminal.ansi.dim_blue": "#c0d2cbff",
|
||||
"terminal.ansi.magenta": "#d3869bff",
|
||||
"terminal.ansi.bright_magenta": "#8e5868ff",
|
||||
"terminal.ansi.dim_magenta": "#ff9ebbff",
|
||||
"terminal.ansi.magenta": "#a89984ff",
|
||||
"terminal.ansi.bright_magenta": "#514a41ff",
|
||||
"terminal.ansi.dim_magenta": "#d2cabfff",
|
||||
"terminal.ansi.cyan": "#8ec07cff",
|
||||
"terminal.ansi.bright_cyan": "#45603eff",
|
||||
"terminal.ansi.dim_cyan": "#c7dfbdff",
|
||||
@@ -483,8 +501,15 @@
|
||||
"terminal.ansi.dim_white": "#b0a189ff",
|
||||
"link_text.hover": "#83a598ff",
|
||||
"version_control.added": "#b7bb26ff",
|
||||
"version_control.modified": "#f9bd2fff",
|
||||
"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",
|
||||
@@ -756,11 +781,6 @@
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#ebdbb2ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
@@ -776,7 +796,15 @@
|
||||
{
|
||||
"name": "Gruvbox Dark Soft",
|
||||
"appearance": "dark",
|
||||
"accents": ["#cc241dff", "#98971aff", "#d79921ff", "#458588ff", "#b16286ff", "#689d6aff", "#d65d0eff"],
|
||||
"accents": [
|
||||
"#cc241dff",
|
||||
"#98971aff",
|
||||
"#d79921ff",
|
||||
"#458588ff",
|
||||
"#b16286ff",
|
||||
"#689d6aff",
|
||||
"#d65d0eff"
|
||||
],
|
||||
"style": {
|
||||
"border": "#5b534dff",
|
||||
"border.variant": "#494340ff",
|
||||
@@ -857,9 +885,9 @@
|
||||
"terminal.ansi.blue": "#83a598ff",
|
||||
"terminal.ansi.bright_blue": "#414f4aff",
|
||||
"terminal.ansi.dim_blue": "#c0d2cbff",
|
||||
"terminal.ansi.magenta": "#d3869bff",
|
||||
"terminal.ansi.bright_magenta": "#8e5868ff",
|
||||
"terminal.ansi.dim_magenta": "#ff9ebbff",
|
||||
"terminal.ansi.magenta": "#a89984ff",
|
||||
"terminal.ansi.bright_magenta": "#514a41ff",
|
||||
"terminal.ansi.dim_magenta": "#d2cabfff",
|
||||
"terminal.ansi.cyan": "#8ec07cff",
|
||||
"terminal.ansi.bright_cyan": "#45603eff",
|
||||
"terminal.ansi.dim_cyan": "#c7dfbdff",
|
||||
@@ -868,8 +896,15 @@
|
||||
"terminal.ansi.dim_white": "#b0a189ff",
|
||||
"link_text.hover": "#83a598ff",
|
||||
"version_control.added": "#b7bb26ff",
|
||||
"version_control.modified": "#f9bd2fff",
|
||||
"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",
|
||||
@@ -1141,11 +1176,6 @@
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#ebdbb2ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#83a598ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
@@ -1161,7 +1191,15 @@
|
||||
{
|
||||
"name": "Gruvbox Light",
|
||||
"appearance": "light",
|
||||
"accents": ["#cc241dff", "#98971aff", "#d79921ff", "#458588ff", "#b16286ff", "#689d6aff", "#d65d0eff"],
|
||||
"accents": [
|
||||
"#cc241dff",
|
||||
"#98971aff",
|
||||
"#d79921ff",
|
||||
"#458588ff",
|
||||
"#b16286ff",
|
||||
"#689d6aff",
|
||||
"#d65d0eff"
|
||||
],
|
||||
"style": {
|
||||
"border": "#c8b899ff",
|
||||
"border.variant": "#ddcca7ff",
|
||||
@@ -1242,9 +1280,9 @@
|
||||
"terminal.ansi.blue": "#0b6678ff",
|
||||
"terminal.ansi.bright_blue": "#8fb0baff",
|
||||
"terminal.ansi.dim_blue": "#14333bff",
|
||||
"terminal.ansi.magenta": "#8f3e71ff",
|
||||
"terminal.ansi.bright_magenta": "#c76da0ff",
|
||||
"terminal.ansi.dim_magenta": "#5c2848ff",
|
||||
"terminal.ansi.magenta": "#7c6f64ff",
|
||||
"terminal.ansi.bright_magenta": "#bcb5afff",
|
||||
"terminal.ansi.dim_magenta": "#3e3833ff",
|
||||
"terminal.ansi.cyan": "#437b59ff",
|
||||
"terminal.ansi.bright_cyan": "#9fbca8ff",
|
||||
"terminal.ansi.dim_cyan": "#253e2eff",
|
||||
@@ -1252,9 +1290,16 @@
|
||||
"terminal.ansi.bright_white": "#282828ff",
|
||||
"terminal.ansi.dim_white": "#73675eff",
|
||||
"link_text.hover": "#0b6678ff",
|
||||
"version_control.added": "#797410ff",
|
||||
"version_control.modified": "#b57615ff",
|
||||
"version_control.deleted": "#9d0308ff",
|
||||
"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",
|
||||
@@ -1526,11 +1571,6 @@
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#282828ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#066578ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
@@ -1546,7 +1586,15 @@
|
||||
{
|
||||
"name": "Gruvbox Light Hard",
|
||||
"appearance": "light",
|
||||
"accents": ["#cc241dff", "#98971aff", "#d79921ff", "#458588ff", "#b16286ff", "#689d6aff", "#d65d0eff"],
|
||||
"accents": [
|
||||
"#cc241dff",
|
||||
"#98971aff",
|
||||
"#d79921ff",
|
||||
"#458588ff",
|
||||
"#b16286ff",
|
||||
"#689d6aff",
|
||||
"#d65d0eff"
|
||||
],
|
||||
"style": {
|
||||
"border": "#c8b899ff",
|
||||
"border.variant": "#ddcca7ff",
|
||||
@@ -1627,9 +1675,9 @@
|
||||
"terminal.ansi.blue": "#0b6678ff",
|
||||
"terminal.ansi.bright_blue": "#8fb0baff",
|
||||
"terminal.ansi.dim_blue": "#14333bff",
|
||||
"terminal.ansi.magenta": "#8f3e71ff",
|
||||
"terminal.ansi.bright_magenta": "#c76da0ff",
|
||||
"terminal.ansi.dim_magenta": "#5c2848ff",
|
||||
"terminal.ansi.magenta": "#7c6f64ff",
|
||||
"terminal.ansi.bright_magenta": "#bcb5afff",
|
||||
"terminal.ansi.dim_magenta": "#3e3833ff",
|
||||
"terminal.ansi.cyan": "#437b59ff",
|
||||
"terminal.ansi.bright_cyan": "#9fbca8ff",
|
||||
"terminal.ansi.dim_cyan": "#253e2eff",
|
||||
@@ -1637,9 +1685,16 @@
|
||||
"terminal.ansi.bright_white": "#282828ff",
|
||||
"terminal.ansi.dim_white": "#73675eff",
|
||||
"link_text.hover": "#0b6678ff",
|
||||
"version_control.added": "#797410ff",
|
||||
"version_control.modified": "#b57615ff",
|
||||
"version_control.deleted": "#9d0308ff",
|
||||
"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",
|
||||
@@ -1911,11 +1966,6 @@
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#282828ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#066578ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
@@ -1931,7 +1981,15 @@
|
||||
{
|
||||
"name": "Gruvbox Light Soft",
|
||||
"appearance": "light",
|
||||
"accents": ["#cc241dff", "#98971aff", "#d79921ff", "#458588ff", "#b16286ff", "#689d6aff", "#d65d0eff"],
|
||||
"accents": [
|
||||
"#cc241dff",
|
||||
"#98971aff",
|
||||
"#d79921ff",
|
||||
"#458588ff",
|
||||
"#b16286ff",
|
||||
"#689d6aff",
|
||||
"#d65d0eff"
|
||||
],
|
||||
"style": {
|
||||
"border": "#c8b899ff",
|
||||
"border.variant": "#ddcca7ff",
|
||||
@@ -2012,9 +2070,9 @@
|
||||
"terminal.ansi.blue": "#0b6678ff",
|
||||
"terminal.ansi.bright_blue": "#8fb0baff",
|
||||
"terminal.ansi.dim_blue": "#14333bff",
|
||||
"terminal.ansi.magenta": "#8f3e71ff",
|
||||
"terminal.ansi.bright_magenta": "#c76da0ff",
|
||||
"terminal.ansi.dim_magenta": "#5c2848ff",
|
||||
"terminal.ansi.magenta": "#7c6f64ff",
|
||||
"terminal.ansi.bright_magenta": "#bcb5afff",
|
||||
"terminal.ansi.dim_magenta": "#3e3833ff",
|
||||
"terminal.ansi.cyan": "#437b59ff",
|
||||
"terminal.ansi.bright_cyan": "#9fbca8ff",
|
||||
"terminal.ansi.dim_cyan": "#253e2eff",
|
||||
@@ -2022,9 +2080,16 @@
|
||||
"terminal.ansi.bright_white": "#282828ff",
|
||||
"terminal.ansi.dim_white": "#73675eff",
|
||||
"link_text.hover": "#0b6678ff",
|
||||
"version_control.added": "#797410ff",
|
||||
"version_control.modified": "#b57615ff",
|
||||
"version_control.deleted": "#9d0308ff",
|
||||
"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",
|
||||
@@ -2296,11 +2361,6 @@
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#282828ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
"variable.special": {
|
||||
"color": "#066578ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
|
||||
@@ -96,9 +96,16 @@
|
||||
"terminal.ansi.bright_white": "#dce0e5ff",
|
||||
"terminal.ansi.dim_white": "#575d65ff",
|
||||
"link_text.hover": "#74ade8ff",
|
||||
"version_control.added": "#27a657ff",
|
||||
"version_control.modified": "#d3b020ff",
|
||||
"version_control.deleted": "#e06c76ff",
|
||||
"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",
|
||||
@@ -365,7 +372,7 @@
|
||||
"font_weight": null
|
||||
},
|
||||
"variable": {
|
||||
"color": "#acb2beff",
|
||||
"color": "#dce0e5ff",
|
||||
"font_style": null,
|
||||
"font_weight": null
|
||||
},
|
||||
@@ -444,7 +451,7 @@
|
||||
"editor.invisible": "#a3a3a4ff",
|
||||
"editor.wrap_guide": "#383a410d",
|
||||
"editor.active_wrap_guide": "#383a411a",
|
||||
"editor.document_highlight.read_background": "#5c78e225",
|
||||
"editor.document_highlight.read_background": "#5c78e21a",
|
||||
"editor.document_highlight.write_background": "#a3a3a466",
|
||||
"terminal.background": "#fafafaff",
|
||||
"terminal.foreground": "#242529ff",
|
||||
@@ -475,9 +482,6 @@
|
||||
"terminal.ansi.bright_white": "#242529ff",
|
||||
"terminal.ansi.dim_white": "#97979aff",
|
||||
"link_text.hover": "#5c78e2ff",
|
||||
"version_control.added": "#27a657ff",
|
||||
"version_control.modified": "#d3b020ff",
|
||||
"version_control.deleted": "#e06c76ff",
|
||||
"conflict": "#a48819ff",
|
||||
"conflict.background": "#faf2e6ff",
|
||||
"conflict.border": "#f4e7d1ff",
|
||||
|
||||
@@ -25,7 +25,6 @@ smallvec.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
editor = { workspace = true, features = ["test-support"] }
|
||||
|
||||
@@ -3,29 +3,17 @@ use editor::Editor;
|
||||
use extension_host::ExtensionStore;
|
||||
use futures::StreamExt;
|
||||
use gpui::{
|
||||
Animation, AnimationExt as _, App, Context, CursorStyle, Entity, EventEmitter,
|
||||
InteractiveElement as _, ParentElement as _, Render, SharedString, StatefulInteractiveElement,
|
||||
Styled, Transformation, Window, actions, percentage,
|
||||
actions, percentage, Animation, AnimationExt as _, App, Context, CursorStyle, Entity,
|
||||
EventEmitter, InteractiveElement as _, ParentElement as _, Render, SharedString,
|
||||
StatefulInteractiveElement, Styled, Transformation, Window,
|
||||
};
|
||||
use language::{BinaryStatus, LanguageRegistry, LanguageServerId};
|
||||
use project::{
|
||||
EnvironmentErrorMessage, LanguageServerProgress, LspStoreEvent, Project,
|
||||
ProjectEnvironmentEvent,
|
||||
git_store::{GitStoreEvent, Repository},
|
||||
};
|
||||
use project::{EnvironmentErrorMessage, LanguageServerProgress, Project, WorktreeId};
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
fmt::Write,
|
||||
path::Path,
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use ui::{ButtonLike, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*};
|
||||
use std::{cmp::Reverse, fmt::Write, sync::Arc, time::Duration};
|
||||
use ui::{prelude::*, ButtonLike, ContextMenu, PopoverMenu, PopoverMenuHandle, Tooltip};
|
||||
use util::truncate_and_trailoff;
|
||||
use workspace::{StatusItemView, Workspace, item::ItemHandle};
|
||||
|
||||
const GIT_OPERATION_DELAY: Duration = Duration::from_millis(0);
|
||||
use workspace::{item::ItemHandle, StatusItemView, Workspace};
|
||||
|
||||
actions!(activity_indicator, [ShowErrorMessage]);
|
||||
|
||||
@@ -72,9 +60,9 @@ impl ActivityIndicator {
|
||||
let auto_updater = AutoUpdater::get(cx);
|
||||
let this = cx.new(|cx| {
|
||||
let mut status_events = languages.language_server_binary_statuses();
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
while let Some((name, status)) = status_events.next().await {
|
||||
this.update(cx, |this: &mut ActivityIndicator, cx| {
|
||||
this.update(&mut cx, |this: &mut ActivityIndicator, cx| {
|
||||
this.statuses.retain(|s| s.name != name);
|
||||
this.statuses.push(ServerStatus { name, status });
|
||||
cx.notify();
|
||||
@@ -85,9 +73,9 @@ impl ActivityIndicator {
|
||||
.detach();
|
||||
|
||||
let mut status_events = languages.dap_server_binary_statuses();
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
while let Some((name, status)) = status_events.next().await {
|
||||
this.update(cx, |this, cx| {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.statuses.retain(|s| s.name != name);
|
||||
this.statuses.push(ServerStatus { name, status });
|
||||
cx.notify();
|
||||
@@ -97,31 +85,7 @@ impl ActivityIndicator {
|
||||
})
|
||||
.detach();
|
||||
|
||||
cx.subscribe(
|
||||
&project.read(cx).lsp_store(),
|
||||
|_, _, event, cx| match event {
|
||||
LspStoreEvent::LanguageServerUpdate { .. } => cx.notify(),
|
||||
_ => {}
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
|
||||
cx.subscribe(
|
||||
&project.read(cx).environment().clone(),
|
||||
|_, _, event, cx| match event {
|
||||
ProjectEnvironmentEvent::ErrorsUpdated => cx.notify(),
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
|
||||
cx.subscribe(
|
||||
&project.read(cx).git_store().clone(),
|
||||
|_, _, event: &GitStoreEvent, cx| match event {
|
||||
project::git_store::GitStoreEvent::JobsUpdated => cx.notify(),
|
||||
_ => {}
|
||||
},
|
||||
)
|
||||
.detach();
|
||||
cx.observe(&project, |_, _, cx| cx.notify()).detach();
|
||||
|
||||
if let Some(auto_updater) = auto_updater.as_ref() {
|
||||
cx.observe(auto_updater, |_, _, cx| cx.notify()).detach();
|
||||
@@ -141,9 +105,9 @@ impl ActivityIndicator {
|
||||
let project = project.clone();
|
||||
let error = error.clone();
|
||||
let server_name = server_name.clone();
|
||||
cx.spawn_in(window, async move |workspace, cx| {
|
||||
cx.spawn_in(window, |workspace, mut cx| async move {
|
||||
let buffer = create_buffer.await?;
|
||||
buffer.update(cx, |buffer, cx| {
|
||||
buffer.update(&mut cx, |buffer, cx| {
|
||||
buffer.edit(
|
||||
[(
|
||||
0..0,
|
||||
@@ -154,7 +118,7 @@ impl ActivityIndicator {
|
||||
);
|
||||
buffer.set_capability(language::Capability::ReadOnly, cx);
|
||||
})?;
|
||||
workspace.update_in(cx, |workspace, window, cx| {
|
||||
workspace.update_in(&mut cx, |workspace, window, cx| {
|
||||
workspace.add_item_to_active_pane(
|
||||
Box::new(cx.new(|cx| {
|
||||
Editor::for_buffer(buffer, Some(project.clone()), window, cx)
|
||||
@@ -236,14 +200,13 @@ impl ActivityIndicator {
|
||||
fn pending_environment_errors<'a>(
|
||||
&'a self,
|
||||
cx: &'a App,
|
||||
) -> impl Iterator<Item = (&'a Arc<Path>, &'a EnvironmentErrorMessage)> {
|
||||
) -> impl Iterator<Item = (&'a WorktreeId, &'a EnvironmentErrorMessage)> {
|
||||
self.project.read(cx).shell_environment_errors(cx)
|
||||
}
|
||||
|
||||
fn content_to_render(&mut self, cx: &mut Context<Self>) -> Option<Content> {
|
||||
// Show if any direnv calls failed
|
||||
if let Some((abs_path, error)) = self.pending_environment_errors(cx).next() {
|
||||
let abs_path = abs_path.clone();
|
||||
if let Some((&worktree_id, error)) = self.pending_environment_errors(cx).next() {
|
||||
return Some(Content {
|
||||
icon: Some(
|
||||
Icon::new(IconName::Warning)
|
||||
@@ -253,7 +216,7 @@ impl ActivityIndicator {
|
||||
message: error.0.clone(),
|
||||
on_click: Some(Arc::new(move |this, window, cx| {
|
||||
this.project.update(cx, |project, cx| {
|
||||
project.remove_environment_error(&abs_path, cx);
|
||||
project.remove_environment_error(cx, worktree_id);
|
||||
});
|
||||
window.dispatch_action(Box::new(workspace::OpenLog), cx);
|
||||
})),
|
||||
@@ -303,34 +266,6 @@ impl ActivityIndicator {
|
||||
});
|
||||
}
|
||||
|
||||
let current_job = self
|
||||
.project
|
||||
.read(cx)
|
||||
.active_repository(cx)
|
||||
.map(|r| r.read(cx))
|
||||
.and_then(Repository::current_job);
|
||||
// Show any long-running git command
|
||||
if let Some(job_info) = current_job {
|
||||
if Instant::now() - job_info.start >= GIT_OPERATION_DELAY {
|
||||
return Some(Content {
|
||||
icon: Some(
|
||||
Icon::new(IconName::ArrowCircle)
|
||||
.size(IconSize::Small)
|
||||
.with_animation(
|
||||
"arrow-circle",
|
||||
Animation::new(Duration::from_secs(2)).repeat(),
|
||||
|icon, delta| {
|
||||
icon.transform(Transformation::rotate(percentage(delta)))
|
||||
},
|
||||
)
|
||||
.into_any_element(),
|
||||
),
|
||||
message: job_info.message.into(),
|
||||
on_click: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Show any language server installation info.
|
||||
let mut downloading = SmallVec::<[_; 3]>::new();
|
||||
let mut checking_for_update = SmallVec::<[_; 3]>::new();
|
||||
|
||||
@@ -1,443 +0,0 @@
|
||||
mod add_context_server_modal;
|
||||
mod manage_profiles_modal;
|
||||
mod tool_picker;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use assistant_settings::AssistantSettings;
|
||||
use assistant_tool::{ToolSource, ToolWorkingSet};
|
||||
use collections::HashMap;
|
||||
use context_server::manager::ContextServerManager;
|
||||
use fs::Fs;
|
||||
use gpui::{Action, AnyView, App, Entity, EventEmitter, FocusHandle, Focusable, Subscription};
|
||||
use language_model::{LanguageModelProvider, LanguageModelProviderId, LanguageModelRegistry};
|
||||
use settings::{Settings, update_settings_file};
|
||||
use ui::{Disclosure, Divider, DividerColor, ElevationIndex, Indicator, Switch, prelude::*};
|
||||
use util::ResultExt as _;
|
||||
use zed_actions::ExtensionCategoryFilter;
|
||||
|
||||
pub(crate) use add_context_server_modal::AddContextServerModal;
|
||||
pub(crate) use manage_profiles_modal::ManageProfilesModal;
|
||||
|
||||
use crate::AddContextServer;
|
||||
|
||||
pub struct AssistantConfiguration {
|
||||
fs: Arc<dyn Fs>,
|
||||
focus_handle: FocusHandle,
|
||||
configuration_views_by_provider: HashMap<LanguageModelProviderId, AnyView>,
|
||||
context_server_manager: Entity<ContextServerManager>,
|
||||
expanded_context_server_tools: HashMap<Arc<str>, bool>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
_registry_subscription: Subscription,
|
||||
}
|
||||
|
||||
impl AssistantConfiguration {
|
||||
pub fn new(
|
||||
fs: Arc<dyn Fs>,
|
||||
context_server_manager: Entity<ContextServerManager>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let focus_handle = cx.focus_handle();
|
||||
|
||||
let registry_subscription = cx.subscribe_in(
|
||||
&LanguageModelRegistry::global(cx),
|
||||
window,
|
||||
|this, _, event: &language_model::Event, window, cx| match event {
|
||||
language_model::Event::AddedProvider(provider_id) => {
|
||||
let provider = LanguageModelRegistry::read_global(cx).provider(provider_id);
|
||||
if let Some(provider) = provider {
|
||||
this.add_provider_configuration_view(&provider, window, cx);
|
||||
}
|
||||
}
|
||||
language_model::Event::RemovedProvider(provider_id) => {
|
||||
this.remove_provider_configuration_view(provider_id);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
);
|
||||
|
||||
let mut this = Self {
|
||||
fs,
|
||||
focus_handle,
|
||||
configuration_views_by_provider: HashMap::default(),
|
||||
context_server_manager,
|
||||
expanded_context_server_tools: HashMap::default(),
|
||||
tools,
|
||||
_registry_subscription: registry_subscription,
|
||||
};
|
||||
this.build_provider_configuration_views(window, cx);
|
||||
this
|
||||
}
|
||||
|
||||
fn build_provider_configuration_views(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let providers = LanguageModelRegistry::read_global(cx).providers();
|
||||
for provider in providers {
|
||||
self.add_provider_configuration_view(&provider, window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_provider_configuration_view(&mut self, provider_id: &LanguageModelProviderId) {
|
||||
self.configuration_views_by_provider.remove(provider_id);
|
||||
}
|
||||
|
||||
fn add_provider_configuration_view(
|
||||
&mut self,
|
||||
provider: &Arc<dyn LanguageModelProvider>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let configuration_view = provider.configuration_view(window, cx);
|
||||
self.configuration_views_by_provider
|
||||
.insert(provider.id(), configuration_view);
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for AssistantConfiguration {
|
||||
fn focus_handle(&self, _: &App) -> FocusHandle {
|
||||
self.focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum AssistantConfigurationEvent {
|
||||
NewThread(Arc<dyn LanguageModelProvider>),
|
||||
}
|
||||
|
||||
impl EventEmitter<AssistantConfigurationEvent> for AssistantConfiguration {}
|
||||
|
||||
impl AssistantConfiguration {
|
||||
fn render_provider_configuration(
|
||||
&mut self,
|
||||
provider: &Arc<dyn LanguageModelProvider>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement + use<> {
|
||||
let provider_id = provider.id().0.clone();
|
||||
let provider_name = provider.name().0.clone();
|
||||
let configuration_view = self
|
||||
.configuration_views_by_provider
|
||||
.get(&provider.id())
|
||||
.cloned();
|
||||
|
||||
v_flex()
|
||||
.gap_1p5()
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(
|
||||
Icon::new(provider.icon())
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(Label::new(provider_name.clone())),
|
||||
)
|
||||
.when(provider.is_authenticated(cx), |parent| {
|
||||
parent.child(
|
||||
Button::new(
|
||||
SharedString::from(format!("new-thread-{provider_id}")),
|
||||
"Start New Thread",
|
||||
)
|
||||
.icon_position(IconPosition::Start)
|
||||
.icon(IconName::Plus)
|
||||
.icon_size(IconSize::Small)
|
||||
.style(ButtonStyle::Filled)
|
||||
.layer(ElevationIndex::ModalSurface)
|
||||
.label_size(LabelSize::Small)
|
||||
.on_click(cx.listener({
|
||||
let provider = provider.clone();
|
||||
move |_this, _event, _window, cx| {
|
||||
cx.emit(AssistantConfigurationEvent::NewThread(
|
||||
provider.clone(),
|
||||
))
|
||||
}
|
||||
})),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.p(DynamicSpacing::Base08.rems(cx))
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.rounded_sm()
|
||||
.map(|parent| match configuration_view {
|
||||
Some(configuration_view) => parent.child(configuration_view),
|
||||
None => parent.child(div().child(Label::new(format!(
|
||||
"No configuration view for {provider_name}",
|
||||
)))),
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_command_permission(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let always_allow_tool_actions = AssistantSettings::get_global(cx).always_allow_tool_actions;
|
||||
|
||||
const HEADING: &str = "Allow running tools without asking for confirmation";
|
||||
|
||||
v_flex()
|
||||
.p(DynamicSpacing::Base16.rems(cx))
|
||||
.gap_2()
|
||||
.flex_1()
|
||||
.child(Headline::new("General Settings").size(HeadlineSize::Small))
|
||||
.child(
|
||||
h_flex()
|
||||
.p_2p5()
|
||||
.rounded_sm()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.border_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.gap_4()
|
||||
.justify_between()
|
||||
.flex_wrap()
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_0p5()
|
||||
.max_w_5_6()
|
||||
.child(Label::new(HEADING))
|
||||
.child(Label::new("When enabled, the agent can perform potentially destructive actions without asking for your confirmation.").color(Color::Muted)),
|
||||
)
|
||||
.child(
|
||||
Switch::new(
|
||||
"always-allow-tool-actions-switch",
|
||||
always_allow_tool_actions.into(),
|
||||
)
|
||||
.on_click({
|
||||
let fs = self.fs.clone();
|
||||
move |state, _window, cx| {
|
||||
let allow = state == &ToggleState::Selected;
|
||||
update_settings_file::<AssistantSettings>(
|
||||
fs.clone(),
|
||||
cx,
|
||||
move |settings, _| {
|
||||
settings.set_always_allow_tool_actions(allow);
|
||||
},
|
||||
);
|
||||
}
|
||||
}),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_context_servers_section(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let context_servers = self.context_server_manager.read(cx).all_servers().clone();
|
||||
let tools_by_source = self.tools.tools_by_source(cx);
|
||||
let empty = Vec::new();
|
||||
|
||||
const SUBHEADING: &str = "Connect to context servers via the Model Context Protocol either via Zed extensions or directly.";
|
||||
|
||||
v_flex()
|
||||
.p(DynamicSpacing::Base16.rems(cx))
|
||||
.gap_2()
|
||||
.flex_1()
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_0p5()
|
||||
.child(Headline::new("Context Servers (MCP)").size(HeadlineSize::Small))
|
||||
.child(Label::new(SUBHEADING).color(Color::Muted)),
|
||||
)
|
||||
.children(context_servers.into_iter().map(|context_server| {
|
||||
let is_running = context_server.client().is_some();
|
||||
let are_tools_expanded = self
|
||||
.expanded_context_server_tools
|
||||
.get(&context_server.id())
|
||||
.copied()
|
||||
.unwrap_or_default();
|
||||
|
||||
let tools = tools_by_source
|
||||
.get(&ToolSource::ContextServer {
|
||||
id: context_server.id().into(),
|
||||
})
|
||||
.unwrap_or_else(|| &empty);
|
||||
let tool_count = tools.len();
|
||||
|
||||
v_flex()
|
||||
.id(SharedString::from(context_server.id()))
|
||||
.border_1()
|
||||
.rounded_sm()
|
||||
.border_color(cx.theme().colors().border)
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.when(are_tools_expanded, |element| {
|
||||
element
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
})
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(
|
||||
Disclosure::new("tool-list-disclosure", are_tools_expanded)
|
||||
.on_click(cx.listener({
|
||||
let context_server_id = context_server.id();
|
||||
move |this, _event, _window, _cx| {
|
||||
let is_open = this
|
||||
.expanded_context_server_tools
|
||||
.entry(context_server_id.clone())
|
||||
.or_insert(false);
|
||||
|
||||
*is_open = !*is_open;
|
||||
}
|
||||
})),
|
||||
)
|
||||
.child(Indicator::dot().color(if is_running {
|
||||
Color::Success
|
||||
} else {
|
||||
Color::Error
|
||||
}))
|
||||
.child(Label::new(context_server.id()))
|
||||
.child(
|
||||
Label::new(format!("{tool_count} tools"))
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.child(h_flex().child(
|
||||
Switch::new("context-server-switch", is_running.into()).on_click({
|
||||
let context_server_manager =
|
||||
self.context_server_manager.clone();
|
||||
let context_server = context_server.clone();
|
||||
move |state, _window, cx| match state {
|
||||
ToggleState::Unselected | ToggleState::Indeterminate => {
|
||||
context_server_manager.update(cx, |this, cx| {
|
||||
this.stop_server(context_server.clone(), cx)
|
||||
.log_err();
|
||||
});
|
||||
}
|
||||
ToggleState::Selected => {
|
||||
cx.spawn({
|
||||
let context_server_manager =
|
||||
context_server_manager.clone();
|
||||
let context_server = context_server.clone();
|
||||
async move |cx| {
|
||||
if let Some(start_server_task) =
|
||||
context_server_manager
|
||||
.update(cx, |this, cx| {
|
||||
this.start_server(
|
||||
context_server,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.log_err()
|
||||
{
|
||||
start_server_task.await.log_err();
|
||||
}
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
}),
|
||||
)),
|
||||
)
|
||||
.map(|parent| {
|
||||
if !are_tools_expanded {
|
||||
return parent;
|
||||
}
|
||||
|
||||
parent.child(v_flex().children(tools.into_iter().enumerate().map(
|
||||
|(ix, tool)| {
|
||||
h_flex()
|
||||
.px_2()
|
||||
.py_1()
|
||||
.when(ix < tool_count - 1, |element| {
|
||||
element
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().colors().border)
|
||||
})
|
||||
.child(Label::new(tool.name()))
|
||||
},
|
||||
)))
|
||||
})
|
||||
}))
|
||||
.child(
|
||||
h_flex()
|
||||
.justify_between()
|
||||
.gap_2()
|
||||
.child(
|
||||
h_flex().w_full().child(
|
||||
Button::new("add-context-server", "Add Context Server")
|
||||
.style(ButtonStyle::Filled)
|
||||
.layer(ElevationIndex::ModalSurface)
|
||||
.full_width()
|
||||
.icon(IconName::Plus)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_position(IconPosition::Start)
|
||||
.on_click(|_event, window, cx| {
|
||||
window.dispatch_action(AddContextServer.boxed_clone(), cx)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
h_flex().w_full().child(
|
||||
Button::new(
|
||||
"install-context-server-extensions",
|
||||
"Install Context Server Extensions",
|
||||
)
|
||||
.style(ButtonStyle::Filled)
|
||||
.layer(ElevationIndex::ModalSurface)
|
||||
.full_width()
|
||||
.icon(IconName::DatabaseZap)
|
||||
.icon_size(IconSize::Small)
|
||||
.icon_position(IconPosition::Start)
|
||||
.on_click(|_event, window, cx| {
|
||||
window.dispatch_action(
|
||||
zed_actions::Extensions {
|
||||
category_filter: Some(
|
||||
ExtensionCategoryFilter::ContextServers,
|
||||
),
|
||||
}
|
||||
.boxed_clone(),
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for AssistantConfiguration {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let providers = LanguageModelRegistry::read_global(cx).providers();
|
||||
|
||||
v_flex()
|
||||
.id("assistant-configuration")
|
||||
.key_context("AgentConfiguration")
|
||||
.track_focus(&self.focus_handle(cx))
|
||||
.bg(cx.theme().colors().panel_background)
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
.child(self.render_command_permission(cx))
|
||||
.child(Divider::horizontal().color(DividerColor::Border))
|
||||
.child(self.render_context_servers_section(cx))
|
||||
.child(Divider::horizontal().color(DividerColor::Border))
|
||||
.child(
|
||||
v_flex()
|
||||
.p(DynamicSpacing::Base16.rems(cx))
|
||||
.mt_1()
|
||||
.gap_6()
|
||||
.flex_1()
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_0p5()
|
||||
.child(Headline::new("LLM Providers").size(HeadlineSize::Small))
|
||||
.child(
|
||||
Label::new("Add at least one provider to use AI-powered features.")
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.children(
|
||||
providers
|
||||
.into_iter()
|
||||
.map(|provider| self.render_provider_configuration(&provider, cx)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
use context_server::{ContextServerSettings, ServerCommand, ServerConfig};
|
||||
use gpui::{DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, prelude::*};
|
||||
use serde_json::json;
|
||||
use settings::update_settings_file;
|
||||
use ui::{Modal, ModalFooter, ModalHeader, Section, Tooltip, prelude::*};
|
||||
use ui_input::SingleLineInput;
|
||||
use workspace::{ModalView, Workspace};
|
||||
|
||||
use crate::AddContextServer;
|
||||
|
||||
pub struct AddContextServerModal {
|
||||
workspace: WeakEntity<Workspace>,
|
||||
name_editor: Entity<SingleLineInput>,
|
||||
command_editor: Entity<SingleLineInput>,
|
||||
}
|
||||
|
||||
impl AddContextServerModal {
|
||||
pub fn register(
|
||||
workspace: &mut Workspace,
|
||||
_window: Option<&mut Window>,
|
||||
_cx: &mut Context<Workspace>,
|
||||
) {
|
||||
workspace.register_action(|workspace, _: &AddContextServer, window, cx| {
|
||||
let workspace_handle = cx.entity().downgrade();
|
||||
workspace.toggle_modal(window, cx, |window, cx| {
|
||||
Self::new(workspace_handle, window, cx)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
workspace: WeakEntity<Workspace>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let name_editor =
|
||||
cx.new(|cx| SingleLineInput::new(window, cx, "Your server name").label("Name"));
|
||||
let command_editor = cx.new(|cx| {
|
||||
SingleLineInput::new(window, cx, "Command").label("Command to run the context server")
|
||||
});
|
||||
|
||||
Self {
|
||||
name_editor,
|
||||
command_editor,
|
||||
workspace,
|
||||
}
|
||||
}
|
||||
|
||||
fn confirm(&mut self, cx: &mut Context<Self>) {
|
||||
let name = self
|
||||
.name_editor
|
||||
.read(cx)
|
||||
.editor()
|
||||
.read(cx)
|
||||
.text(cx)
|
||||
.trim()
|
||||
.to_string();
|
||||
let command = self
|
||||
.command_editor
|
||||
.read(cx)
|
||||
.editor()
|
||||
.read(cx)
|
||||
.text(cx)
|
||||
.trim()
|
||||
.to_string();
|
||||
|
||||
if name.is_empty() || command.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut command_parts = command.split(' ').map(|part| part.trim().to_string());
|
||||
let Some(path) = command_parts.next() else {
|
||||
return;
|
||||
};
|
||||
let args = command_parts.collect::<Vec<_>>();
|
||||
|
||||
if let Some(workspace) = self.workspace.upgrade() {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
let fs = workspace.app_state().fs.clone();
|
||||
update_settings_file::<ContextServerSettings>(fs.clone(), cx, |settings, _| {
|
||||
settings.context_servers.insert(
|
||||
name.into(),
|
||||
ServerConfig {
|
||||
command: Some(ServerCommand {
|
||||
path,
|
||||
args,
|
||||
env: None,
|
||||
}),
|
||||
settings: Some(json!({})),
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
|
||||
fn cancel(&mut self, cx: &mut Context<Self>) {
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalView for AddContextServerModal {}
|
||||
|
||||
impl Focusable for AddContextServerModal {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
self.name_editor.focus_handle(cx).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<DismissEvent> for AddContextServerModal {}
|
||||
|
||||
impl Render for AddContextServerModal {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let is_name_empty = self.name_editor.read(cx).is_empty(cx);
|
||||
let is_command_empty = self.command_editor.read(cx).is_empty(cx);
|
||||
|
||||
div()
|
||||
.elevation_3(cx)
|
||||
.w(rems(34.))
|
||||
.key_context("AddContextServerModal")
|
||||
.on_action(cx.listener(|this, _: &menu::Cancel, _window, cx| this.cancel(cx)))
|
||||
.on_action(cx.listener(|this, _: &menu::Confirm, _window, cx| this.confirm(cx)))
|
||||
.capture_any_mouse_down(cx.listener(|this, _, window, cx| {
|
||||
this.focus_handle(cx).focus(window);
|
||||
}))
|
||||
.on_mouse_down_out(cx.listener(|_this, _, _, cx| cx.emit(DismissEvent)))
|
||||
.child(
|
||||
Modal::new("add-context-server", None)
|
||||
.header(ModalHeader::new().headline("Add Context Server"))
|
||||
.section(
|
||||
Section::new()
|
||||
.child(self.name_editor.clone())
|
||||
.child(self.command_editor.clone()),
|
||||
)
|
||||
.footer(
|
||||
ModalFooter::new()
|
||||
.start_slot(
|
||||
Button::new("cancel", "Cancel").on_click(
|
||||
cx.listener(|this, _event, _window, cx| this.cancel(cx)),
|
||||
),
|
||||
)
|
||||
.end_slot(
|
||||
Button::new("add-server", "Add Server")
|
||||
.disabled(is_name_empty || is_command_empty)
|
||||
.map(|button| {
|
||||
if is_name_empty {
|
||||
button.tooltip(Tooltip::text("Name is required"))
|
||||
} else if is_command_empty {
|
||||
button.tooltip(Tooltip::text("Command is required"))
|
||||
} else {
|
||||
button
|
||||
}
|
||||
})
|
||||
.on_click(
|
||||
cx.listener(|this, _event, _window, cx| this.confirm(cx)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,570 +0,0 @@
|
||||
mod profile_modal_header;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use assistant_settings::{AgentProfile, AgentProfileId, AssistantSettings};
|
||||
use assistant_tool::ToolWorkingSet;
|
||||
use convert_case::{Case, Casing as _};
|
||||
use editor::Editor;
|
||||
use fs::Fs;
|
||||
use gpui::{
|
||||
DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, Subscription, WeakEntity,
|
||||
prelude::*,
|
||||
};
|
||||
use settings::{Settings as _, update_settings_file};
|
||||
use ui::{
|
||||
KeyBinding, ListItem, ListItemSpacing, ListSeparator, Navigable, NavigableEntry, prelude::*,
|
||||
};
|
||||
use util::ResultExt as _;
|
||||
use workspace::{ModalView, Workspace};
|
||||
|
||||
use crate::assistant_configuration::manage_profiles_modal::profile_modal_header::ProfileModalHeader;
|
||||
use crate::assistant_configuration::tool_picker::{ToolPicker, ToolPickerDelegate};
|
||||
use crate::{AssistantPanel, ManageProfiles, ThreadStore};
|
||||
|
||||
enum Mode {
|
||||
ChooseProfile(ChooseProfileMode),
|
||||
NewProfile(NewProfileMode),
|
||||
ViewProfile(ViewProfileMode),
|
||||
ConfigureTools {
|
||||
profile_id: AgentProfileId,
|
||||
tool_picker: Entity<ToolPicker>,
|
||||
_subscription: Subscription,
|
||||
},
|
||||
}
|
||||
|
||||
impl Mode {
|
||||
pub fn choose_profile(_window: &mut Window, cx: &mut Context<ManageProfilesModal>) -> Self {
|
||||
let settings = AssistantSettings::get_global(cx);
|
||||
|
||||
let mut profiles = settings.profiles.clone();
|
||||
profiles.sort_unstable_by(|_, a, _, b| a.name.cmp(&b.name));
|
||||
|
||||
let profiles = profiles
|
||||
.into_iter()
|
||||
.map(|(id, profile)| ProfileEntry {
|
||||
id,
|
||||
name: profile.name,
|
||||
navigation: NavigableEntry::focusable(cx),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Self::ChooseProfile(ChooseProfileMode {
|
||||
profiles,
|
||||
add_new_profile: NavigableEntry::focusable(cx),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ProfileEntry {
|
||||
pub id: AgentProfileId,
|
||||
pub name: SharedString,
|
||||
pub navigation: NavigableEntry,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ChooseProfileMode {
|
||||
profiles: Vec<ProfileEntry>,
|
||||
add_new_profile: NavigableEntry,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ViewProfileMode {
|
||||
profile_id: AgentProfileId,
|
||||
fork_profile: NavigableEntry,
|
||||
configure_tools: NavigableEntry,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NewProfileMode {
|
||||
name_editor: Entity<Editor>,
|
||||
base_profile_id: Option<AgentProfileId>,
|
||||
}
|
||||
|
||||
pub struct ManageProfilesModal {
|
||||
fs: Arc<dyn Fs>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
thread_store: WeakEntity<ThreadStore>,
|
||||
focus_handle: FocusHandle,
|
||||
mode: Mode,
|
||||
}
|
||||
|
||||
impl ManageProfilesModal {
|
||||
pub fn register(
|
||||
workspace: &mut Workspace,
|
||||
_window: Option<&mut Window>,
|
||||
_cx: &mut Context<Workspace>,
|
||||
) {
|
||||
workspace.register_action(|workspace, action: &ManageProfiles, window, cx| {
|
||||
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
|
||||
let fs = workspace.app_state().fs.clone();
|
||||
let thread_store = panel.read(cx).thread_store();
|
||||
let tools = thread_store.read(cx).tools();
|
||||
let thread_store = thread_store.downgrade();
|
||||
workspace.toggle_modal(window, cx, |window, cx| {
|
||||
let mut this = Self::new(fs, tools, thread_store, window, cx);
|
||||
|
||||
if let Some(profile_id) = action.customize_tools.clone() {
|
||||
this.configure_tools(profile_id, window, cx);
|
||||
}
|
||||
|
||||
this
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
fs: Arc<dyn Fs>,
|
||||
tools: Arc<ToolWorkingSet>,
|
||||
thread_store: WeakEntity<ThreadStore>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let focus_handle = cx.focus_handle();
|
||||
|
||||
Self {
|
||||
fs,
|
||||
tools,
|
||||
thread_store,
|
||||
focus_handle,
|
||||
mode: Mode::choose_profile(window, cx),
|
||||
}
|
||||
}
|
||||
|
||||
fn choose_profile(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.mode = Mode::choose_profile(window, cx);
|
||||
self.focus_handle(cx).focus(window);
|
||||
}
|
||||
|
||||
fn new_profile(
|
||||
&mut self,
|
||||
base_profile_id: Option<AgentProfileId>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let name_editor = cx.new(|cx| Editor::single_line(window, cx));
|
||||
name_editor.update(cx, |editor, cx| {
|
||||
editor.set_placeholder_text("Profile name", cx);
|
||||
});
|
||||
|
||||
self.mode = Mode::NewProfile(NewProfileMode {
|
||||
name_editor,
|
||||
base_profile_id,
|
||||
});
|
||||
self.focus_handle(cx).focus(window);
|
||||
}
|
||||
|
||||
pub fn view_profile(
|
||||
&mut self,
|
||||
profile_id: AgentProfileId,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.mode = Mode::ViewProfile(ViewProfileMode {
|
||||
profile_id,
|
||||
fork_profile: NavigableEntry::focusable(cx),
|
||||
configure_tools: NavigableEntry::focusable(cx),
|
||||
});
|
||||
self.focus_handle(cx).focus(window);
|
||||
}
|
||||
|
||||
fn configure_tools(
|
||||
&mut self,
|
||||
profile_id: AgentProfileId,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let settings = AssistantSettings::get_global(cx);
|
||||
let Some(profile) = settings.profiles.get(&profile_id).cloned() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let tool_picker = cx.new(|cx| {
|
||||
let delegate = ToolPickerDelegate::new(
|
||||
self.fs.clone(),
|
||||
self.tools.clone(),
|
||||
self.thread_store.clone(),
|
||||
profile_id.clone(),
|
||||
profile,
|
||||
cx,
|
||||
);
|
||||
ToolPicker::new(delegate, window, cx)
|
||||
});
|
||||
let dismiss_subscription = cx.subscribe_in(&tool_picker, window, {
|
||||
let profile_id = profile_id.clone();
|
||||
move |this, _tool_picker, _: &DismissEvent, window, cx| {
|
||||
this.view_profile(profile_id.clone(), window, cx);
|
||||
}
|
||||
});
|
||||
|
||||
self.mode = Mode::ConfigureTools {
|
||||
profile_id,
|
||||
tool_picker,
|
||||
_subscription: dismiss_subscription,
|
||||
};
|
||||
self.focus_handle(cx).focus(window);
|
||||
}
|
||||
|
||||
fn confirm(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
match &self.mode {
|
||||
Mode::ChooseProfile { .. } => {}
|
||||
Mode::NewProfile(mode) => {
|
||||
let settings = AssistantSettings::get_global(cx);
|
||||
|
||||
let base_profile = mode
|
||||
.base_profile_id
|
||||
.as_ref()
|
||||
.and_then(|profile_id| settings.profiles.get(profile_id).cloned());
|
||||
|
||||
let name = mode.name_editor.read(cx).text(cx);
|
||||
let profile_id = AgentProfileId(name.to_case(Case::Kebab).into());
|
||||
|
||||
let profile = AgentProfile {
|
||||
name: name.into(),
|
||||
tools: base_profile
|
||||
.as_ref()
|
||||
.map(|profile| profile.tools.clone())
|
||||
.unwrap_or_default(),
|
||||
enable_all_context_servers: base_profile
|
||||
.as_ref()
|
||||
.map(|profile| profile.enable_all_context_servers)
|
||||
.unwrap_or_default(),
|
||||
context_servers: base_profile
|
||||
.map(|profile| profile.context_servers)
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
|
||||
self.create_profile(profile_id.clone(), profile, cx);
|
||||
self.view_profile(profile_id, window, cx);
|
||||
}
|
||||
Mode::ViewProfile(_) => {}
|
||||
Mode::ConfigureTools { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn cancel(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
match &self.mode {
|
||||
Mode::ChooseProfile { .. } => {
|
||||
cx.emit(DismissEvent);
|
||||
}
|
||||
Mode::NewProfile(mode) => {
|
||||
if let Some(profile_id) = mode.base_profile_id.clone() {
|
||||
self.view_profile(profile_id, window, cx);
|
||||
} else {
|
||||
self.choose_profile(window, cx);
|
||||
}
|
||||
}
|
||||
Mode::ViewProfile(_) => self.choose_profile(window, cx),
|
||||
Mode::ConfigureTools { .. } => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_profile(
|
||||
&self,
|
||||
profile_id: AgentProfileId,
|
||||
profile: AgentProfile,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
update_settings_file::<AssistantSettings>(self.fs.clone(), cx, {
|
||||
move |settings, _cx| {
|
||||
settings.create_profile(profile_id, profile).log_err();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl ModalView for ManageProfilesModal {}
|
||||
|
||||
impl Focusable for ManageProfilesModal {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
match &self.mode {
|
||||
Mode::ChooseProfile(_) => self.focus_handle.clone(),
|
||||
Mode::NewProfile(mode) => mode.name_editor.focus_handle(cx),
|
||||
Mode::ViewProfile(_) => self.focus_handle.clone(),
|
||||
Mode::ConfigureTools { tool_picker, .. } => tool_picker.focus_handle(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<DismissEvent> for ManageProfilesModal {}
|
||||
|
||||
impl ManageProfilesModal {
|
||||
fn render_choose_profile(
|
||||
&mut self,
|
||||
mode: ChooseProfileMode,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
Navigable::new(
|
||||
div()
|
||||
.track_focus(&self.focus_handle(cx))
|
||||
.size_full()
|
||||
.child(ProfileModalHeader::new(
|
||||
"Agent Profiles",
|
||||
IconName::ZedAssistant,
|
||||
))
|
||||
.child(
|
||||
v_flex()
|
||||
.pb_1()
|
||||
.child(ListSeparator)
|
||||
.children(mode.profiles.iter().map(|profile| {
|
||||
div()
|
||||
.id(SharedString::from(format!("profile-{}", profile.id)))
|
||||
.track_focus(&profile.navigation.focus_handle)
|
||||
.on_action({
|
||||
let profile_id = profile.id.clone();
|
||||
cx.listener(move |this, _: &menu::Confirm, window, cx| {
|
||||
this.view_profile(profile_id.clone(), window, cx);
|
||||
})
|
||||
})
|
||||
.child(
|
||||
ListItem::new(SharedString::from(format!(
|
||||
"profile-{}",
|
||||
profile.id
|
||||
)))
|
||||
.toggle_state(
|
||||
profile
|
||||
.navigation
|
||||
.focus_handle
|
||||
.contains_focused(window, cx),
|
||||
)
|
||||
.inset(true)
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
.child(Label::new(profile.name.clone()))
|
||||
.end_slot(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(Label::new("Customize").size(LabelSize::Small))
|
||||
.children(KeyBinding::for_action_in(
|
||||
&menu::Confirm,
|
||||
&self.focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)),
|
||||
)
|
||||
.on_click({
|
||||
let profile_id = profile.id.clone();
|
||||
cx.listener(move |this, _, window, cx| {
|
||||
this.view_profile(profile_id.clone(), window, cx);
|
||||
})
|
||||
}),
|
||||
)
|
||||
}))
|
||||
.child(ListSeparator)
|
||||
.child(
|
||||
div()
|
||||
.id("new-profile")
|
||||
.track_focus(&mode.add_new_profile.focus_handle)
|
||||
.on_action(cx.listener(|this, _: &menu::Confirm, window, cx| {
|
||||
this.new_profile(None, window, cx);
|
||||
}))
|
||||
.child(
|
||||
ListItem::new("new-profile")
|
||||
.toggle_state(
|
||||
mode.add_new_profile
|
||||
.focus_handle
|
||||
.contains_focused(window, cx),
|
||||
)
|
||||
.inset(true)
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
.start_slot(Icon::new(IconName::Plus))
|
||||
.child(Label::new("Add New Profile"))
|
||||
.on_click({
|
||||
cx.listener(move |this, _, window, cx| {
|
||||
this.new_profile(None, window, cx);
|
||||
})
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
.into_any_element(),
|
||||
)
|
||||
.map(|mut navigable| {
|
||||
for profile in mode.profiles {
|
||||
navigable = navigable.entry(profile.navigation);
|
||||
}
|
||||
|
||||
navigable
|
||||
})
|
||||
.entry(mode.add_new_profile)
|
||||
}
|
||||
|
||||
fn render_new_profile(
|
||||
&mut self,
|
||||
mode: NewProfileMode,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let settings = AssistantSettings::get_global(cx);
|
||||
|
||||
let base_profile_name = mode.base_profile_id.as_ref().map(|base_profile_id| {
|
||||
settings
|
||||
.profiles
|
||||
.get(base_profile_id)
|
||||
.map(|profile| profile.name.clone())
|
||||
.unwrap_or_else(|| "Unknown".into())
|
||||
});
|
||||
|
||||
v_flex()
|
||||
.id("new-profile")
|
||||
.track_focus(&self.focus_handle(cx))
|
||||
.child(ProfileModalHeader::new(
|
||||
match base_profile_name {
|
||||
Some(base_profile) => format!("Fork {base_profile}"),
|
||||
None => "New Profile".into(),
|
||||
},
|
||||
IconName::Plus,
|
||||
))
|
||||
.child(ListSeparator)
|
||||
.child(h_flex().p_2().child(mode.name_editor.clone()))
|
||||
}
|
||||
|
||||
fn render_view_profile(
|
||||
&mut self,
|
||||
mode: ViewProfileMode,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> impl IntoElement {
|
||||
let settings = AssistantSettings::get_global(cx);
|
||||
|
||||
let profile_name = settings
|
||||
.profiles
|
||||
.get(&mode.profile_id)
|
||||
.map(|profile| profile.name.clone())
|
||||
.unwrap_or_else(|| "Unknown".into());
|
||||
|
||||
Navigable::new(
|
||||
div()
|
||||
.track_focus(&self.focus_handle(cx))
|
||||
.size_full()
|
||||
.child(ProfileModalHeader::new(
|
||||
profile_name,
|
||||
IconName::ZedAssistant,
|
||||
))
|
||||
.child(
|
||||
v_flex()
|
||||
.pb_1()
|
||||
.child(ListSeparator)
|
||||
.child(
|
||||
div()
|
||||
.id("fork-profile")
|
||||
.track_focus(&mode.fork_profile.focus_handle)
|
||||
.on_action({
|
||||
let profile_id = mode.profile_id.clone();
|
||||
cx.listener(move |this, _: &menu::Confirm, window, cx| {
|
||||
this.new_profile(Some(profile_id.clone()), window, cx);
|
||||
})
|
||||
})
|
||||
.child(
|
||||
ListItem::new("fork-profile")
|
||||
.toggle_state(
|
||||
mode.fork_profile
|
||||
.focus_handle
|
||||
.contains_focused(window, cx),
|
||||
)
|
||||
.inset(true)
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
.start_slot(Icon::new(IconName::GitBranch))
|
||||
.child(Label::new("Fork Profile"))
|
||||
.on_click({
|
||||
let profile_id = mode.profile_id.clone();
|
||||
cx.listener(move |this, _, window, cx| {
|
||||
this.new_profile(
|
||||
Some(profile_id.clone()),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("configure-tools")
|
||||
.track_focus(&mode.configure_tools.focus_handle)
|
||||
.on_action({
|
||||
let profile_id = mode.profile_id.clone();
|
||||
cx.listener(move |this, _: &menu::Confirm, window, cx| {
|
||||
this.configure_tools(profile_id.clone(), window, cx);
|
||||
})
|
||||
})
|
||||
.child(
|
||||
ListItem::new("configure-tools")
|
||||
.toggle_state(
|
||||
mode.configure_tools
|
||||
.focus_handle
|
||||
.contains_focused(window, cx),
|
||||
)
|
||||
.inset(true)
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
.start_slot(Icon::new(IconName::Cog))
|
||||
.child(Label::new("Configure Tools"))
|
||||
.on_click({
|
||||
let profile_id = mode.profile_id.clone();
|
||||
cx.listener(move |this, _, window, cx| {
|
||||
this.configure_tools(
|
||||
profile_id.clone(),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
.into_any_element(),
|
||||
)
|
||||
.entry(mode.fork_profile)
|
||||
.entry(mode.configure_tools)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ManageProfilesModal {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let settings = AssistantSettings::get_global(cx);
|
||||
|
||||
div()
|
||||
.elevation_3(cx)
|
||||
.w(rems(34.))
|
||||
.key_context("ManageProfilesModal")
|
||||
.on_action(cx.listener(|this, _: &menu::Cancel, window, cx| this.cancel(window, cx)))
|
||||
.on_action(cx.listener(|this, _: &menu::Confirm, window, cx| this.confirm(window, cx)))
|
||||
.capture_any_mouse_down(cx.listener(|this, _, window, cx| {
|
||||
this.focus_handle(cx).focus(window);
|
||||
}))
|
||||
.on_mouse_down_out(cx.listener(|_this, _, _, cx| cx.emit(DismissEvent)))
|
||||
.child(match &self.mode {
|
||||
Mode::ChooseProfile(mode) => self
|
||||
.render_choose_profile(mode.clone(), window, cx)
|
||||
.into_any_element(),
|
||||
Mode::NewProfile(mode) => self
|
||||
.render_new_profile(mode.clone(), window, cx)
|
||||
.into_any_element(),
|
||||
Mode::ViewProfile(mode) => self
|
||||
.render_view_profile(mode.clone(), window, cx)
|
||||
.into_any_element(),
|
||||
Mode::ConfigureTools {
|
||||
profile_id,
|
||||
tool_picker,
|
||||
..
|
||||
} => {
|
||||
let profile_name = settings
|
||||
.profiles
|
||||
.get(profile_id)
|
||||
.map(|profile| profile.name.clone())
|
||||
.unwrap_or_else(|| "Unknown".into());
|
||||
|
||||
div()
|
||||
.child(ProfileModalHeader::new(
|
||||
format!("{profile_name}: Configure Tools"),
|
||||
IconName::Cog,
|
||||
))
|
||||
.child(ListSeparator)
|
||||
.child(tool_picker.clone())
|
||||
.into_any_element()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
use ui::prelude::*;
|
||||
|
||||
#[derive(IntoElement)]
|
||||
pub struct ProfileModalHeader {
|
||||
label: SharedString,
|
||||
icon: IconName,
|
||||
}
|
||||
|
||||
impl ProfileModalHeader {
|
||||
pub fn new(label: impl Into<SharedString>, icon: IconName) -> Self {
|
||||
Self {
|
||||
label: label.into(),
|
||||
icon,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for ProfileModalHeader {
|
||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
h_flex()
|
||||
.w_full()
|
||||
.px(DynamicSpacing::Base12.rems(cx))
|
||||
.pt(DynamicSpacing::Base08.rems(cx))
|
||||
.pb(DynamicSpacing::Base04.rems(cx))
|
||||
.rounded_t_sm()
|
||||
.gap_1p5()
|
||||
.child(Icon::new(self.icon).size(IconSize::XSmall))
|
||||
.child(
|
||||
h_flex().gap_1().overflow_x_hidden().child(
|
||||
div()
|
||||
.max_w_96()
|
||||
.overflow_x_hidden()
|
||||
.text_ellipsis()
|
||||
.child(Headline::new(self.label).size(HeadlineSize::XSmall)),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,302 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use assistant_settings::{
|
||||
AgentProfile, AgentProfileContent, AgentProfileId, AssistantSettings, AssistantSettingsContent,
|
||||
ContextServerPresetContent, VersionedAssistantSettingsContent,
|
||||
};
|
||||
use assistant_tool::{ToolSource, ToolWorkingSet};
|
||||
use fs::Fs;
|
||||
use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
|
||||
use gpui::{App, Context, DismissEvent, Entity, EventEmitter, Focusable, Task, WeakEntity, Window};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use settings::{Settings as _, update_settings_file};
|
||||
use ui::{HighlightedLabel, ListItem, ListItemSpacing, prelude::*};
|
||||
use util::ResultExt as _;
|
||||
|
||||
use crate::ThreadStore;
|
||||
|
||||
pub struct ToolPicker {
|
||||
picker: Entity<Picker<ToolPickerDelegate>>,
|
||||
}
|
||||
|
||||
impl ToolPicker {
|
||||
pub fn new(delegate: ToolPickerDelegate, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx).modal(false));
|
||||
Self { picker }
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<DismissEvent> for ToolPicker {}
|
||||
|
||||
impl Focusable for ToolPicker {
|
||||
fn focus_handle(&self, cx: &App) -> gpui::FocusHandle {
|
||||
self.picker.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ToolPicker {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
v_flex().w(rems(34.)).child(self.picker.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ToolEntry {
|
||||
pub name: Arc<str>,
|
||||
pub source: ToolSource,
|
||||
}
|
||||
|
||||
pub struct ToolPickerDelegate {
|
||||
tool_picker: WeakEntity<ToolPicker>,
|
||||
thread_store: WeakEntity<ThreadStore>,
|
||||
fs: Arc<dyn Fs>,
|
||||
tools: Vec<ToolEntry>,
|
||||
profile_id: AgentProfileId,
|
||||
profile: AgentProfile,
|
||||
matches: Vec<StringMatch>,
|
||||
selected_index: usize,
|
||||
}
|
||||
|
||||
impl ToolPickerDelegate {
|
||||
pub fn new(
|
||||
fs: Arc<dyn Fs>,
|
||||
tool_set: Arc<ToolWorkingSet>,
|
||||
thread_store: WeakEntity<ThreadStore>,
|
||||
profile_id: AgentProfileId,
|
||||
profile: AgentProfile,
|
||||
cx: &mut Context<ToolPicker>,
|
||||
) -> Self {
|
||||
let mut tool_entries = Vec::new();
|
||||
|
||||
for (source, tools) in tool_set.tools_by_source(cx) {
|
||||
tool_entries.extend(tools.into_iter().map(|tool| ToolEntry {
|
||||
name: tool.name().into(),
|
||||
source: source.clone(),
|
||||
}));
|
||||
}
|
||||
|
||||
Self {
|
||||
tool_picker: cx.entity().downgrade(),
|
||||
thread_store,
|
||||
fs,
|
||||
tools: tool_entries,
|
||||
profile_id,
|
||||
profile,
|
||||
matches: Vec::new(),
|
||||
selected_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PickerDelegate for ToolPickerDelegate {
|
||||
type ListItem = ListItem;
|
||||
|
||||
fn match_count(&self) -> usize {
|
||||
self.matches.len()
|
||||
}
|
||||
|
||||
fn selected_index(&self) -> usize {
|
||||
self.selected_index
|
||||
}
|
||||
|
||||
fn set_selected_index(
|
||||
&mut self,
|
||||
ix: usize,
|
||||
_window: &mut Window,
|
||||
_cx: &mut Context<Picker<Self>>,
|
||||
) {
|
||||
self.selected_index = ix;
|
||||
}
|
||||
|
||||
fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc<str> {
|
||||
"Search tools…".into()
|
||||
}
|
||||
|
||||
fn update_matches(
|
||||
&mut self,
|
||||
query: String,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
let background = cx.background_executor().clone();
|
||||
let candidates = self
|
||||
.tools
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, profile)| StringMatchCandidate::new(id, profile.name.as_ref()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let matches = if query.is_empty() {
|
||||
candidates
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, candidate)| StringMatch {
|
||||
candidate_id: index,
|
||||
string: candidate.string,
|
||||
positions: Vec::new(),
|
||||
score: 0.,
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
match_strings(
|
||||
&candidates,
|
||||
&query,
|
||||
false,
|
||||
100,
|
||||
&Default::default(),
|
||||
background,
|
||||
)
|
||||
.await
|
||||
};
|
||||
|
||||
this.update(cx, |this, _cx| {
|
||||
this.delegate.matches = matches;
|
||||
this.delegate.selected_index = this
|
||||
.delegate
|
||||
.selected_index
|
||||
.min(this.delegate.matches.len().saturating_sub(1));
|
||||
})
|
||||
.log_err();
|
||||
})
|
||||
}
|
||||
|
||||
fn confirm(&mut self, _secondary: bool, window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
if self.matches.is_empty() {
|
||||
self.dismissed(window, cx);
|
||||
return;
|
||||
}
|
||||
|
||||
let candidate_id = self.matches[self.selected_index].candidate_id;
|
||||
let tool = &self.tools[candidate_id];
|
||||
|
||||
let is_enabled = match &tool.source {
|
||||
ToolSource::Native => {
|
||||
let is_enabled = self.profile.tools.entry(tool.name.clone()).or_default();
|
||||
*is_enabled = !*is_enabled;
|
||||
*is_enabled
|
||||
}
|
||||
ToolSource::ContextServer { id } => {
|
||||
let preset = self
|
||||
.profile
|
||||
.context_servers
|
||||
.entry(id.clone().into())
|
||||
.or_default();
|
||||
let is_enabled = preset.tools.entry(tool.name.clone()).or_default();
|
||||
*is_enabled = !*is_enabled;
|
||||
*is_enabled
|
||||
}
|
||||
};
|
||||
|
||||
let active_profile_id = &AssistantSettings::get_global(cx).default_profile;
|
||||
if active_profile_id == &self.profile_id {
|
||||
self.thread_store
|
||||
.update(cx, |this, cx| {
|
||||
this.load_profile(&self.profile, cx);
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
|
||||
update_settings_file::<AssistantSettings>(self.fs.clone(), cx, {
|
||||
let profile_id = self.profile_id.clone();
|
||||
let default_profile = self.profile.clone();
|
||||
let tool = tool.clone();
|
||||
move |settings, _cx| match settings {
|
||||
AssistantSettingsContent::Versioned(boxed) => {
|
||||
if let VersionedAssistantSettingsContent::V2(ref mut settings) = **boxed {
|
||||
let profiles = settings.profiles.get_or_insert_default();
|
||||
let profile =
|
||||
profiles
|
||||
.entry(profile_id)
|
||||
.or_insert_with(|| AgentProfileContent {
|
||||
name: default_profile.name.into(),
|
||||
tools: default_profile.tools,
|
||||
enable_all_context_servers: Some(
|
||||
default_profile.enable_all_context_servers,
|
||||
),
|
||||
context_servers: default_profile
|
||||
.context_servers
|
||||
.into_iter()
|
||||
.map(|(server_id, preset)| {
|
||||
(
|
||||
server_id,
|
||||
ContextServerPresetContent {
|
||||
tools: preset.tools,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
|
||||
match tool.source {
|
||||
ToolSource::Native => {
|
||||
*profile.tools.entry(tool.name).or_default() = is_enabled;
|
||||
}
|
||||
ToolSource::ContextServer { id } => {
|
||||
let preset = profile
|
||||
.context_servers
|
||||
.entry(id.clone().into())
|
||||
.or_default();
|
||||
*preset.tools.entry(tool.name.clone()).or_default() = is_enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn dismissed(&mut self, _window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
self.tool_picker
|
||||
.update(cx, |_this, cx| cx.emit(DismissEvent))
|
||||
.log_err();
|
||||
}
|
||||
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
selected: bool,
|
||||
_window: &mut Window,
|
||||
_cx: &mut Context<Picker<Self>>,
|
||||
) -> Option<Self::ListItem> {
|
||||
let tool_match = &self.matches[ix];
|
||||
let tool = &self.tools[tool_match.candidate_id];
|
||||
|
||||
let is_enabled = match &tool.source {
|
||||
ToolSource::Native => self.profile.tools.get(&tool.name).copied().unwrap_or(false),
|
||||
ToolSource::ContextServer { id } => self
|
||||
.profile
|
||||
.context_servers
|
||||
.get(id.as_ref())
|
||||
.and_then(|preset| preset.tools.get(&tool.name))
|
||||
.copied()
|
||||
.unwrap_or(false),
|
||||
};
|
||||
|
||||
Some(
|
||||
ListItem::new(ix)
|
||||
.inset(true)
|
||||
.spacing(ListItemSpacing::Sparse)
|
||||
.toggle_state(selected)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_2()
|
||||
.child(HighlightedLabel::new(
|
||||
tool_match.string.clone(),
|
||||
tool_match.positions.clone(),
|
||||
))
|
||||
.map(|parent| match &tool.source {
|
||||
ToolSource::Native => parent,
|
||||
ToolSource::ContextServer { id } => parent
|
||||
.child(Label::new(id).size(LabelSize::XSmall).color(Color::Muted)),
|
||||
}),
|
||||
)
|
||||
.end_slot::<Icon>(is_enabled.then(|| {
|
||||
Icon::new(IconName::Check)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Success)
|
||||
})),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
use assistant_settings::AssistantSettings;
|
||||
use fs::Fs;
|
||||
use gpui::{Entity, FocusHandle, SharedString};
|
||||
use language_model::LanguageModelRegistry;
|
||||
use language_model_selector::{
|
||||
LanguageModelSelector, LanguageModelSelectorPopoverMenu, ToggleModelSelector,
|
||||
};
|
||||
use settings::update_settings_file;
|
||||
use std::sync::Arc;
|
||||
use ui::{ButtonLike, PopoverMenuHandle, Tooltip, prelude::*};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ModelType {
|
||||
Default,
|
||||
InlineAssistant,
|
||||
}
|
||||
|
||||
pub struct AssistantModelSelector {
|
||||
selector: Entity<LanguageModelSelector>,
|
||||
menu_handle: PopoverMenuHandle<LanguageModelSelector>,
|
||||
focus_handle: FocusHandle,
|
||||
model_type: ModelType,
|
||||
}
|
||||
|
||||
impl AssistantModelSelector {
|
||||
pub(crate) fn new(
|
||||
fs: Arc<dyn Fs>,
|
||||
menu_handle: PopoverMenuHandle<LanguageModelSelector>,
|
||||
focus_handle: FocusHandle,
|
||||
model_type: ModelType,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Self {
|
||||
Self {
|
||||
selector: cx.new(|cx| {
|
||||
let fs = fs.clone();
|
||||
LanguageModelSelector::new(
|
||||
move |model, cx| {
|
||||
let provider = model.provider_id().0.to_string();
|
||||
let model_id = model.id().0.to_string();
|
||||
|
||||
match model_type {
|
||||
ModelType::Default => {
|
||||
update_settings_file::<AssistantSettings>(
|
||||
fs.clone(),
|
||||
cx,
|
||||
move |settings, _cx| {
|
||||
settings.set_model(model.clone());
|
||||
},
|
||||
);
|
||||
}
|
||||
ModelType::InlineAssistant => {
|
||||
update_settings_file::<AssistantSettings>(
|
||||
fs.clone(),
|
||||
cx,
|
||||
move |settings, _cx| {
|
||||
settings.set_inline_assistant_model(
|
||||
provider.clone(),
|
||||
model_id.clone(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
menu_handle,
|
||||
focus_handle,
|
||||
model_type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle(&self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.menu_handle.toggle(window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for AssistantModelSelector {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let model_registry = LanguageModelRegistry::read_global(cx);
|
||||
|
||||
let model = match self.model_type {
|
||||
ModelType::Default => model_registry.default_model(),
|
||||
ModelType::InlineAssistant => model_registry.inline_assistant_model(),
|
||||
};
|
||||
|
||||
let focus_handle = self.focus_handle.clone();
|
||||
let model_name = match model {
|
||||
Some(model) => model.model.name().0,
|
||||
_ => SharedString::from("No model selected"),
|
||||
};
|
||||
|
||||
LanguageModelSelectorPopoverMenu::new(
|
||||
self.selector.clone(),
|
||||
ButtonLike::new("active-model")
|
||||
.style(ButtonStyle::Subtle)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Label::new(model_name)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
Icon::new(IconName::ChevronDown)
|
||||
.color(Color::Muted)
|
||||
.size(IconSize::XSmall),
|
||||
),
|
||||
),
|
||||
move |window, cx| {
|
||||
Tooltip::for_action_in(
|
||||
"Change Model",
|
||||
&ToggleModelSelector,
|
||||
&focus_handle,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
},
|
||||
gpui::Corner::BottomRight,
|
||||
)
|
||||
.with_handle(self.menu_handle.clone())
|
||||
}
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
use std::{ops::Range, path::Path, sync::Arc};
|
||||
|
||||
use gpui::{App, Entity, SharedString};
|
||||
use language::{Buffer, File};
|
||||
use language_model::LanguageModelRequestMessage;
|
||||
use project::{ProjectPath, Worktree};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use text::{Anchor, BufferId};
|
||||
use ui::IconName;
|
||||
use util::post_inc;
|
||||
|
||||
use crate::thread::Thread;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct ContextId(pub(crate) usize);
|
||||
|
||||
impl ContextId {
|
||||
pub fn post_inc(&mut self) -> Self {
|
||||
Self(post_inc(&mut self.0))
|
||||
}
|
||||
}
|
||||
pub enum ContextKind {
|
||||
File,
|
||||
Directory,
|
||||
Symbol,
|
||||
FetchedUrl,
|
||||
Thread,
|
||||
}
|
||||
|
||||
impl ContextKind {
|
||||
pub fn icon(&self) -> IconName {
|
||||
match self {
|
||||
ContextKind::File => IconName::File,
|
||||
ContextKind::Directory => IconName::Folder,
|
||||
ContextKind::Symbol => IconName::Code,
|
||||
ContextKind::FetchedUrl => IconName::Globe,
|
||||
ContextKind::Thread => IconName::MessageBubbles,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AssistantContext {
|
||||
File(FileContext),
|
||||
Directory(DirectoryContext),
|
||||
Symbol(SymbolContext),
|
||||
FetchedUrl(FetchedUrlContext),
|
||||
Thread(ThreadContext),
|
||||
}
|
||||
|
||||
impl AssistantContext {
|
||||
pub fn id(&self) -> ContextId {
|
||||
match self {
|
||||
Self::File(file) => file.id,
|
||||
Self::Directory(directory) => directory.id,
|
||||
Self::Symbol(symbol) => symbol.id,
|
||||
Self::FetchedUrl(url) => url.id,
|
||||
Self::Thread(thread) => thread.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FileContext {
|
||||
pub id: ContextId,
|
||||
pub context_buffer: ContextBuffer,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DirectoryContext {
|
||||
pub id: ContextId,
|
||||
pub worktree: Entity<Worktree>,
|
||||
pub path: Arc<Path>,
|
||||
/// Buffers of the files within the directory.
|
||||
pub context_buffers: Vec<ContextBuffer>,
|
||||
}
|
||||
|
||||
impl DirectoryContext {
|
||||
pub fn project_path(&self, cx: &App) -> ProjectPath {
|
||||
ProjectPath {
|
||||
worktree_id: self.worktree.read(cx).id(),
|
||||
path: self.path.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SymbolContext {
|
||||
pub id: ContextId,
|
||||
pub context_symbol: ContextSymbol,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FetchedUrlContext {
|
||||
pub id: ContextId,
|
||||
pub url: SharedString,
|
||||
pub text: SharedString,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ThreadContext {
|
||||
pub id: ContextId,
|
||||
// TODO: Entity<Thread> holds onto the thread even if the thread is deleted. Should probably be
|
||||
// a WeakEntity and handle removal from the UI when it has dropped.
|
||||
pub thread: Entity<Thread>,
|
||||
pub text: SharedString,
|
||||
}
|
||||
|
||||
impl ThreadContext {
|
||||
pub fn summary(&self, cx: &App) -> SharedString {
|
||||
self.thread
|
||||
.read(cx)
|
||||
.summary()
|
||||
.unwrap_or("New thread".into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ContextBuffer {
|
||||
pub id: BufferId,
|
||||
// TODO: Entity<Buffer> holds onto the thread even if the thread is deleted. Should probably be
|
||||
// a WeakEntity and handle removal from the UI when it has dropped.
|
||||
pub buffer: Entity<Buffer>,
|
||||
pub file: Arc<dyn File>,
|
||||
pub version: clock::Global,
|
||||
pub text: SharedString,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ContextBuffer {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ContextBuffer")
|
||||
.field("id", &self.id)
|
||||
.field("buffer", &self.buffer)
|
||||
.field("version", &self.version)
|
||||
.field("text", &self.text)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ContextSymbol {
|
||||
pub id: ContextSymbolId,
|
||||
pub buffer: Entity<Buffer>,
|
||||
pub buffer_version: clock::Global,
|
||||
/// The range that the symbol encloses, e.g. for function symbol, this will
|
||||
/// include not only the signature, but also the body
|
||||
pub enclosing_range: Range<Anchor>,
|
||||
pub text: SharedString,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ContextSymbolId {
|
||||
pub path: ProjectPath,
|
||||
pub name: SharedString,
|
||||
pub range: Range<Anchor>,
|
||||
}
|
||||
|
||||
/// Formats a collection of contexts into a string representation
|
||||
pub fn format_context_as_string<'a>(
|
||||
contexts: impl Iterator<Item = &'a AssistantContext>,
|
||||
cx: &App,
|
||||
) -> Option<String> {
|
||||
let mut file_context = Vec::new();
|
||||
let mut directory_context = Vec::new();
|
||||
let mut symbol_context = Vec::new();
|
||||
let mut fetch_context = Vec::new();
|
||||
let mut thread_context = Vec::new();
|
||||
|
||||
for context in contexts {
|
||||
match context {
|
||||
AssistantContext::File(context) => file_context.push(context),
|
||||
AssistantContext::Directory(context) => directory_context.push(context),
|
||||
AssistantContext::Symbol(context) => symbol_context.push(context),
|
||||
AssistantContext::FetchedUrl(context) => fetch_context.push(context),
|
||||
AssistantContext::Thread(context) => thread_context.push(context),
|
||||
}
|
||||
}
|
||||
|
||||
if file_context.is_empty()
|
||||
&& directory_context.is_empty()
|
||||
&& symbol_context.is_empty()
|
||||
&& fetch_context.is_empty()
|
||||
&& thread_context.is_empty()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut result = String::new();
|
||||
result.push_str("\n<context>\n\
|
||||
The following items were attached by the user. You don't need to use other tools to read them.\n\n");
|
||||
|
||||
if !file_context.is_empty() {
|
||||
result.push_str("<files>\n");
|
||||
for context in file_context {
|
||||
result.push_str(&context.context_buffer.text);
|
||||
}
|
||||
result.push_str("</files>\n");
|
||||
}
|
||||
|
||||
if !directory_context.is_empty() {
|
||||
result.push_str("<directories>\n");
|
||||
for context in directory_context {
|
||||
for context_buffer in &context.context_buffers {
|
||||
result.push_str(&context_buffer.text);
|
||||
}
|
||||
}
|
||||
result.push_str("</directories>\n");
|
||||
}
|
||||
|
||||
if !symbol_context.is_empty() {
|
||||
result.push_str("<symbols>\n");
|
||||
for context in symbol_context {
|
||||
result.push_str(&context.context_symbol.text);
|
||||
result.push('\n');
|
||||
}
|
||||
result.push_str("</symbols>\n");
|
||||
}
|
||||
|
||||
if !fetch_context.is_empty() {
|
||||
result.push_str("<fetched_urls>\n");
|
||||
for context in &fetch_context {
|
||||
result.push_str(&context.url);
|
||||
result.push('\n');
|
||||
result.push_str(&context.text);
|
||||
result.push('\n');
|
||||
}
|
||||
result.push_str("</fetched_urls>\n");
|
||||
}
|
||||
|
||||
if !thread_context.is_empty() {
|
||||
result.push_str("<conversation_threads>\n");
|
||||
for context in &thread_context {
|
||||
result.push_str(&context.summary(cx));
|
||||
result.push('\n');
|
||||
result.push_str(&context.text);
|
||||
result.push('\n');
|
||||
}
|
||||
result.push_str("</conversation_threads>\n");
|
||||
}
|
||||
|
||||
result.push_str("</context>\n");
|
||||
Some(result)
|
||||
}
|
||||
|
||||
pub fn attach_context_to_message<'a>(
|
||||
message: &mut LanguageModelRequestMessage,
|
||||
contexts: impl Iterator<Item = &'a AssistantContext>,
|
||||
cx: &App,
|
||||
) {
|
||||
if let Some(context_string) = format_context_as_string(contexts, cx) {
|
||||
message.content.push(context_string.into());
|
||||
}
|
||||
}
|
||||
@@ -1,728 +0,0 @@
|
||||
mod completion_provider;
|
||||
mod fetch_context_picker;
|
||||
mod file_context_picker;
|
||||
mod symbol_context_picker;
|
||||
mod thread_context_picker;
|
||||
|
||||
use std::ops::Range;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{Result, anyhow};
|
||||
use editor::display_map::{Crease, FoldId};
|
||||
use editor::{Anchor, AnchorRangeExt as _, Editor, ExcerptId, FoldPlaceholder, ToOffset};
|
||||
use file_context_picker::render_file_context_entry;
|
||||
use gpui::{
|
||||
App, DismissEvent, Empty, Entity, EventEmitter, FocusHandle, Focusable, Subscription, Task,
|
||||
WeakEntity,
|
||||
};
|
||||
use multi_buffer::MultiBufferRow;
|
||||
use project::{Entry, ProjectPath};
|
||||
use symbol_context_picker::SymbolContextPicker;
|
||||
use thread_context_picker::{ThreadContextEntry, render_thread_context_entry};
|
||||
use ui::{
|
||||
ButtonLike, ContextMenu, ContextMenuEntry, ContextMenuItem, Disclosure, TintColor, prelude::*,
|
||||
};
|
||||
use workspace::{Workspace, notifications::NotifyResultExt};
|
||||
|
||||
use crate::AssistantPanel;
|
||||
pub use crate::context_picker::completion_provider::ContextPickerCompletionProvider;
|
||||
use crate::context_picker::fetch_context_picker::FetchContextPicker;
|
||||
use crate::context_picker::file_context_picker::FileContextPicker;
|
||||
use crate::context_picker::thread_context_picker::ThreadContextPicker;
|
||||
use crate::context_store::ContextStore;
|
||||
use crate::thread::ThreadId;
|
||||
use crate::thread_store::ThreadStore;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum ConfirmBehavior {
|
||||
KeepOpen,
|
||||
Close,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum ContextPickerMode {
|
||||
File,
|
||||
Symbol,
|
||||
Fetch,
|
||||
Thread,
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for ContextPickerMode {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
"file" => Ok(Self::File),
|
||||
"symbol" => Ok(Self::Symbol),
|
||||
"fetch" => Ok(Self::Fetch),
|
||||
"thread" => Ok(Self::Thread),
|
||||
_ => Err(format!("Invalid context picker mode: {}", value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ContextPickerMode {
|
||||
pub fn mention_prefix(&self) -> &'static str {
|
||||
match self {
|
||||
Self::File => "file",
|
||||
Self::Symbol => "symbol",
|
||||
Self::Fetch => "fetch",
|
||||
Self::Thread => "thread",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn label(&self) -> &'static str {
|
||||
match self {
|
||||
Self::File => "Files & Directories",
|
||||
Self::Symbol => "Symbols",
|
||||
Self::Fetch => "Fetch",
|
||||
Self::Thread => "Threads",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn icon(&self) -> IconName {
|
||||
match self {
|
||||
Self::File => IconName::File,
|
||||
Self::Symbol => IconName::Code,
|
||||
Self::Fetch => IconName::Globe,
|
||||
Self::Thread => IconName::MessageBubbles,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum ContextPickerState {
|
||||
Default(Entity<ContextMenu>),
|
||||
File(Entity<FileContextPicker>),
|
||||
Symbol(Entity<SymbolContextPicker>),
|
||||
Fetch(Entity<FetchContextPicker>),
|
||||
Thread(Entity<ThreadContextPicker>),
|
||||
}
|
||||
|
||||
pub(super) struct ContextPicker {
|
||||
mode: ContextPickerState,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
thread_store: Option<WeakEntity<ThreadStore>>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
_subscriptions: Vec<Subscription>,
|
||||
}
|
||||
|
||||
impl ContextPicker {
|
||||
pub fn new(
|
||||
workspace: WeakEntity<Workspace>,
|
||||
thread_store: Option<WeakEntity<ThreadStore>>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let subscriptions = context_store
|
||||
.upgrade()
|
||||
.map(|context_store| {
|
||||
cx.observe(&context_store, |this, _, cx| this.notify_current_picker(cx))
|
||||
})
|
||||
.into_iter()
|
||||
.chain(
|
||||
thread_store
|
||||
.as_ref()
|
||||
.and_then(|thread_store| thread_store.upgrade())
|
||||
.map(|thread_store| {
|
||||
cx.observe(&thread_store, |this, _, cx| this.notify_current_picker(cx))
|
||||
}),
|
||||
)
|
||||
.collect::<Vec<Subscription>>();
|
||||
|
||||
ContextPicker {
|
||||
mode: ContextPickerState::Default(ContextMenu::build(
|
||||
window,
|
||||
cx,
|
||||
|menu, _window, _cx| menu,
|
||||
)),
|
||||
workspace,
|
||||
context_store,
|
||||
thread_store,
|
||||
confirm_behavior,
|
||||
_subscriptions: subscriptions,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.mode = ContextPickerState::Default(self.build_menu(window, cx));
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn build_menu(&mut self, window: &mut Window, cx: &mut Context<Self>) -> Entity<ContextMenu> {
|
||||
let context_picker = cx.entity().clone();
|
||||
|
||||
let menu = ContextMenu::build(window, cx, move |menu, _window, cx| {
|
||||
let recent = self.recent_entries(cx);
|
||||
let has_recent = !recent.is_empty();
|
||||
let recent_entries = recent
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(ix, entry)| self.recent_menu_item(context_picker.clone(), ix, entry));
|
||||
|
||||
let modes = supported_context_picker_modes(&self.thread_store);
|
||||
|
||||
let menu = menu
|
||||
.when(has_recent, |menu| {
|
||||
menu.custom_row(|_, _| {
|
||||
div()
|
||||
.mb_1()
|
||||
.child(
|
||||
Label::new("Recent")
|
||||
.color(Color::Muted)
|
||||
.size(LabelSize::Small),
|
||||
)
|
||||
.into_any_element()
|
||||
})
|
||||
})
|
||||
.extend(recent_entries)
|
||||
.when(has_recent, |menu| menu.separator())
|
||||
.extend(modes.into_iter().map(|mode| {
|
||||
let context_picker = context_picker.clone();
|
||||
|
||||
ContextMenuEntry::new(mode.label())
|
||||
.icon(mode.icon())
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.handler(move |window, cx| {
|
||||
context_picker.update(cx, |this, cx| this.select_mode(mode, window, cx))
|
||||
})
|
||||
}));
|
||||
|
||||
match self.confirm_behavior {
|
||||
ConfirmBehavior::KeepOpen => menu.keep_open_on_confirm(),
|
||||
ConfirmBehavior::Close => menu,
|
||||
}
|
||||
});
|
||||
|
||||
cx.subscribe(&menu, move |_, _, _: &DismissEvent, cx| {
|
||||
cx.emit(DismissEvent);
|
||||
})
|
||||
.detach();
|
||||
|
||||
menu
|
||||
}
|
||||
|
||||
/// Whether threads are allowed as context.
|
||||
pub fn allow_threads(&self) -> bool {
|
||||
self.thread_store.is_some()
|
||||
}
|
||||
|
||||
fn select_mode(
|
||||
&mut self,
|
||||
mode: ContextPickerMode,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let context_picker = cx.entity().downgrade();
|
||||
|
||||
match mode {
|
||||
ContextPickerMode::File => {
|
||||
self.mode = ContextPickerState::File(cx.new(|cx| {
|
||||
FileContextPicker::new(
|
||||
context_picker.clone(),
|
||||
self.workspace.clone(),
|
||||
self.context_store.clone(),
|
||||
self.confirm_behavior,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}));
|
||||
}
|
||||
ContextPickerMode::Symbol => {
|
||||
self.mode = ContextPickerState::Symbol(cx.new(|cx| {
|
||||
SymbolContextPicker::new(
|
||||
context_picker.clone(),
|
||||
self.workspace.clone(),
|
||||
self.context_store.clone(),
|
||||
self.confirm_behavior,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}));
|
||||
}
|
||||
ContextPickerMode::Fetch => {
|
||||
self.mode = ContextPickerState::Fetch(cx.new(|cx| {
|
||||
FetchContextPicker::new(
|
||||
context_picker.clone(),
|
||||
self.workspace.clone(),
|
||||
self.context_store.clone(),
|
||||
self.confirm_behavior,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}));
|
||||
}
|
||||
ContextPickerMode::Thread => {
|
||||
if let Some(thread_store) = self.thread_store.as_ref() {
|
||||
self.mode = ContextPickerState::Thread(cx.new(|cx| {
|
||||
ThreadContextPicker::new(
|
||||
thread_store.clone(),
|
||||
context_picker.clone(),
|
||||
self.context_store.clone(),
|
||||
self.confirm_behavior,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
cx.focus_self(window);
|
||||
}
|
||||
|
||||
fn recent_menu_item(
|
||||
&self,
|
||||
context_picker: Entity<ContextPicker>,
|
||||
ix: usize,
|
||||
entry: RecentEntry,
|
||||
) -> ContextMenuItem {
|
||||
match entry {
|
||||
RecentEntry::File {
|
||||
project_path,
|
||||
path_prefix,
|
||||
} => {
|
||||
let context_store = self.context_store.clone();
|
||||
let worktree_id = project_path.worktree_id;
|
||||
let path = project_path.path.clone();
|
||||
|
||||
ContextMenuItem::custom_entry(
|
||||
move |_window, cx| {
|
||||
render_file_context_entry(
|
||||
ElementId::NamedInteger("ctx-recent".into(), ix),
|
||||
worktree_id,
|
||||
&path,
|
||||
&path_prefix,
|
||||
false,
|
||||
context_store.clone(),
|
||||
cx,
|
||||
)
|
||||
.into_any()
|
||||
},
|
||||
move |window, cx| {
|
||||
context_picker.update(cx, |this, cx| {
|
||||
this.add_recent_file(project_path.clone(), window, cx);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
RecentEntry::Thread(thread) => {
|
||||
let context_store = self.context_store.clone();
|
||||
let view_thread = thread.clone();
|
||||
|
||||
ContextMenuItem::custom_entry(
|
||||
move |_window, cx| {
|
||||
render_thread_context_entry(&view_thread, context_store.clone(), cx)
|
||||
.into_any()
|
||||
},
|
||||
move |_window, cx| {
|
||||
context_picker.update(cx, |this, cx| {
|
||||
this.add_recent_thread(thread.clone(), cx)
|
||||
.detach_and_log_err(cx);
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_recent_file(
|
||||
&self,
|
||||
project_path: ProjectPath,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(context_store) = self.context_store.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let task = context_store.update(cx, |context_store, cx| {
|
||||
context_store.add_file_from_path(project_path.clone(), true, cx)
|
||||
});
|
||||
|
||||
cx.spawn_in(window, async move |_, cx| task.await.notify_async_err(cx))
|
||||
.detach();
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn add_recent_thread(
|
||||
&self,
|
||||
thread: ThreadContextEntry,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<()>> {
|
||||
let Some(context_store) = self.context_store.upgrade() else {
|
||||
return Task::ready(Err(anyhow!("context store not available")));
|
||||
};
|
||||
|
||||
let Some(thread_store) = self
|
||||
.thread_store
|
||||
.as_ref()
|
||||
.and_then(|thread_store| thread_store.upgrade())
|
||||
else {
|
||||
return Task::ready(Err(anyhow!("thread store not available")));
|
||||
};
|
||||
|
||||
let open_thread_task = thread_store.update(cx, |this, cx| this.open_thread(&thread.id, cx));
|
||||
cx.spawn(async move |this, cx| {
|
||||
let thread = open_thread_task.await?;
|
||||
context_store.update(cx, |context_store, cx| {
|
||||
context_store.add_thread(thread, true, cx);
|
||||
})?;
|
||||
|
||||
this.update(cx, |_this, cx| cx.notify())
|
||||
})
|
||||
}
|
||||
|
||||
fn recent_entries(&self, cx: &mut App) -> Vec<RecentEntry> {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
let Some(context_store) = self.context_store.upgrade() else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
recent_context_picker_entries(context_store, self.thread_store.clone(), workspace, cx)
|
||||
}
|
||||
|
||||
fn notify_current_picker(&mut self, cx: &mut Context<Self>) {
|
||||
match &self.mode {
|
||||
ContextPickerState::Default(entity) => entity.update(cx, |_, cx| cx.notify()),
|
||||
ContextPickerState::File(entity) => entity.update(cx, |_, cx| cx.notify()),
|
||||
ContextPickerState::Symbol(entity) => entity.update(cx, |_, cx| cx.notify()),
|
||||
ContextPickerState::Fetch(entity) => entity.update(cx, |_, cx| cx.notify()),
|
||||
ContextPickerState::Thread(entity) => entity.update(cx, |_, cx| cx.notify()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<DismissEvent> for ContextPicker {}
|
||||
|
||||
impl Focusable for ContextPicker {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
match &self.mode {
|
||||
ContextPickerState::Default(menu) => menu.focus_handle(cx),
|
||||
ContextPickerState::File(file_picker) => file_picker.focus_handle(cx),
|
||||
ContextPickerState::Symbol(symbol_picker) => symbol_picker.focus_handle(cx),
|
||||
ContextPickerState::Fetch(fetch_picker) => fetch_picker.focus_handle(cx),
|
||||
ContextPickerState::Thread(thread_picker) => thread_picker.focus_handle(cx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ContextPicker {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
v_flex()
|
||||
.w(px(400.))
|
||||
.min_w(px(400.))
|
||||
.map(|parent| match &self.mode {
|
||||
ContextPickerState::Default(menu) => parent.child(menu.clone()),
|
||||
ContextPickerState::File(file_picker) => parent.child(file_picker.clone()),
|
||||
ContextPickerState::Symbol(symbol_picker) => parent.child(symbol_picker.clone()),
|
||||
ContextPickerState::Fetch(fetch_picker) => parent.child(fetch_picker.clone()),
|
||||
ContextPickerState::Thread(thread_picker) => parent.child(thread_picker.clone()),
|
||||
})
|
||||
}
|
||||
}
|
||||
enum RecentEntry {
|
||||
File {
|
||||
project_path: ProjectPath,
|
||||
path_prefix: Arc<str>,
|
||||
},
|
||||
Thread(ThreadContextEntry),
|
||||
}
|
||||
|
||||
fn supported_context_picker_modes(
|
||||
thread_store: &Option<WeakEntity<ThreadStore>>,
|
||||
) -> Vec<ContextPickerMode> {
|
||||
let mut modes = vec![
|
||||
ContextPickerMode::File,
|
||||
ContextPickerMode::Symbol,
|
||||
ContextPickerMode::Fetch,
|
||||
];
|
||||
if thread_store.is_some() {
|
||||
modes.push(ContextPickerMode::Thread);
|
||||
}
|
||||
modes
|
||||
}
|
||||
|
||||
fn recent_context_picker_entries(
|
||||
context_store: Entity<ContextStore>,
|
||||
thread_store: Option<WeakEntity<ThreadStore>>,
|
||||
workspace: Entity<Workspace>,
|
||||
cx: &App,
|
||||
) -> Vec<RecentEntry> {
|
||||
let mut recent = Vec::with_capacity(6);
|
||||
|
||||
let current_files = context_store.read(cx).file_paths(cx);
|
||||
let workspace = workspace.read(cx);
|
||||
let project = workspace.project().read(cx);
|
||||
|
||||
recent.extend(
|
||||
workspace
|
||||
.recent_navigation_history_iter(cx)
|
||||
.filter(|(path, _)| !current_files.contains(path))
|
||||
.take(4)
|
||||
.filter_map(|(project_path, _)| {
|
||||
project
|
||||
.worktree_for_id(project_path.worktree_id, cx)
|
||||
.map(|worktree| RecentEntry::File {
|
||||
project_path,
|
||||
path_prefix: worktree.read(cx).root_name().into(),
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
let mut current_threads = context_store.read(cx).thread_ids();
|
||||
|
||||
if let Some(active_thread) = workspace
|
||||
.panel::<AssistantPanel>(cx)
|
||||
.map(|panel| panel.read(cx).active_thread(cx))
|
||||
{
|
||||
current_threads.insert(active_thread.read(cx).id().clone());
|
||||
}
|
||||
|
||||
if let Some(thread_store) = thread_store.and_then(|thread_store| thread_store.upgrade()) {
|
||||
recent.extend(
|
||||
thread_store
|
||||
.read(cx)
|
||||
.threads()
|
||||
.into_iter()
|
||||
.filter(|thread| !current_threads.contains(&thread.id))
|
||||
.take(2)
|
||||
.map(|thread| {
|
||||
RecentEntry::Thread(ThreadContextEntry {
|
||||
id: thread.id,
|
||||
summary: thread.summary,
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
recent
|
||||
}
|
||||
|
||||
pub(crate) fn insert_crease_for_mention(
|
||||
excerpt_id: ExcerptId,
|
||||
crease_start: text::Anchor,
|
||||
content_len: usize,
|
||||
crease_label: SharedString,
|
||||
crease_icon_path: SharedString,
|
||||
editor_entity: Entity<Editor>,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) {
|
||||
editor_entity.update(cx, |editor, cx| {
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
|
||||
let Some(start) = snapshot.anchor_in_excerpt(excerpt_id, crease_start) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let start = start.bias_right(&snapshot);
|
||||
let end = snapshot.anchor_before(start.to_offset(&snapshot) + content_len);
|
||||
|
||||
let placeholder = FoldPlaceholder {
|
||||
render: render_fold_icon_button(
|
||||
crease_icon_path,
|
||||
crease_label,
|
||||
editor_entity.downgrade(),
|
||||
),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let render_trailer =
|
||||
move |_row, _unfold, _window: &mut Window, _cx: &mut App| Empty.into_any();
|
||||
|
||||
let crease = Crease::inline(
|
||||
start..end,
|
||||
placeholder.clone(),
|
||||
fold_toggle("mention"),
|
||||
render_trailer,
|
||||
);
|
||||
|
||||
editor.insert_creases(vec![crease.clone()], cx);
|
||||
editor.fold_creases(vec![crease], false, window, cx);
|
||||
});
|
||||
}
|
||||
|
||||
fn render_fold_icon_button(
|
||||
icon_path: SharedString,
|
||||
label: SharedString,
|
||||
editor: WeakEntity<Editor>,
|
||||
) -> Arc<dyn Send + Sync + Fn(FoldId, Range<Anchor>, &mut App) -> AnyElement> {
|
||||
Arc::new({
|
||||
move |fold_id, fold_range, cx| {
|
||||
let is_in_text_selection = editor.upgrade().is_some_and(|editor| {
|
||||
editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor
|
||||
.buffer()
|
||||
.update(cx, |multi_buffer, cx| multi_buffer.snapshot(cx));
|
||||
|
||||
let is_in_pending_selection = || {
|
||||
editor
|
||||
.selections
|
||||
.pending
|
||||
.as_ref()
|
||||
.is_some_and(|pending_selection| {
|
||||
pending_selection
|
||||
.selection
|
||||
.range()
|
||||
.includes(&fold_range, &snapshot)
|
||||
})
|
||||
};
|
||||
|
||||
let mut is_in_complete_selection = || {
|
||||
editor
|
||||
.selections
|
||||
.disjoint_in_range::<usize>(fold_range.clone(), cx)
|
||||
.into_iter()
|
||||
.any(|selection| {
|
||||
// This is needed to cover a corner case, if we just check for an existing
|
||||
// selection in the fold range, having a cursor at the start of the fold
|
||||
// marks it as selected. Non-empty selections don't cause this.
|
||||
let length = selection.end - selection.start;
|
||||
length > 0
|
||||
})
|
||||
};
|
||||
|
||||
is_in_pending_selection() || is_in_complete_selection()
|
||||
})
|
||||
});
|
||||
|
||||
ButtonLike::new(fold_id)
|
||||
.style(ButtonStyle::Filled)
|
||||
.selected_style(ButtonStyle::Tinted(TintColor::Accent))
|
||||
.toggle_state(is_in_text_selection)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(
|
||||
Icon::from_path(icon_path.clone())
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
Label::new(label.clone())
|
||||
.size(LabelSize::Small)
|
||||
.single_line(),
|
||||
),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_toggle(
|
||||
name: &'static str,
|
||||
) -> impl Fn(
|
||||
MultiBufferRow,
|
||||
bool,
|
||||
Arc<dyn Fn(bool, &mut Window, &mut App) + Send + Sync>,
|
||||
&mut Window,
|
||||
&mut App,
|
||||
) -> AnyElement {
|
||||
move |row, is_folded, fold, _window, _cx| {
|
||||
Disclosure::new((name, row.0 as u64), !is_folded)
|
||||
.toggle_state(is_folded)
|
||||
.on_click(move |_e, window, cx| fold(!is_folded, window, cx))
|
||||
.into_any_element()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum MentionLink {
|
||||
File(ProjectPath, Entry),
|
||||
Symbol(ProjectPath, String),
|
||||
Fetch(String),
|
||||
Thread(ThreadId),
|
||||
}
|
||||
|
||||
impl MentionLink {
|
||||
const FILE: &str = "@file";
|
||||
const SYMBOL: &str = "@symbol";
|
||||
const THREAD: &str = "@thread";
|
||||
const FETCH: &str = "@fetch";
|
||||
|
||||
const SEPARATOR: &str = ":";
|
||||
|
||||
pub fn is_valid(url: &str) -> bool {
|
||||
url.starts_with(Self::FILE)
|
||||
|| url.starts_with(Self::SYMBOL)
|
||||
|| url.starts_with(Self::FETCH)
|
||||
|| url.starts_with(Self::THREAD)
|
||||
}
|
||||
|
||||
pub fn for_file(file_name: &str, full_path: &str) -> String {
|
||||
format!("[@{}]({}:{})", file_name, Self::FILE, full_path)
|
||||
}
|
||||
|
||||
pub fn for_symbol(symbol_name: &str, full_path: &str) -> String {
|
||||
format!(
|
||||
"[@{}]({}:{}:{})",
|
||||
symbol_name,
|
||||
Self::SYMBOL,
|
||||
full_path,
|
||||
symbol_name
|
||||
)
|
||||
}
|
||||
|
||||
pub fn for_fetch(url: &str) -> String {
|
||||
format!("[@{}]({}:{})", url, Self::FETCH, url)
|
||||
}
|
||||
|
||||
pub fn for_thread(thread: &ThreadContextEntry) -> String {
|
||||
format!("[@{}]({}:{})", thread.summary, Self::THREAD, thread.id)
|
||||
}
|
||||
|
||||
pub fn try_parse(link: &str, workspace: &Entity<Workspace>, cx: &App) -> Option<Self> {
|
||||
fn extract_project_path_from_link(
|
||||
path: &str,
|
||||
workspace: &Entity<Workspace>,
|
||||
cx: &App,
|
||||
) -> Option<ProjectPath> {
|
||||
let path = PathBuf::from(path);
|
||||
let worktree_name = path.iter().next()?;
|
||||
let path: PathBuf = path.iter().skip(1).collect();
|
||||
let worktree_id = workspace
|
||||
.read(cx)
|
||||
.visible_worktrees(cx)
|
||||
.find(|worktree| worktree.read(cx).root_name() == worktree_name)
|
||||
.map(|worktree| worktree.read(cx).id())?;
|
||||
Some(ProjectPath {
|
||||
worktree_id,
|
||||
path: path.into(),
|
||||
})
|
||||
}
|
||||
|
||||
let (prefix, argument) = link.split_once(Self::SEPARATOR)?;
|
||||
match prefix {
|
||||
Self::FILE => {
|
||||
let project_path = extract_project_path_from_link(argument, workspace, cx)?;
|
||||
let entry = workspace
|
||||
.read(cx)
|
||||
.project()
|
||||
.read(cx)
|
||||
.entry_for_path(&project_path, cx)?;
|
||||
Some(MentionLink::File(project_path, entry))
|
||||
}
|
||||
Self::SYMBOL => {
|
||||
let (path, symbol) = argument.split_once(Self::SEPARATOR)?;
|
||||
let project_path = extract_project_path_from_link(path, workspace, cx)?;
|
||||
Some(MentionLink::Symbol(project_path, symbol.to_string()))
|
||||
}
|
||||
Self::THREAD => {
|
||||
let thread_id = ThreadId::from(argument);
|
||||
Some(MentionLink::Thread(thread_id))
|
||||
}
|
||||
Self::FETCH => Some(MentionLink::Fetch(argument.to_string())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,410 +0,0 @@
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
use file_icons::FileIcons;
|
||||
use fuzzy::PathMatch;
|
||||
use gpui::{
|
||||
App, AppContext, DismissEvent, Entity, FocusHandle, Focusable, Stateful, Task, WeakEntity,
|
||||
};
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use project::{PathMatchCandidateSet, ProjectPath, WorktreeId};
|
||||
use ui::{ListItem, Tooltip, prelude::*};
|
||||
use util::ResultExt as _;
|
||||
use workspace::{Workspace, notifications::NotifyResultExt};
|
||||
|
||||
use crate::context_picker::{ConfirmBehavior, ContextPicker};
|
||||
use crate::context_store::{ContextStore, FileInclusion};
|
||||
|
||||
pub struct FileContextPicker {
|
||||
picker: Entity<Picker<FileContextPickerDelegate>>,
|
||||
}
|
||||
|
||||
impl FileContextPicker {
|
||||
pub fn new(
|
||||
context_picker: WeakEntity<ContextPicker>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let delegate = FileContextPickerDelegate::new(
|
||||
context_picker,
|
||||
workspace,
|
||||
context_store,
|
||||
confirm_behavior,
|
||||
);
|
||||
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||
|
||||
Self { picker }
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for FileContextPicker {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
self.picker.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for FileContextPicker {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
self.picker.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FileContextPickerDelegate {
|
||||
context_picker: WeakEntity<ContextPicker>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
matches: Vec<FileMatch>,
|
||||
selected_index: usize,
|
||||
}
|
||||
|
||||
impl FileContextPickerDelegate {
|
||||
pub fn new(
|
||||
context_picker: WeakEntity<ContextPicker>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
) -> Self {
|
||||
Self {
|
||||
context_picker,
|
||||
workspace,
|
||||
context_store,
|
||||
confirm_behavior,
|
||||
matches: Vec::new(),
|
||||
selected_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PickerDelegate for FileContextPickerDelegate {
|
||||
type ListItem = ListItem;
|
||||
|
||||
fn match_count(&self) -> usize {
|
||||
self.matches.len()
|
||||
}
|
||||
|
||||
fn selected_index(&self) -> usize {
|
||||
self.selected_index
|
||||
}
|
||||
|
||||
fn set_selected_index(
|
||||
&mut self,
|
||||
ix: usize,
|
||||
_window: &mut Window,
|
||||
_cx: &mut Context<Picker<Self>>,
|
||||
) {
|
||||
self.selected_index = ix;
|
||||
}
|
||||
|
||||
fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc<str> {
|
||||
"Search files & directories…".into()
|
||||
}
|
||||
|
||||
fn update_matches(
|
||||
&mut self,
|
||||
query: String,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return Task::ready(());
|
||||
};
|
||||
|
||||
let search_task = search_files(query, Arc::<AtomicBool>::default(), &workspace, cx);
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
// TODO: This should be probably be run in the background.
|
||||
let paths = search_task.await;
|
||||
|
||||
this.update(cx, |this, _cx| {
|
||||
this.delegate.matches = paths;
|
||||
})
|
||||
.log_err();
|
||||
})
|
||||
}
|
||||
|
||||
fn confirm(&mut self, _secondary: bool, window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
let Some(FileMatch { mat, .. }) = self.matches.get(self.selected_index) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let project_path = ProjectPath {
|
||||
worktree_id: WorktreeId::from_usize(mat.worktree_id),
|
||||
path: mat.path.clone(),
|
||||
};
|
||||
|
||||
let is_directory = mat.is_dir;
|
||||
|
||||
let Some(task) = self
|
||||
.context_store
|
||||
.update(cx, |context_store, cx| {
|
||||
if is_directory {
|
||||
context_store.add_directory(project_path, true, cx)
|
||||
} else {
|
||||
context_store.add_file_from_path(project_path, true, cx)
|
||||
}
|
||||
})
|
||||
.ok()
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let confirm_behavior = self.confirm_behavior;
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
match task.await.notify_async_err(cx) {
|
||||
None => anyhow::Ok(()),
|
||||
Some(()) => this.update_in(cx, |this, window, cx| match confirm_behavior {
|
||||
ConfirmBehavior::KeepOpen => {}
|
||||
ConfirmBehavior::Close => this.delegate.dismissed(window, cx),
|
||||
}),
|
||||
}
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn dismissed(&mut self, _: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
self.context_picker
|
||||
.update(cx, |_, cx| {
|
||||
cx.emit(DismissEvent);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
selected: bool,
|
||||
_window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Option<Self::ListItem> {
|
||||
let FileMatch { mat, .. } = &self.matches[ix];
|
||||
|
||||
Some(
|
||||
ListItem::new(ix)
|
||||
.inset(true)
|
||||
.toggle_state(selected)
|
||||
.child(render_file_context_entry(
|
||||
ElementId::NamedInteger("file-ctx-picker".into(), ix),
|
||||
WorktreeId::from_usize(mat.worktree_id),
|
||||
&mat.path,
|
||||
&mat.path_prefix,
|
||||
mat.is_dir,
|
||||
self.context_store.clone(),
|
||||
cx,
|
||||
)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FileMatch {
|
||||
pub mat: PathMatch,
|
||||
pub is_recent: bool,
|
||||
}
|
||||
|
||||
pub(crate) fn search_files(
|
||||
query: String,
|
||||
cancellation_flag: Arc<AtomicBool>,
|
||||
workspace: &Entity<Workspace>,
|
||||
cx: &App,
|
||||
) -> Task<Vec<FileMatch>> {
|
||||
if query.is_empty() {
|
||||
let workspace = workspace.read(cx);
|
||||
let project = workspace.project().read(cx);
|
||||
let recent_matches = workspace
|
||||
.recent_navigation_history(Some(10), cx)
|
||||
.into_iter()
|
||||
.filter_map(|(project_path, _)| {
|
||||
let worktree = project.worktree_for_id(project_path.worktree_id, cx)?;
|
||||
Some(FileMatch {
|
||||
mat: PathMatch {
|
||||
score: 0.,
|
||||
positions: Vec::new(),
|
||||
worktree_id: project_path.worktree_id.to_usize(),
|
||||
path: project_path.path,
|
||||
path_prefix: worktree.read(cx).root_name().into(),
|
||||
distance_to_relative_ancestor: 0,
|
||||
is_dir: false,
|
||||
},
|
||||
is_recent: true,
|
||||
})
|
||||
});
|
||||
|
||||
let file_matches = project.worktrees(cx).flat_map(|worktree| {
|
||||
let worktree = worktree.read(cx);
|
||||
let path_prefix: Arc<str> = worktree.root_name().into();
|
||||
worktree.entries(false, 0).map(move |entry| FileMatch {
|
||||
mat: PathMatch {
|
||||
score: 0.,
|
||||
positions: Vec::new(),
|
||||
worktree_id: worktree.id().to_usize(),
|
||||
path: entry.path.clone(),
|
||||
path_prefix: path_prefix.clone(),
|
||||
distance_to_relative_ancestor: 0,
|
||||
is_dir: entry.is_dir(),
|
||||
},
|
||||
is_recent: false,
|
||||
})
|
||||
});
|
||||
|
||||
Task::ready(recent_matches.chain(file_matches).collect())
|
||||
} else {
|
||||
let worktrees = workspace.read(cx).visible_worktrees(cx).collect::<Vec<_>>();
|
||||
let candidate_sets = worktrees
|
||||
.into_iter()
|
||||
.map(|worktree| {
|
||||
let worktree = worktree.read(cx);
|
||||
|
||||
PathMatchCandidateSet {
|
||||
snapshot: worktree.snapshot(),
|
||||
include_ignored: worktree
|
||||
.root_entry()
|
||||
.map_or(false, |entry| entry.is_ignored),
|
||||
include_root_name: true,
|
||||
candidates: project::Candidates::Entries,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let executor = cx.background_executor().clone();
|
||||
cx.foreground_executor().spawn(async move {
|
||||
fuzzy::match_path_sets(
|
||||
candidate_sets.as_slice(),
|
||||
query.as_str(),
|
||||
None,
|
||||
false,
|
||||
100,
|
||||
&cancellation_flag,
|
||||
executor,
|
||||
)
|
||||
.await
|
||||
.into_iter()
|
||||
.map(|mat| FileMatch {
|
||||
mat,
|
||||
is_recent: false,
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_file_name_and_directory(
|
||||
path: &Path,
|
||||
path_prefix: &str,
|
||||
) -> (SharedString, Option<SharedString>) {
|
||||
if path == Path::new("") {
|
||||
(
|
||||
SharedString::from(
|
||||
path_prefix
|
||||
.trim_end_matches(std::path::MAIN_SEPARATOR)
|
||||
.to_string(),
|
||||
),
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
let file_name = path
|
||||
.file_name()
|
||||
.unwrap_or_default()
|
||||
.to_string_lossy()
|
||||
.to_string()
|
||||
.into();
|
||||
|
||||
let mut directory = path_prefix
|
||||
.trim_end_matches(std::path::MAIN_SEPARATOR)
|
||||
.to_string();
|
||||
if !directory.ends_with('/') {
|
||||
directory.push('/');
|
||||
}
|
||||
if let Some(parent) = path.parent().filter(|parent| parent != &Path::new("")) {
|
||||
directory.push_str(&parent.to_string_lossy());
|
||||
directory.push('/');
|
||||
}
|
||||
|
||||
(file_name, Some(directory.into()))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_file_context_entry(
|
||||
id: ElementId,
|
||||
worktree_id: WorktreeId,
|
||||
path: &Arc<Path>,
|
||||
path_prefix: &Arc<str>,
|
||||
is_directory: bool,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
cx: &App,
|
||||
) -> Stateful<Div> {
|
||||
let (file_name, directory) = extract_file_name_and_directory(&path, path_prefix);
|
||||
|
||||
let added = context_store.upgrade().and_then(|context_store| {
|
||||
let project_path = ProjectPath {
|
||||
worktree_id,
|
||||
path: path.clone(),
|
||||
};
|
||||
if is_directory {
|
||||
context_store.read(cx).includes_directory(&project_path)
|
||||
} else {
|
||||
context_store
|
||||
.read(cx)
|
||||
.will_include_file_path(&project_path, cx)
|
||||
}
|
||||
});
|
||||
|
||||
let file_icon = if is_directory {
|
||||
FileIcons::get_folder_icon(false, cx)
|
||||
} else {
|
||||
FileIcons::get_icon(&path, cx)
|
||||
}
|
||||
.map(Icon::from_path)
|
||||
.unwrap_or_else(|| Icon::new(IconName::File));
|
||||
|
||||
h_flex()
|
||||
.id(id)
|
||||
.gap_1p5()
|
||||
.w_full()
|
||||
.child(file_icon.size(IconSize::Small).color(Color::Muted))
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(Label::new(file_name))
|
||||
.children(directory.map(|directory| {
|
||||
Label::new(directory)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted)
|
||||
})),
|
||||
)
|
||||
.when_some(added, |el, added| match added {
|
||||
FileInclusion::Direct(_) => el.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.justify_end()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Icon::new(IconName::Check)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Success),
|
||||
)
|
||||
.child(Label::new("Added").size(LabelSize::Small)),
|
||||
),
|
||||
FileInclusion::InDirectory(directory_project_path) => {
|
||||
// TODO: Consider using worktree full_path to include worktree name.
|
||||
let directory_path = directory_project_path.path.to_string_lossy().into_owned();
|
||||
|
||||
el.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.justify_end()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Icon::new(IconName::Check)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Success),
|
||||
)
|
||||
.child(Label::new("Included").size(LabelSize::Small)),
|
||||
)
|
||||
.tooltip(Tooltip::text(format!("in {directory_path}")))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1,447 +0,0 @@
|
||||
use std::cmp::Reverse;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
|
||||
use anyhow::Result;
|
||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
App, AppContext, DismissEvent, Entity, FocusHandle, Focusable, Stateful, Task, WeakEntity,
|
||||
};
|
||||
use ordered_float::OrderedFloat;
|
||||
use picker::{Picker, PickerDelegate};
|
||||
use project::{DocumentSymbol, Symbol};
|
||||
use text::OffsetRangeExt;
|
||||
use ui::{ListItem, prelude::*};
|
||||
use util::ResultExt as _;
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::context_picker::{ConfirmBehavior, ContextPicker};
|
||||
use crate::context_store::ContextStore;
|
||||
|
||||
pub struct SymbolContextPicker {
|
||||
picker: Entity<Picker<SymbolContextPickerDelegate>>,
|
||||
}
|
||||
|
||||
impl SymbolContextPicker {
|
||||
pub fn new(
|
||||
context_picker: WeakEntity<ContextPicker>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let delegate = SymbolContextPickerDelegate::new(
|
||||
context_picker,
|
||||
workspace,
|
||||
context_store,
|
||||
confirm_behavior,
|
||||
);
|
||||
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||
|
||||
Self { picker }
|
||||
}
|
||||
}
|
||||
|
||||
impl Focusable for SymbolContextPicker {
|
||||
fn focus_handle(&self, cx: &App) -> FocusHandle {
|
||||
self.picker.focus_handle(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for SymbolContextPicker {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||
self.picker.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SymbolContextPickerDelegate {
|
||||
context_picker: WeakEntity<ContextPicker>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
matches: Vec<SymbolEntry>,
|
||||
selected_index: usize,
|
||||
}
|
||||
|
||||
impl SymbolContextPickerDelegate {
|
||||
pub fn new(
|
||||
context_picker: WeakEntity<ContextPicker>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
confirm_behavior: ConfirmBehavior,
|
||||
) -> Self {
|
||||
Self {
|
||||
context_picker,
|
||||
workspace,
|
||||
context_store,
|
||||
confirm_behavior,
|
||||
matches: Vec::new(),
|
||||
selected_index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PickerDelegate for SymbolContextPickerDelegate {
|
||||
type ListItem = ListItem;
|
||||
|
||||
fn match_count(&self) -> usize {
|
||||
self.matches.len()
|
||||
}
|
||||
|
||||
fn selected_index(&self) -> usize {
|
||||
self.selected_index
|
||||
}
|
||||
|
||||
fn set_selected_index(
|
||||
&mut self,
|
||||
ix: usize,
|
||||
_window: &mut Window,
|
||||
_cx: &mut Context<Picker<Self>>,
|
||||
) {
|
||||
self.selected_index = ix;
|
||||
}
|
||||
|
||||
fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc<str> {
|
||||
"Search symbols…".into()
|
||||
}
|
||||
|
||||
fn update_matches(
|
||||
&mut self,
|
||||
query: String,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return Task::ready(());
|
||||
};
|
||||
|
||||
let search_task = search_symbols(query, Arc::<AtomicBool>::default(), &workspace, cx);
|
||||
let context_store = self.context_store.clone();
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let symbols = search_task.await;
|
||||
|
||||
let symbol_entries = context_store
|
||||
.read_with(cx, |context_store, cx| {
|
||||
compute_symbol_entries(symbols, context_store, cx)
|
||||
})
|
||||
.log_err()
|
||||
.unwrap_or_default();
|
||||
|
||||
this.update(cx, |this, _cx| {
|
||||
this.delegate.matches = symbol_entries;
|
||||
})
|
||||
.log_err();
|
||||
})
|
||||
}
|
||||
|
||||
fn confirm(&mut self, _secondary: bool, window: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
let Some(mat) = self.matches.get(self.selected_index) else {
|
||||
return;
|
||||
};
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let confirm_behavior = self.confirm_behavior;
|
||||
let add_symbol_task = add_symbol(
|
||||
mat.symbol.clone(),
|
||||
true,
|
||||
workspace,
|
||||
self.context_store.clone(),
|
||||
cx,
|
||||
);
|
||||
|
||||
let selected_index = self.selected_index;
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
let included = add_symbol_task.await?;
|
||||
this.update_in(cx, |this, window, cx| {
|
||||
if let Some(mat) = this.delegate.matches.get_mut(selected_index) {
|
||||
mat.is_included = included;
|
||||
}
|
||||
match confirm_behavior {
|
||||
ConfirmBehavior::KeepOpen => {}
|
||||
ConfirmBehavior::Close => this.delegate.dismissed(window, cx),
|
||||
}
|
||||
})
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
|
||||
fn dismissed(&mut self, _: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
self.context_picker
|
||||
.update(cx, |_, cx| {
|
||||
cx.emit(DismissEvent);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
fn render_match(
|
||||
&self,
|
||||
ix: usize,
|
||||
selected: bool,
|
||||
_window: &mut Window,
|
||||
_: &mut Context<Picker<Self>>,
|
||||
) -> Option<Self::ListItem> {
|
||||
let mat = &self.matches[ix];
|
||||
|
||||
Some(ListItem::new(ix).inset(true).toggle_state(selected).child(
|
||||
render_symbol_context_entry(
|
||||
ElementId::NamedInteger("symbol-ctx-picker".into(), ix),
|
||||
mat,
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SymbolEntry {
|
||||
pub symbol: Symbol,
|
||||
pub is_included: bool,
|
||||
}
|
||||
|
||||
pub(crate) fn add_symbol(
|
||||
symbol: Symbol,
|
||||
remove_if_exists: bool,
|
||||
workspace: Entity<Workspace>,
|
||||
context_store: WeakEntity<ContextStore>,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<bool>> {
|
||||
let project = workspace.read(cx).project().clone();
|
||||
let open_buffer_task = project.update(cx, |project, cx| {
|
||||
project.open_buffer(symbol.path.clone(), cx)
|
||||
});
|
||||
cx.spawn(async move |cx| {
|
||||
let buffer = open_buffer_task.await?;
|
||||
let document_symbols = project
|
||||
.update(cx, |project, cx| project.document_symbols(&buffer, cx))?
|
||||
.await?;
|
||||
|
||||
// Try to find a matching document symbol. Document symbols include
|
||||
// not only the symbol itself (e.g. function name), but they also
|
||||
// include the context that they contain (e.g. function body).
|
||||
let (name, range, enclosing_range) = if let Some(DocumentSymbol {
|
||||
name,
|
||||
range,
|
||||
selection_range,
|
||||
..
|
||||
}) =
|
||||
find_matching_symbol(&symbol, document_symbols.as_slice())
|
||||
{
|
||||
(name, selection_range, range)
|
||||
} else {
|
||||
// If we do not find a matching document symbol, fall back to
|
||||
// just the symbol itself
|
||||
(symbol.name, symbol.range.clone(), symbol.range)
|
||||
};
|
||||
|
||||
let (range, enclosing_range) = buffer.read_with(cx, |buffer, _| {
|
||||
(
|
||||
buffer.anchor_after(range.start)..buffer.anchor_before(range.end),
|
||||
buffer.anchor_after(enclosing_range.start)
|
||||
..buffer.anchor_before(enclosing_range.end),
|
||||
)
|
||||
})?;
|
||||
|
||||
context_store
|
||||
.update(cx, move |context_store, cx| {
|
||||
context_store.add_symbol(
|
||||
buffer,
|
||||
name.into(),
|
||||
range,
|
||||
enclosing_range,
|
||||
remove_if_exists,
|
||||
cx,
|
||||
)
|
||||
})?
|
||||
.await
|
||||
})
|
||||
}
|
||||
|
||||
fn find_matching_symbol(symbol: &Symbol, candidates: &[DocumentSymbol]) -> Option<DocumentSymbol> {
|
||||
let mut candidates = candidates.iter();
|
||||
let mut candidate = candidates.next()?;
|
||||
|
||||
loop {
|
||||
if candidate.range.start > symbol.range.end {
|
||||
return None;
|
||||
}
|
||||
if candidate.range.end < symbol.range.start {
|
||||
candidate = candidates.next()?;
|
||||
continue;
|
||||
}
|
||||
if candidate.selection_range == symbol.range {
|
||||
return Some(candidate.clone());
|
||||
}
|
||||
if candidate.range.start <= symbol.range.start && symbol.range.end <= candidate.range.end {
|
||||
candidates = candidate.children.iter();
|
||||
candidate = candidates.next()?;
|
||||
continue;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SymbolMatch {
|
||||
pub symbol: Symbol,
|
||||
}
|
||||
|
||||
pub(crate) fn search_symbols(
|
||||
query: String,
|
||||
cancellation_flag: Arc<AtomicBool>,
|
||||
workspace: &Entity<Workspace>,
|
||||
cx: &mut App,
|
||||
) -> Task<Vec<SymbolMatch>> {
|
||||
let symbols_task = workspace.update(cx, |workspace, cx| {
|
||||
workspace
|
||||
.project()
|
||||
.update(cx, |project, cx| project.symbols(&query, cx))
|
||||
});
|
||||
let project = workspace.read(cx).project().clone();
|
||||
cx.spawn(async move |cx| {
|
||||
let Some(symbols) = symbols_task.await.log_err() else {
|
||||
return Vec::new();
|
||||
};
|
||||
let Some((visible_match_candidates, external_match_candidates)): Option<(Vec<_>, Vec<_>)> =
|
||||
project
|
||||
.update(cx, |project, cx| {
|
||||
symbols
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(id, symbol)| {
|
||||
StringMatchCandidate::new(id, &symbol.label.filter_text())
|
||||
})
|
||||
.partition(|candidate| {
|
||||
project
|
||||
.entry_for_path(&symbols[candidate.id].path, cx)
|
||||
.map_or(false, |e| !e.is_ignored)
|
||||
})
|
||||
})
|
||||
.log_err()
|
||||
else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
const MAX_MATCHES: usize = 100;
|
||||
let mut visible_matches = cx.background_executor().block(fuzzy::match_strings(
|
||||
&visible_match_candidates,
|
||||
&query,
|
||||
false,
|
||||
MAX_MATCHES,
|
||||
&cancellation_flag,
|
||||
cx.background_executor().clone(),
|
||||
));
|
||||
let mut external_matches = cx.background_executor().block(fuzzy::match_strings(
|
||||
&external_match_candidates,
|
||||
&query,
|
||||
false,
|
||||
MAX_MATCHES - visible_matches.len().min(MAX_MATCHES),
|
||||
&cancellation_flag,
|
||||
cx.background_executor().clone(),
|
||||
));
|
||||
let sort_key_for_match = |mat: &StringMatch| {
|
||||
let symbol = &symbols[mat.candidate_id];
|
||||
(Reverse(OrderedFloat(mat.score)), symbol.label.filter_text())
|
||||
};
|
||||
|
||||
visible_matches.sort_unstable_by_key(sort_key_for_match);
|
||||
external_matches.sort_unstable_by_key(sort_key_for_match);
|
||||
let mut matches = visible_matches;
|
||||
matches.append(&mut external_matches);
|
||||
|
||||
matches
|
||||
.into_iter()
|
||||
.map(|mut mat| {
|
||||
let symbol = symbols[mat.candidate_id].clone();
|
||||
let filter_start = symbol.label.filter_range.start;
|
||||
for position in &mut mat.positions {
|
||||
*position += filter_start;
|
||||
}
|
||||
SymbolMatch { symbol }
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
fn compute_symbol_entries(
|
||||
symbols: Vec<SymbolMatch>,
|
||||
context_store: &ContextStore,
|
||||
cx: &App,
|
||||
) -> Vec<SymbolEntry> {
|
||||
let mut symbol_entries = Vec::with_capacity(symbols.len());
|
||||
for SymbolMatch { symbol, .. } in symbols {
|
||||
let symbols_for_path = context_store.included_symbols_by_path().get(&symbol.path);
|
||||
let is_included = if let Some(symbols_for_path) = symbols_for_path {
|
||||
let mut is_included = false;
|
||||
for included_symbol_id in symbols_for_path {
|
||||
if included_symbol_id.name.as_ref() == symbol.name.as_str() {
|
||||
if let Some(buffer) = context_store.buffer_for_symbol(included_symbol_id) {
|
||||
let snapshot = buffer.read(cx).snapshot();
|
||||
let included_symbol_range =
|
||||
included_symbol_id.range.to_point_utf16(&snapshot);
|
||||
|
||||
if included_symbol_range.start == symbol.range.start.0
|
||||
&& included_symbol_range.end == symbol.range.end.0
|
||||
{
|
||||
is_included = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is_included
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
symbol_entries.push(SymbolEntry {
|
||||
symbol,
|
||||
is_included,
|
||||
})
|
||||
}
|
||||
symbol_entries
|
||||
}
|
||||
|
||||
pub fn render_symbol_context_entry(id: ElementId, entry: &SymbolEntry) -> Stateful<Div> {
|
||||
let path = entry
|
||||
.symbol
|
||||
.path
|
||||
.path
|
||||
.file_name()
|
||||
.map(|s| s.to_string_lossy())
|
||||
.unwrap_or_default();
|
||||
let symbol_location = format!("{} L{}", path, entry.symbol.range.start.0.row + 1);
|
||||
|
||||
h_flex()
|
||||
.id(id)
|
||||
.gap_1p5()
|
||||
.w_full()
|
||||
.child(
|
||||
Icon::new(IconName::Code)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Muted),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.child(Label::new(&entry.symbol.name))
|
||||
.child(
|
||||
Label::new(symbol_location)
|
||||
.size(LabelSize::Small)
|
||||
.color(Color::Muted),
|
||||
),
|
||||
)
|
||||
.when(entry.is_included, |el| {
|
||||
el.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.justify_end()
|
||||
.gap_0p5()
|
||||
.child(
|
||||
Icon::new(IconName::Check)
|
||||
.size(IconSize::Small)
|
||||
.color(Color::Success),
|
||||
)
|
||||
.child(Label::new("Added").size(LabelSize::Small)),
|
||||
)
|
||||
})
|
||||
}
|
||||