mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Merge branch 'main' into feat/git-bash-shell-integration
This commit is contained in:
commit
a06bbd27d8
|
@ -154,8 +154,6 @@
|
|||
"src/vs/editor/contrib/codeAction/test/browser/codeActionModel.test.ts",
|
||||
"src/vs/editor/test/common/services/languageService.test.ts",
|
||||
"src/vs/editor/test/node/classification/typescript.test.ts",
|
||||
"src/vs/editor/test/node/diffing/defaultLinesDiffComputer.test.ts",
|
||||
"src/vs/editor/test/node/diffing/fixtures.test.ts",
|
||||
"src/vs/platform/configuration/test/common/configuration.test.ts",
|
||||
"src/vs/platform/extensions/test/common/extensionValidator.test.ts",
|
||||
"src/vs/platform/opener/test/common/opener.test.ts",
|
||||
|
|
4
.yarnrc
4
.yarnrc
|
@ -1,5 +1,5 @@
|
|||
disturl "https://electronjs.org/headers"
|
||||
target "28.2.6"
|
||||
ms_build_id "27476517"
|
||||
target "28.2.8"
|
||||
ms_build_id "27744544"
|
||||
runtime "electron"
|
||||
build_from_source "true"
|
||||
|
|
|
@ -1,75 +1,75 @@
|
|||
2cd042f38fd13cbb3ed0e7205c6c892cd5f04fd4992d18da363b8f0df9dda3eb *chromedriver-v28.2.6-darwin-arm64.zip
|
||||
05bc772ecb5728cde1efed2308074ad53a4abfe7c541a82d6fef62d3350c6cf4 *chromedriver-v28.2.6-darwin-x64.zip
|
||||
4c7ea31be89009fcedfe8e3619be61bec6056c8bb9ea93b4e6a5deec791f8c55 *chromedriver-v28.2.6-linux-arm64.zip
|
||||
ae61e86c512dff5108f2240018c3b549b57e25f3f31e822effb7f1d5a53cd474 *chromedriver-v28.2.6-linux-armv7l.zip
|
||||
d2eac837adf3691abfab267d5e5f2428450c3ca506d74e47382bd0ae73755a4a *chromedriver-v28.2.6-linux-x64.zip
|
||||
326f6f4ce44e42bae98894eb3f3ef125fe887a1188ce98d8cc1e8b68862283fe *chromedriver-v28.2.6-mas-arm64.zip
|
||||
4cb08690d4db116f115e5da2f2d9ed9ccb287a33a8c9cb7264dba1329117f979 *chromedriver-v28.2.6-mas-x64.zip
|
||||
ce1124ac3e5b91efc78d95260e5ecb001b362f12f1c9d2abc71fc3e8140aefb1 *chromedriver-v28.2.6-win32-arm64.zip
|
||||
1a36b630b828953873a102c118d7954409de7ae0e40bdcb325baca0915fde4ff *chromedriver-v28.2.6-win32-ia32.zip
|
||||
7e138e53e1acada2047c9adda42ee3760397cda56f7c73f30b48f69c51fb136f *chromedriver-v28.2.6-win32-x64.zip
|
||||
f8809dc99407cc14bdc6579a6205d391ecf285a6d9ef49a34d529371616cd032 *electron-api.json
|
||||
3bd369be1ce7175a637eb5531317c49c13287152cae4e0cfb875acdceee92fe3 *electron-v28.2.6-darwin-arm64-dsym-snapshot.zip
|
||||
0020309287b4eef7cc59b761a1d604af80cca6d195cfecea5b97b834ba808d2a *electron-v28.2.6-darwin-arm64-dsym.zip
|
||||
b1aeb1b30a965cf439456beaa3e99228437f3f9f91ddbbfa27a1695143a8a892 *electron-v28.2.6-darwin-arm64-symbols.zip
|
||||
432ef2d5767991347c9452961e392182baa761d0b8b23483c1117a8c75bf18e9 *electron-v28.2.6-darwin-arm64.zip
|
||||
c4723e680bf78ebe7e4a151d0b68c8e698985c36007237e9c5ffbd3976451519 *electron-v28.2.6-darwin-x64-dsym-snapshot.zip
|
||||
86845958cedf3af045f07fd287066678e0ff73a8caf29c8032e8def0d3277b23 *electron-v28.2.6-darwin-x64-dsym.zip
|
||||
450f7324fb9b0baed557133af50c8772a4b3e33f1288a7e732f7cc8fbd9df30d *electron-v28.2.6-darwin-x64-symbols.zip
|
||||
524d710d21d64b539e568946debb3659b8e8071ead56c4b1a598c7c76fc32089 *electron-v28.2.6-darwin-x64.zip
|
||||
c6ecf165f51d7da20278324a7454cc5119e6e546527dc9f21e7d4701f062443d *electron-v28.2.6-linux-arm64-debug.zip
|
||||
cb495ec65c3a5cb6639a2ff1110f588cc82df241982e5cbb91932990de723772 *electron-v28.2.6-linux-arm64-symbols.zip
|
||||
cdc832c6e337a2241bec78b7130f21c6db01d90d0ef93cd3c934f220319fa696 *electron-v28.2.6-linux-arm64.zip
|
||||
c6ecf165f51d7da20278324a7454cc5119e6e546527dc9f21e7d4701f062443d *electron-v28.2.6-linux-armv7l-debug.zip
|
||||
9eb155513a0a6f6fa518c2c768e0cc483a3e35c7beb7b657211df7bcf33ad144 *electron-v28.2.6-linux-armv7l-symbols.zip
|
||||
6e340b9468950d8d3b5a9bf7840622403346f043af3f25471beff32212d227ce *electron-v28.2.6-linux-armv7l.zip
|
||||
51567b886d0510726e733d9ecb33f32f14c78ee8cdedfa56adae26c0ac59b890 *electron-v28.2.6-linux-x64-debug.zip
|
||||
fd6e2bc61e6df6113a74503d60bdea23d6734ba75bc270fa87f2a99a472d2e22 *electron-v28.2.6-linux-x64-symbols.zip
|
||||
a5ec62621ccd0cd4636dc290a0406abc706c2900b518b085bff2312a5ee1dc6f *electron-v28.2.6-linux-x64.zip
|
||||
1fb074339d42ef399254199418849f0fd591ba6bb203ab0570be192d7225921a *electron-v28.2.6-mas-arm64-dsym-snapshot.zip
|
||||
3a8228698d1a85103eb3958de0ba8d77f1129a4eca44227a46dc70eda3ce2abc *electron-v28.2.6-mas-arm64-dsym.zip
|
||||
3668d2aa7d00679f93106b1feb1dab4f1284bf5c6a041aa47284693786b3ad08 *electron-v28.2.6-mas-arm64-symbols.zip
|
||||
ba40b18e6964fa96a72a86984032b534b94596b5a29418d286fba090f6ec8076 *electron-v28.2.6-mas-arm64.zip
|
||||
dc7d071fb39d89c65745f6a567011959c4cd32e60e95cb92d970bc0ca89da26f *electron-v28.2.6-mas-x64-dsym-snapshot.zip
|
||||
812909c73e1ebcb121e7874ae2250ed55ce58e3ef651fcfac9bd92284b1f6d69 *electron-v28.2.6-mas-x64-dsym.zip
|
||||
fd720ee5353c20ff1ff0dc1b8eeaa64f28f7860268d5f8528d468ced0375086b *electron-v28.2.6-mas-x64-symbols.zip
|
||||
9ce774a52e32a7df11c6ca20ae766303a33f1fd9000c628238fe93426b73216e *electron-v28.2.6-mas-x64.zip
|
||||
952360b9cc257c145de62111cf9f0569892b3dfde3d4f8246b4025d8931c0377 *electron-v28.2.6-win32-arm64-pdb.zip
|
||||
095500f4db01a8448cf7263a9db053446d88c08e1f6abd9a84323b7c45bd5a25 *electron-v28.2.6-win32-arm64-symbols.zip
|
||||
c9f31ae6408aa6936b5d683eda601773789185890375cd097e61e924d4fed77a *electron-v28.2.6-win32-arm64-toolchain-profile.zip
|
||||
99b24366555381bdaf35e4b85956941c859afbbfc52b5cc66bbda7ace4bcdc26 *electron-v28.2.6-win32-arm64.zip
|
||||
85f92b7d9f5689c92216c71b3e76a3e1181f3b74b1a30649c5870126d197c057 *electron-v28.2.6-win32-ia32-pdb.zip
|
||||
276b143933a186e397820424fddc6d0488d3293828e76273d64a6d642b64b67d *electron-v28.2.6-win32-ia32-symbols.zip
|
||||
c9f31ae6408aa6936b5d683eda601773789185890375cd097e61e924d4fed77a *electron-v28.2.6-win32-ia32-toolchain-profile.zip
|
||||
8f4547b567c5e88b7b5c08381d9da21210cbf796cf4b8348f2f15c139d03dc3a *electron-v28.2.6-win32-ia32.zip
|
||||
1e875caf77e8ba4f622743e015522b1bef6b73eacebbfb00b9f62cd1fd46a3d3 *electron-v28.2.6-win32-x64-pdb.zip
|
||||
c57843add2a3106247c3e16b5a246bfb43a046a114826f222004d72c54ab6e0b *electron-v28.2.6-win32-x64-symbols.zip
|
||||
c9f31ae6408aa6936b5d683eda601773789185890375cd097e61e924d4fed77a *electron-v28.2.6-win32-x64-toolchain-profile.zip
|
||||
cc27e8af85c8cde97cc53204b612365f3b1c53215e19bb5b6f303ea9491b4953 *electron-v28.2.6-win32-x64.zip
|
||||
be5b134abac3cb2f771246712a564080b2e63475fe9f09accc7acb6ade03af3f *electron.d.ts
|
||||
767539ad20af8cda91da9bf35183ddaea7a09aa3ee8274d2677f407502f24295 *ffmpeg-v28.2.6-darwin-arm64.zip
|
||||
af8422c1596adf13887cac74aa185d3c84787174af305a49e558664162c0bbed *ffmpeg-v28.2.6-darwin-x64.zip
|
||||
8e108e533811febcc51f377ac8604d506663453e41c02dc818517e1ea9a4e8d5 *ffmpeg-v28.2.6-linux-arm64.zip
|
||||
51ecd03435f56a2ced31b1c9dbf281955ba82a814ca0214a4292bdc711e5a45c *ffmpeg-v28.2.6-linux-armv7l.zip
|
||||
acc9dc3765f68b7563045e2d0df11bbef6b41be0a1c34bbf9fa778f36eefb42f *ffmpeg-v28.2.6-linux-x64.zip
|
||||
d478d239203f337f146ba2d6f5af6640a82a8591faac23017f8709e0fbb61d8a *ffmpeg-v28.2.6-mas-arm64.zip
|
||||
77bb31ee80979dce6b1ee786ab39eba7dd56dbdf29101e7046ee8cea1938e350 *ffmpeg-v28.2.6-mas-x64.zip
|
||||
fc406f7a4239d5c37d4dbc44907184213b7e07de9d39796cbef7eaa4ead92549 *ffmpeg-v28.2.6-win32-arm64.zip
|
||||
abd92844333712e2a2a891b2679cbaf434daf7aa50c371bfccccd553d2394300 *ffmpeg-v28.2.6-win32-ia32.zip
|
||||
c5ce83bdfeb037f315bea8c97bfae344ebbec255fd173a7a769fd276b2bdbf28 *ffmpeg-v28.2.6-win32-x64.zip
|
||||
cc27058b50af2fe95070f52aa72e417f27f440cac2ae0471f31af061181272fd *hunspell_dictionaries.zip
|
||||
b593c7f79c5fd49794dcf260ebd8e5b757313b467d3f671c5d2422f7ed3829f2 *libcxx-objects-v28.2.6-linux-arm64.zip
|
||||
92a9f593ccb41c5507c0be01f1ec061d4090290e45c9b6aa003070b4b8fcb839 *libcxx-objects-v28.2.6-linux-armv7l.zip
|
||||
fce1088e2bbc3bbcacae1741c2f7f2508ddf0e00f41450ff96d83df655ee431e *libcxx-objects-v28.2.6-linux-x64.zip
|
||||
ee7ad0db6eb01ee72a70bc6ecf27428d1fd31ab52329fb75aa2b2a9702b1c1d7 *libcxx_headers.zip
|
||||
1a2473c8e94c23a2c00a580c1ae379e2e74cae89ccf9dae977ceb9ba44658801 *libcxxabi_headers.zip
|
||||
9365c442b6bbce858814028fed11a79a518e64d433d01821264afdf5492f9308 *mksnapshot-v28.2.6-darwin-arm64.zip
|
||||
8410f72e3696691cb38ea31acfc6d501291df43bd20636059aaafbef9dc7757d *mksnapshot-v28.2.6-darwin-x64.zip
|
||||
e081547def25c9af1f1ace4aa3ed0ee175bae7c401c92ee42988981d605cb8a7 *mksnapshot-v28.2.6-linux-arm64-x64.zip
|
||||
c6b2d51a82fd10a04532f33385c78921dd85722a9fe3de107ab4809df08ae0e8 *mksnapshot-v28.2.6-linux-armv7l-x64.zip
|
||||
dc80bc57f86e361e0769e1ed62b1d083c0dd1d160c6fcb2c10ae821a83ae6333 *mksnapshot-v28.2.6-linux-x64.zip
|
||||
9ff56ed57c48df1e449c334bbe61874bd495d92978924565fdd2ec99e5be7a54 *mksnapshot-v28.2.6-mas-arm64.zip
|
||||
fb04465058adad0e56f7c3dfa6d9d85b249554595925669e7454348e28490e02 *mksnapshot-v28.2.6-mas-x64.zip
|
||||
681633334d9eaab61ab95c3718ba98e7bf339615b6189d51b0782b77f5e8eaea *mksnapshot-v28.2.6-win32-arm64-x64.zip
|
||||
d3986690b413d43cc6a003f8e09fd07bf213eb5f006f3419e9615fcc09d4891d *mksnapshot-v28.2.6-win32-ia32.zip
|
||||
b26942469d96148f7ec410996d9e4c34c3c013a441e568b05c87e36a3d9ae441 *mksnapshot-v28.2.6-win32-x64.zip
|
||||
69b40637a88ad4c17877b3d665b39ad0e11928aa71b19ef45f5b76250d1c9786 *chromedriver-v28.2.8-darwin-arm64.zip
|
||||
3a9ce6179228245f2c7878c4238e10d51c77dc20642922a226ccc235a20f5a29 *chromedriver-v28.2.8-darwin-x64.zip
|
||||
7f6470ea5d86dbe68fcc3fccfefd3b7135ba3468ef54b0235bf57cedeabf433d *chromedriver-v28.2.8-linux-arm64.zip
|
||||
4bfe709d58b237f5c5a7618b2abecf533dac9415d327e763ad6cf622218517cc *chromedriver-v28.2.8-linux-armv7l.zip
|
||||
7558ee413f96f88b9b9ad5787dd433adcfaf56411fdf052826d39d204ebaba9d *chromedriver-v28.2.8-linux-x64.zip
|
||||
9814583b075d969c32afb6e929b4bf7956b0223fded996c91341388b8f638dd6 *chromedriver-v28.2.8-mas-arm64.zip
|
||||
82d11c6606db9aea355b1e410083c72bd1e39abb9e34a839c16b16b75364ea0d *chromedriver-v28.2.8-mas-x64.zip
|
||||
4803a5335a40ba208136094f5adfde2c4272761d34e0e9e9f4febc2ef676c3ad *chromedriver-v28.2.8-win32-arm64.zip
|
||||
7b079f47869f7e96a5829f6fb7eff032394f76218b39a2aaf73cc93ce8a68050 *chromedriver-v28.2.8-win32-ia32.zip
|
||||
2aedd176d4f72b29cd1914364e813756d52f53558df32e3429996b820edc994d *chromedriver-v28.2.8-win32-x64.zip
|
||||
ae1a521aa36053a3b60b318d7bc093ec7579af6aa8b02bffe1f9e70d6922b726 *electron-api.json
|
||||
a916f0cc438258f42f43955157565e7eca14966266f3fb123c8c736bece97daa *electron-v28.2.8-darwin-arm64-dsym-snapshot.zip
|
||||
3c31d0a105b0632f15aa8adc68f06dc8ca47b1fdf1e62d1436ac43af117a22fb *electron-v28.2.8-darwin-arm64-dsym.zip
|
||||
dab03f1cd7b499552d503bcca2fc1c3f40a1d2c463655ca3ace20778f08e9b04 *electron-v28.2.8-darwin-arm64-symbols.zip
|
||||
2965d8c8d64fb6c51f5a283a246de653bfae22fe4bf9adf6c04592afabf62f04 *electron-v28.2.8-darwin-arm64.zip
|
||||
03511a34d94d27eb576ab20e3a432c082a32a298475c7a85a329e029dddc55e4 *electron-v28.2.8-darwin-x64-dsym-snapshot.zip
|
||||
96089786bd2723786673561c9b6f9a154928de663f2411f10153e6c985703eef *electron-v28.2.8-darwin-x64-dsym.zip
|
||||
872789c3c218ab8f98be83c7781e3e6ef0114bd39780d65eaae77e99dbbda1de *electron-v28.2.8-darwin-x64-symbols.zip
|
||||
a7889addd37254f842798bdd3ca34752b75acf6d8dd456cdeb2d75590c0a9ceb *electron-v28.2.8-darwin-x64.zip
|
||||
fb90b8c903407ae575f9c8f727376519c0b35ed6f01dec55b177285b5db864e3 *electron-v28.2.8-linux-arm64-debug.zip
|
||||
591248f7c94a6d7c4a4d8b2fcf63c8e4347018a65e1f68ed90e5549a587062c8 *electron-v28.2.8-linux-arm64-symbols.zip
|
||||
6183db1029cebd9e0fb0e4f2d24a80b0274c5265756e66cb9fa0a480b92c98ea *electron-v28.2.8-linux-arm64.zip
|
||||
fb90b8c903407ae575f9c8f727376519c0b35ed6f01dec55b177285b5db864e3 *electron-v28.2.8-linux-armv7l-debug.zip
|
||||
87c4c534cd1d447b9d4632585a0d79c9d31114bd39ca63df1f2384afae3aa6b7 *electron-v28.2.8-linux-armv7l-symbols.zip
|
||||
2a772b65815a0d47a756eed52f76cd9f27a8c277d7998bfcfe93b84a346eb255 *electron-v28.2.8-linux-armv7l.zip
|
||||
773aa1f0bbe2b79765bf498958565f63957f8ec2e42327978a143dcbbc7f1bea *electron-v28.2.8-linux-x64-debug.zip
|
||||
f8cbc6f2b719cc2f623afcfde8cb1d42614708793621a7a97b328015366b9b8f *electron-v28.2.8-linux-x64-symbols.zip
|
||||
e7d17ee311299dfef3d2916987a513c4c1b66ad2e417c15fa5d29699602bd6cb *electron-v28.2.8-linux-x64.zip
|
||||
5f0179fd7bf3927381bde24c9fb372fe95328be0500918cd6ee7f9503fae1ef5 *electron-v28.2.8-mas-arm64-dsym-snapshot.zip
|
||||
e9810019f1d7b1b5a93fd1aee8adda5a872ebfb170de6d55cdd55162b923432d *electron-v28.2.8-mas-arm64-dsym.zip
|
||||
4781376244c7df89d119575e2788ad43fae4387d850ef672665688081b30997c *electron-v28.2.8-mas-arm64-symbols.zip
|
||||
a3932199781970e0b2fdb805d6556287ca877b35ac19384da00474140e14c41f *electron-v28.2.8-mas-arm64.zip
|
||||
326cde32079496e0d976c5b65e85e5ce208eea3d8d23cd92c9e25f0fa6b30f40 *electron-v28.2.8-mas-x64-dsym-snapshot.zip
|
||||
59a2b3d28dba45ee3016f8ab49a71b0c55f99ef046476183bc36890c9d335a71 *electron-v28.2.8-mas-x64-dsym.zip
|
||||
313ff88f568c39079a1b7a1011f77fa03890cb9bb53649a489643311303cc3b8 *electron-v28.2.8-mas-x64-symbols.zip
|
||||
41ab9f3addea5066d7e0ace28ebaead7128a2073931473c847aa9133b7df9248 *electron-v28.2.8-mas-x64.zip
|
||||
179de6dd4835216bcd3e8bb9eb4d4b54013df865f52dbf0d5214726fc31cba9a *electron-v28.2.8-win32-arm64-pdb.zip
|
||||
8628dec571206001420c1d8655904883d5de7e772d51ab2101b002c22e0dd25c *electron-v28.2.8-win32-arm64-symbols.zip
|
||||
c9f31ae6408aa6936b5d683eda601773789185890375cd097e61e924d4fed77a *electron-v28.2.8-win32-arm64-toolchain-profile.zip
|
||||
bb2a2a466d14c32c06ff09c42b3d1413f19fdc8a49a445d07d289fa453c268d3 *electron-v28.2.8-win32-arm64.zip
|
||||
1d1efc3a1d17072bc76a4a63c8236a896d46f6f3badacd50bc5824149196d56f *electron-v28.2.8-win32-ia32-pdb.zip
|
||||
9ddb1520de421a7c636160d01432c9bf111e6ef4b9a3be41b185c702c72353ac *electron-v28.2.8-win32-ia32-symbols.zip
|
||||
c9f31ae6408aa6936b5d683eda601773789185890375cd097e61e924d4fed77a *electron-v28.2.8-win32-ia32-toolchain-profile.zip
|
||||
38e22f9b0a32e0fc26e81905214e244c0a5d5c19e13c8ca2329ac75b62881472 *electron-v28.2.8-win32-ia32.zip
|
||||
8168296e0454377e0113a7d0f87535d3d0e0c1a8538e8079ee1aae9c7223bb02 *electron-v28.2.8-win32-x64-pdb.zip
|
||||
a276e9e748fa7db970e7dcce6f4ae571d8615a44e5208c0fa3c03de08774a4aa *electron-v28.2.8-win32-x64-symbols.zip
|
||||
c9f31ae6408aa6936b5d683eda601773789185890375cd097e61e924d4fed77a *electron-v28.2.8-win32-x64-toolchain-profile.zip
|
||||
079cc98f7933992ac7154e21e160d4a4c6b3541c26b56fc6f8438e9eabc369b9 *electron-v28.2.8-win32-x64.zip
|
||||
f838e4a7c24518c5fa25d4a23acf869737cfa88761019cea4f83ebfb302363ec *electron.d.ts
|
||||
4450bcc66cece4ff2373563e0123799f95645fa155577a8f380211b29e8b4ec9 *ffmpeg-v28.2.8-darwin-arm64.zip
|
||||
152e3ed53098d24f356d7ec640d19efc57f7f34c39d8b8278f2586985d4a99a1 *ffmpeg-v28.2.8-darwin-x64.zip
|
||||
8e108e533811febcc51f377ac8604d506663453e41c02dc818517e1ea9a4e8d5 *ffmpeg-v28.2.8-linux-arm64.zip
|
||||
51ecd03435f56a2ced31b1c9dbf281955ba82a814ca0214a4292bdc711e5a45c *ffmpeg-v28.2.8-linux-armv7l.zip
|
||||
acc9dc3765f68b7563045e2d0df11bbef6b41be0a1c34bbf9fa778f36eefb42f *ffmpeg-v28.2.8-linux-x64.zip
|
||||
15a2a4a28a66e65122eb4f2bd796ccd5b6ed45420a034878affd002fc8c290dc *ffmpeg-v28.2.8-mas-arm64.zip
|
||||
2dfe2f524c5220f50c7b6fe08605a67631b5520e0c82842e1f41f677cac17643 *ffmpeg-v28.2.8-mas-x64.zip
|
||||
313e2979f0df88715159c0737bfbb5ae1d5c79fb9820e94d2a93ba71d3324ecd *ffmpeg-v28.2.8-win32-arm64.zip
|
||||
9e73bc07563aefa8b9625676939a410b35a823d961b96da0e8edd90d7e5fb47b *ffmpeg-v28.2.8-win32-ia32.zip
|
||||
1b11042defc8a3f403e5567fa4a4b8c59b224f3b7b52d44d6c7197b96af7b53b *ffmpeg-v28.2.8-win32-x64.zip
|
||||
1e2e9480d4228f6bbc731ff7ee413b9e97656c36b15418d20681a76d82902b86 *hunspell_dictionaries.zip
|
||||
8c8b967cf4c78ed9bbf4921b2c616257f45b137412eb3bc64176066c3e47bbe8 *libcxx-objects-v28.2.8-linux-arm64.zip
|
||||
56af259535ccfaac295b82ce68686f9582265cb2ebe2783852f518c0fabc8a1e *libcxx-objects-v28.2.8-linux-armv7l.zip
|
||||
b590e001dc98e32e5952ca69573e6f1bcec5e2f2d99052d1089ab72084cccea1 *libcxx-objects-v28.2.8-linux-x64.zip
|
||||
c0634d5c92f0a2983b17c866f7d3694cb75f6e78cd07b10d9488ef46acc66a50 *libcxx_headers.zip
|
||||
99ee16441d9eb2b92a05d5a5c9b9dc4cdfab33cb09595e9d78fd2ba503dead5b *libcxxabi_headers.zip
|
||||
a95de1da301d641caaafaea9869c4c7834c254f818ac0c10d97402b2220c8be3 *mksnapshot-v28.2.8-darwin-arm64.zip
|
||||
e5ef6b35d7cd807f93babfedbbde513ab6053ad9fb80b0f7abc1bfda414daaa1 *mksnapshot-v28.2.8-darwin-x64.zip
|
||||
eeb6c5b7962af8d5cfaa97b2cf96d312d0ad57a3abb3e00774d50ea2e005bb9b *mksnapshot-v28.2.8-linux-arm64-x64.zip
|
||||
0adacd0767469f90400b1f17ba8ac3ccb33cfeb11a8ef54d70bc8adb7cc306dc *mksnapshot-v28.2.8-linux-armv7l-x64.zip
|
||||
5242817f1f26e10804e7e2446d0a8a64e8b2958cdba01e79d89db883d9d960d0 *mksnapshot-v28.2.8-linux-x64.zip
|
||||
0ecb67673508c10f4fe08e7cb80300b9a8f507f50994c79caf302ff78ef748ca *mksnapshot-v28.2.8-mas-arm64.zip
|
||||
19429da56077f12de4d4563f49c55f4f1f0fe61f66863804640fc55e65ee98f9 *mksnapshot-v28.2.8-mas-x64.zip
|
||||
c7b47ae63c2f6eb07b06379206e6f215fbcb2b9a49faa72ca850bf8f9b998c4c *mksnapshot-v28.2.8-win32-arm64-x64.zip
|
||||
0032660a9f8575a153951f29adae49a18e400b40906eec803fe7e3d2e970503d *mksnapshot-v28.2.8-win32-ia32.zip
|
||||
2c71c9a2bd4441e580dc3083073e712fba94e0236415c8ab35320da52f492508 *mksnapshot-v28.2.8-win32-x64.zip
|
||||
|
|
|
@ -528,12 +528,12 @@
|
|||
"git": {
|
||||
"name": "electron",
|
||||
"repositoryUrl": "https://github.com/electron/electron",
|
||||
"commitHash": "2977fc4025fbc4c02ae9e87e480a94062b2ca4da"
|
||||
"commitHash": "31cd9d1f61714e20f1067d726404600ab7281698"
|
||||
}
|
||||
},
|
||||
"isOnlyProductionDependency": true,
|
||||
"license": "MIT",
|
||||
"version": "28.2.6"
|
||||
"version": "28.2.8"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"license": "MIT",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "5.4"
|
||||
"typescript": "5.4.3"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall.mjs"
|
||||
|
|
|
@ -234,10 +234,10 @@ to-regex-range@^5.0.1:
|
|||
dependencies:
|
||||
is-number "^7.0.0"
|
||||
|
||||
typescript@5.4:
|
||||
version "5.4.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372"
|
||||
integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==
|
||||
typescript@5.4.3:
|
||||
version "5.4.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff"
|
||||
integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==
|
||||
|
||||
vscode-grammar-updater@^1.1.0:
|
||||
version "1.1.0"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.88.0",
|
||||
"distro": "0d4298753acb3d9ade428d16cda9ae86015707c2",
|
||||
"distro": "340432a8308f66007779ec2133ee39e6995006cb",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
|
@ -149,7 +149,7 @@
|
|||
"cssnano": "^6.0.3",
|
||||
"debounce": "^1.0.0",
|
||||
"deemon": "^1.8.0",
|
||||
"electron": "28.2.6",
|
||||
"electron": "28.2.8",
|
||||
"eslint": "8.36.0",
|
||||
"eslint-plugin-header": "3.1.1",
|
||||
"eslint-plugin-jsdoc": "^46.5.0",
|
||||
|
|
|
@ -39,17 +39,19 @@ export class Cache<T> {
|
|||
/**
|
||||
* Uses a LRU cache to make a given parametrized function cached.
|
||||
* Caches just the last value.
|
||||
* The key must be JSON serializable.
|
||||
*/
|
||||
export class LRUCachedFunction<TArg, TComputed> {
|
||||
private lastCache: TComputed | undefined = undefined;
|
||||
private lastArgKey: string | undefined = undefined;
|
||||
private lastArgKey: unknown | undefined = undefined;
|
||||
|
||||
constructor(private readonly fn: (arg: TArg) => TComputed) {
|
||||
constructor(
|
||||
private readonly fn: (arg: TArg) => TComputed,
|
||||
private readonly _computeKey: (arg: TArg) => unknown = JSON.stringify,
|
||||
) {
|
||||
}
|
||||
|
||||
public get(arg: TArg): TComputed {
|
||||
const key = JSON.stringify(arg);
|
||||
const key = this._computeKey(arg);
|
||||
if (this.lastArgKey !== key) {
|
||||
this.lastArgKey = key;
|
||||
this.lastCache = this.fn(arg);
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IObservable, ISettableObservable, derived, observableValue } from 'vs/base/common/observable';
|
||||
import { IObservable, ISettableObservable, derived, observableFromEvent, observableValue } from 'vs/base/common/observable';
|
||||
import { Constants } from 'vs/base/common/uint';
|
||||
import { diffEditorDefaultOptions } from 'vs/editor/common/config/diffEditor';
|
||||
import { IDiffEditorBaseOptions, IDiffEditorOptions, IEditorOptions, ValidDiffEditorBaseOptions, clampedFloat, clampedInt, boolean as validateBooleanOption, stringSet as validateStringSetOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
||||
export class DiffEditorOptions {
|
||||
private readonly _options: ISettableObservable<IEditorOptions & Required<IDiffEditorBaseOptions>, { changedOptions: IDiffEditorOptions }>;
|
||||
|
@ -15,8 +16,11 @@ export class DiffEditorOptions {
|
|||
|
||||
private readonly _diffEditorWidth = observableValue<number>(this, 0);
|
||||
|
||||
private readonly _screenReaderMode = observableFromEvent(this._accessibilityService.onDidChangeScreenReaderOptimized, () => this._accessibilityService.isScreenReaderOptimized());
|
||||
|
||||
constructor(
|
||||
options: Readonly<IDiffEditorOptions>,
|
||||
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService,
|
||||
) {
|
||||
const optionsCopy = { ...options, ...validateDiffEditorOptions(options, diffEditorDefaultOptions) };
|
||||
this._options = observableValue(this, optionsCopy);
|
||||
|
@ -28,7 +32,7 @@ export class DiffEditorOptions {
|
|||
|
||||
public readonly renderOverviewRuler = derived(this, reader => this._options.read(reader).renderOverviewRuler);
|
||||
public readonly renderSideBySide = derived(this, reader => this._options.read(reader).renderSideBySide
|
||||
&& !(this._options.read(reader).useInlineViewWhenSpaceIsLimited && this.couldShowInlineViewBecauseOfSize.read(reader))
|
||||
&& !(this._options.read(reader).useInlineViewWhenSpaceIsLimited && this.couldShowInlineViewBecauseOfSize.read(reader) && !this._screenReaderMode.read(reader))
|
||||
);
|
||||
public readonly readOnly = derived(this, reader => this._options.read(reader).readOnly);
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor {
|
|||
this._rootSizeObserver = this._register(new ObservableElementSizeObserver(this.elements.root, options.dimension));
|
||||
this._rootSizeObserver.setAutomaticLayout(options.automaticLayout ?? false);
|
||||
|
||||
this._options = new DiffEditorOptions(options);
|
||||
this._options = this._instantiationService.createInstance(DiffEditorOptions, options);
|
||||
this._register(autorun(reader => {
|
||||
this._options.setWidth(this._rootSizeObserver.width.read(reader));
|
||||
}));
|
||||
|
|
|
@ -118,10 +118,12 @@ export class EditorGutter<T extends IGutterItemInfo = IGutterItemInfo> extends D
|
|||
gutterItem.range.startLineNumber <= this._editor.getModel()!.getLineCount()
|
||||
? this._editor.getTopForLineNumber(gutterItem.range.startLineNumber, true) - scrollTop
|
||||
: this._editor.getBottomForLineNumber(gutterItem.range.startLineNumber - 1, false) - scrollTop;
|
||||
const bottom = this._editor.getBottomForLineNumber(gutterItem.range.endLineNumberExclusive - 1, true) - scrollTop;
|
||||
const bottom = gutterItem.range.isEmpty
|
||||
// Don't trust that `getBottomForLineNumber` for the previous line equals `getTopForLineNumber` for the current one.
|
||||
? top
|
||||
: (this._editor.getBottomForLineNumber(gutterItem.range.endLineNumberExclusive - 1, true) - scrollTop);
|
||||
|
||||
const height = bottom - top;
|
||||
|
||||
view.domNode.style.top = `${top}px`;
|
||||
view.domNode.style.height = `${height}px`;
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ export class DocumentDiffItemViewModel extends Disposable {
|
|||
};
|
||||
}
|
||||
|
||||
const options = new DiffEditorOptions(updateOptions(this.entry.value!.options || {}));
|
||||
const options = this._instantiationService.createInstance(DiffEditorOptions, updateOptions(this.entry.value!.options || {}));
|
||||
if (this.entry.value!.onOptionsDidChange) {
|
||||
this._register(this.entry.value!.onOptionsDidChange(() => {
|
||||
options.updateOptions(updateOptions(this.entry.value!.options || {}));
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
|||
import { derived, derivedWithStore, observableValue, recomputeInitiallyAndOnChange } from 'vs/base/common/observable';
|
||||
import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditor/utils';
|
||||
import { IMultiDiffEditorModel } from 'vs/editor/browser/widget/multiDiffEditor/model';
|
||||
import { IMultiDiffEditorViewState, IMultiDiffResource, MultiDiffEditorWidgetImpl } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
|
||||
import { IMultiDiffEditorViewState, IMultiDiffResourceId, MultiDiffEditorWidgetImpl } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
|
||||
import { MultiDiffEditorViewModel } from './multiDiffEditorViewModel';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import './colors';
|
||||
|
@ -46,7 +46,7 @@ export class MultiDiffEditorWidget extends Disposable {
|
|||
this._register(recomputeInitiallyAndOnChange(this._widgetImpl));
|
||||
}
|
||||
|
||||
public reveal(resource: IMultiDiffResource, options?: RevealOptions): void {
|
||||
public reveal(resource: IMultiDiffResourceId, options?: RevealOptions): void {
|
||||
this._widgetImpl.get().reveal(resource, options);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
|||
import { DiffEditorItemTemplate, TemplateData } from './diffEditorItemTemplate';
|
||||
import { DocumentDiffItemViewModel, MultiDiffEditorViewModel } from './multiDiffEditorViewModel';
|
||||
import { ObjectPool } from './objectPool';
|
||||
import { BugIndicatingError } from 'vs/base/common/errors';
|
||||
|
||||
export class MultiDiffEditorWidgetImpl extends Disposable {
|
||||
private readonly _elements = h('div.monaco-component.multiDiffEditor', [
|
||||
|
@ -191,15 +192,15 @@ export class MultiDiffEditorWidgetImpl extends Disposable {
|
|||
this._scrollableElement.setScrollPosition({ scrollLeft: scrollState.left, scrollTop: scrollState.top });
|
||||
}
|
||||
|
||||
public reveal(resource: IMultiDiffResource, options?: RevealOptions): void {
|
||||
public reveal(resource: IMultiDiffResourceId, options?: RevealOptions): void {
|
||||
const viewItems = this._viewItems.get();
|
||||
let searchCallback: (item: VirtualizedViewItem) => boolean;
|
||||
if ('original' in resource) {
|
||||
searchCallback = (item) => item.viewModel.originalUri?.toString() === resource.original.toString();
|
||||
} else {
|
||||
searchCallback = (item) => item.viewModel.modifiedUri?.toString() === resource.modified.toString();
|
||||
const index = viewItems.findIndex(
|
||||
(item) => item.viewModel.originalUri?.toString() === resource.original?.toString()
|
||||
&& item.viewModel.modifiedUri?.toString() === resource.modified?.toString()
|
||||
);
|
||||
if (index === -1) {
|
||||
throw new BugIndicatingError('Resource not found in diff editor');
|
||||
}
|
||||
const index = viewItems.findIndex(searchCallback);
|
||||
let scrollTop = 0;
|
||||
for (let i = 0; i < index; i++) {
|
||||
scrollTop += viewItems[i].contentHeight.get() + this._spaceBetweenPx;
|
||||
|
@ -323,12 +324,12 @@ export interface IMultiDiffEditorOptions extends ITextEditorOptions {
|
|||
|
||||
export interface IMultiDiffEditorOptionsViewState {
|
||||
revealData?: {
|
||||
resource: IMultiDiffResource;
|
||||
resource: IMultiDiffResourceId;
|
||||
range?: IRange;
|
||||
};
|
||||
}
|
||||
|
||||
export type IMultiDiffResource = { original: URI } | { modified: URI };
|
||||
export type IMultiDiffResourceId = { original: URI | undefined; modified: URI | undefined };
|
||||
|
||||
class VirtualizedViewItem extends Disposable {
|
||||
private readonly _templateRef = this._register(disposableObservableValue<IReference<DiffEditorItemTemplate> | undefined>(this, undefined));
|
||||
|
|
|
@ -2760,7 +2760,7 @@ export type EditorLightbulbOptions = Readonly<Required<IEditorLightbulbOptions>>
|
|||
class EditorLightbulb extends BaseEditorOption<EditorOption.lightbulb, IEditorLightbulbOptions, EditorLightbulbOptions> {
|
||||
|
||||
constructor() {
|
||||
const defaults: EditorLightbulbOptions = { enabled: ShowLightbulbIconMode.OnCode };
|
||||
const defaults: EditorLightbulbOptions = { enabled: ShowLightbulbIconMode.On };
|
||||
super(
|
||||
EditorOption.lightbulb, 'lightbulb', defaults,
|
||||
{
|
||||
|
|
|
@ -11,8 +11,11 @@ import { getLineRangeMapping } from 'vs/editor/common/diff/defaultLinesDiffCompu
|
|||
import { LinesSliceCharSequence } from 'vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence';
|
||||
import { MyersDiffAlgorithm } from 'vs/editor/common/diff/defaultLinesDiffComputer/algorithms/myersDiffAlgorithm';
|
||||
import { DynamicProgrammingDiffing } from 'vs/editor/common/diff/defaultLinesDiffComputer/algorithms/dynamicProgrammingDiffing';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
|
||||
suite('myers', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
test('1', () => {
|
||||
const s1 = new LinesSliceCharSequence(['hello world'], new OffsetRange(0, 1), true);
|
||||
const s2 = new LinesSliceCharSequence(['hallo welt'], new OffsetRange(0, 1), true);
|
||||
|
@ -23,6 +26,8 @@ suite('myers', () => {
|
|||
});
|
||||
|
||||
suite('lineRangeMapping', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
test('Simple', () => {
|
||||
assert.deepStrictEqual(
|
||||
getLineRangeMapping(
|
||||
|
@ -68,6 +73,8 @@ suite('lineRangeMapping', () => {
|
|||
});
|
||||
|
||||
suite('LinesSliceCharSequence', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
const sequence = new LinesSliceCharSequence(
|
||||
[
|
||||
'line1: foo',
|
||||
|
|
|
@ -12,8 +12,11 @@ import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
|
|||
import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer';
|
||||
import { DefaultLinesDiffComputer } from 'vs/editor/common/diff/defaultLinesDiffComputer/defaultLinesDiffComputer';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
|
||||
suite('diffing fixtures', () => {
|
||||
ensureNoDisposablesAreLeakedInTestSuite();
|
||||
|
||||
setup(() => {
|
||||
setUnexpectedErrorHandler(e => {
|
||||
throw e;
|
||||
|
|
|
@ -130,9 +130,9 @@ class ActionItemRenderer<T> implements IListRenderer<IActionListItem<T>, IAction
|
|||
data.container.title = element.label;
|
||||
} else if (actionTitle && previewTitle) {
|
||||
if (this._supportsPreview && element.canPreview) {
|
||||
data.container.title = localize({ key: 'label-preview', comment: ['placeholders are keybindings, e.g "F2 to apply, Shift+F2 to preview"'] }, "{0} to apply, {1} to preview", actionTitle, previewTitle);
|
||||
data.container.title = localize({ key: 'label-preview', comment: ['placeholders are keybindings, e.g "F2 to Apply, Shift+F2 to Preview"'] }, "{0} to Apply, {1} to Preview", actionTitle, previewTitle);
|
||||
} else {
|
||||
data.container.title = localize({ key: 'label', comment: ['placeholder is a keybinding, e.g "F2 to apply"'] }, "{0} to apply", actionTitle);
|
||||
data.container.title = localize({ key: 'label', comment: ['placeholder is a keybinding, e.g "F2 to Apply"'] }, "{0} to Apply", actionTitle);
|
||||
}
|
||||
} else {
|
||||
data.container.title = '';
|
||||
|
|
|
@ -14,6 +14,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
|
|||
import 'vs/css!./link';
|
||||
import { ICustomHover, setupCustomHover } from 'vs/base/browser/ui/hover/updatableHoverWidget';
|
||||
import { getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegateFactory';
|
||||
import { IHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegate';
|
||||
|
||||
export interface ILinkDescriptor {
|
||||
readonly label: string | HTMLElement;
|
||||
|
@ -24,6 +25,7 @@ export interface ILinkDescriptor {
|
|||
|
||||
export interface ILinkOptions {
|
||||
readonly opener?: (href: string) => void;
|
||||
readonly hoverDelegate?: IHoverDelegate;
|
||||
readonly textLinkForeground?: string;
|
||||
}
|
||||
|
||||
|
@ -31,6 +33,7 @@ export class Link extends Disposable {
|
|||
|
||||
private el: HTMLAnchorElement;
|
||||
private hover?: ICustomHover;
|
||||
private hoverDelegate: IHoverDelegate;
|
||||
|
||||
private _enabled: boolean = true;
|
||||
|
||||
|
@ -90,6 +93,7 @@ export class Link extends Disposable {
|
|||
href: _link.href,
|
||||
}, _link.label));
|
||||
|
||||
this.hoverDelegate = options.hoverDelegate ?? getDefaultHoverDelegate('mouse');
|
||||
this.setTooltip(_link.title);
|
||||
|
||||
this.el.setAttribute('role', 'button');
|
||||
|
@ -122,8 +126,10 @@ export class Link extends Disposable {
|
|||
}
|
||||
|
||||
private setTooltip(title: string | undefined): void {
|
||||
if (!this.hover && title) {
|
||||
this.hover = this._register(setupCustomHover(getDefaultHoverDelegate('mouse'), this.el, title));
|
||||
if (this.hoverDelegate.showNativeHover) {
|
||||
this.el.title = title ?? '';
|
||||
} else if (!this.hover && title) {
|
||||
this.hover = this._register(setupCustomHover(this.hoverDelegate, this.el, title));
|
||||
} else if (this.hover) {
|
||||
this.hover.update(title);
|
||||
}
|
||||
|
|
|
@ -707,6 +707,10 @@ export class QuickInputTree extends Disposable {
|
|||
// Elements that apply to the current set of elements
|
||||
private _elementDisposable = this._register(new DisposableStore());
|
||||
private _lastHover: IHoverWidget | undefined;
|
||||
// This is used to prevent setting the checked state of a single element from firing the checked events
|
||||
// so that we can batch them together. This can probably be improved by handling events differently,
|
||||
// but this works for now. An observable would probably be ideal for this.
|
||||
private _shouldFireCheckedEvents = true;
|
||||
|
||||
constructor(
|
||||
private parent: HTMLElement,
|
||||
|
@ -1056,12 +1060,18 @@ export class QuickInputTree extends Disposable {
|
|||
}
|
||||
|
||||
setAllVisibleChecked(checked: boolean) {
|
||||
this._itemElements.forEach(element => {
|
||||
if (!element.hidden && !element.checkboxDisabled) {
|
||||
element.checked = checked;
|
||||
}
|
||||
});
|
||||
this._fireCheckedEvents();
|
||||
try {
|
||||
this._shouldFireCheckedEvents = false;
|
||||
this._itemElements.forEach(element => {
|
||||
if (!element.hidden && !element.checkboxDisabled) {
|
||||
// Would fire an event if we didn't have the flag set
|
||||
element.checked = checked;
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
this._shouldFireCheckedEvents = true;
|
||||
this._fireCheckedEvents();
|
||||
}
|
||||
}
|
||||
|
||||
setElements(inputElements: QuickPickItem[]): void {
|
||||
|
@ -1185,14 +1195,20 @@ export class QuickInputTree extends Disposable {
|
|||
}
|
||||
|
||||
setCheckedElements(items: IQuickPickItem[]) {
|
||||
const checked = new Set();
|
||||
for (const item of items) {
|
||||
checked.add(item);
|
||||
try {
|
||||
this._shouldFireCheckedEvents = false;
|
||||
const checked = new Set();
|
||||
for (const item of items) {
|
||||
checked.add(item);
|
||||
}
|
||||
for (const element of this._itemElements) {
|
||||
// Would fire an event if we didn't have the flag set
|
||||
element.checked = checked.has(element.item);
|
||||
}
|
||||
} finally {
|
||||
this._shouldFireCheckedEvents = true;
|
||||
this._fireCheckedEvents();
|
||||
}
|
||||
for (const element of this._itemElements) {
|
||||
element.checked = checked.has(element.item);
|
||||
}
|
||||
this._fireCheckedEvents();
|
||||
}
|
||||
|
||||
focus(what: QuickInputListFocus): void {
|
||||
|
@ -1276,9 +1292,9 @@ export class QuickInputTree extends Disposable {
|
|||
|
||||
if (e.element instanceof QuickPickSeparatorElement) {
|
||||
foundSeparatorAsItem = true;
|
||||
// If the separator is visible, then we should just focus it.
|
||||
// If the separator is visible, then we should just reveal its first child so it's not as jarring.
|
||||
if (this._separatorRenderer.isSeparatorVisible(e.element)) {
|
||||
this._tree.reveal(e.element);
|
||||
this._tree.reveal(e.element.children[0]);
|
||||
} else {
|
||||
// If the separator is not visible, then we should
|
||||
// push it up to the top of the list.
|
||||
|
@ -1498,14 +1514,20 @@ export class QuickInputTree extends Disposable {
|
|||
}
|
||||
|
||||
toggleCheckbox() {
|
||||
const elements = this._tree.getFocus().filter((e): e is QuickPickItemElement => e instanceof QuickPickItemElement);
|
||||
const allChecked = this._allVisibleChecked(elements);
|
||||
for (const element of elements) {
|
||||
if (!element.checkboxDisabled) {
|
||||
element.checked = !allChecked;
|
||||
try {
|
||||
this._shouldFireCheckedEvents = false;
|
||||
const elements = this._tree.getFocus().filter((e): e is QuickPickItemElement => e instanceof QuickPickItemElement);
|
||||
const allChecked = this._allVisibleChecked(elements);
|
||||
for (const element of elements) {
|
||||
if (!element.checkboxDisabled) {
|
||||
// Would fire an event if we didn't have the flag set
|
||||
element.checked = !allChecked;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this._shouldFireCheckedEvents = true;
|
||||
this._fireCheckedEvents();
|
||||
}
|
||||
this._fireCheckedEvents();
|
||||
}
|
||||
|
||||
display(display: boolean) {
|
||||
|
@ -1565,6 +1587,9 @@ export class QuickInputTree extends Disposable {
|
|||
}
|
||||
|
||||
private _fireCheckedEvents() {
|
||||
if (!this._shouldFireCheckedEvents) {
|
||||
return;
|
||||
}
|
||||
this._onChangedAllVisibleChecked.fire(this.getAllVisibleChecked());
|
||||
this._onChangedCheckedCount.fire(this.getCheckedCount());
|
||||
this._onChangedCheckedElements.fire(this.getCheckedElements());
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
|
|||
|
||||
// Import the effects we need
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { registerColor, darken, lighten, ifDefinedThenElse, transparent } from 'vs/platform/theme/common/colorUtils';
|
||||
import { registerColor, darken, lighten, transparent, ifDefinedThenElse } from 'vs/platform/theme/common/colorUtils';
|
||||
|
||||
// Import the colors we need
|
||||
import { foreground, contrastBorder, activeContrastBorder, focusBorder, iconForeground } from 'vs/platform/theme/common/colors/baseColors';
|
||||
|
|
|
@ -267,7 +267,8 @@ export abstract class AbstractTextEditor<T extends IEditorViewState> extends Abs
|
|||
}
|
||||
|
||||
return {
|
||||
scrollTop: editor.getScrollTop(),
|
||||
// The top position can vary depending on the view zones (find widget for example)
|
||||
scrollTop: editor.getScrollTop() - editor.getTopForLineNumber(1),
|
||||
scrollLeft: editor.getScrollLeft(),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -109,6 +109,8 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
|
|||
{
|
||||
type: 'string',
|
||||
markdownDescription: localize('workbench.editor.label.template', "The template which should be rendered when the pattern mtches. May include the variables ${dirname}, ${filename} and ${extname}."),
|
||||
minLength: 1,
|
||||
pattern: '.*[a-zA-Z0-9].*'
|
||||
},
|
||||
'default': {}
|
||||
},
|
||||
|
|
|
@ -37,8 +37,9 @@ import { ButtonBar } from 'vs/base/browser/ui/button/button';
|
|||
import { defaultButtonStyles } from 'vs/platform/theme/browser/defaultStyles';
|
||||
import { Mutable } from 'vs/base/common/types';
|
||||
import { IResourceDiffEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IMultiDiffEditorOptions } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
|
||||
import { IMultiDiffEditorOptions, IMultiDiffResourceId } from 'vs/editor/browser/widget/multiDiffEditor/multiDiffEditorWidgetImpl';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { CachedFunction, LRUCachedFunction } from 'vs/base/common/cache';
|
||||
|
||||
const enum State {
|
||||
Data = 'data',
|
||||
|
@ -70,8 +71,6 @@ export class BulkEditPane extends ViewPane {
|
|||
private _currentResolve?: (edit?: ResourceEdit[]) => void;
|
||||
private _currentInput?: BulkFileOperations;
|
||||
private _currentProvider?: BulkEditPreviewProvider;
|
||||
private _fileOperations?: BulkFileOperation[];
|
||||
private _resources?: IResourceDiffEditorInput[];
|
||||
|
||||
constructor(
|
||||
options: IViewletViewOptions,
|
||||
|
@ -345,12 +344,13 @@ export class BulkEditPane extends ViewPane {
|
|||
return;
|
||||
}
|
||||
|
||||
const resources = await this._resolveResources(fileOperations);
|
||||
const result = await this._computeResourceDiffEditorInputs.get(fileOperations);
|
||||
const resourceId = await result.getResourceDiffEditorInputIdOfOperation(fileElement.edit);
|
||||
const options: Mutable<IMultiDiffEditorOptions> = {
|
||||
...e.editorOptions,
|
||||
viewState: {
|
||||
revealData: {
|
||||
resource: { original: fileElement.edit.uri },
|
||||
resource: resourceId,
|
||||
range: selection,
|
||||
}
|
||||
}
|
||||
|
@ -359,49 +359,56 @@ export class BulkEditPane extends ViewPane {
|
|||
const label = 'Refactor Preview';
|
||||
this._editorService.openEditor({
|
||||
multiDiffSource,
|
||||
resources,
|
||||
label,
|
||||
options,
|
||||
isTransient: true,
|
||||
description: label
|
||||
description: label,
|
||||
resources: result.resources
|
||||
}, e.sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
|
||||
}
|
||||
|
||||
private async _resolveResources(fileOperations: BulkFileOperation[]): Promise<IResourceDiffEditorInput[]> {
|
||||
if (this._fileOperations === fileOperations && this._resources) {
|
||||
return this._resources;
|
||||
}
|
||||
const sortedFileOperations = fileOperations.sort(compareBulkFileOperations);
|
||||
const resources: IResourceDiffEditorInput[] = [];
|
||||
for (const operation of sortedFileOperations) {
|
||||
const operationUri = operation.uri;
|
||||
const previewUri = this._currentProvider!.asPreviewUri(operationUri);
|
||||
// delete -> show single editor
|
||||
if (operation.type & BulkFileOperationType.Delete) {
|
||||
resources.push({
|
||||
original: { resource: undefined },
|
||||
modified: { resource: URI.revive(previewUri) }
|
||||
});
|
||||
private readonly _computeResourceDiffEditorInputs = new LRUCachedFunction(async (fileOperations: BulkFileOperation[]) => {
|
||||
const computeDiffEditorInput = new CachedFunction<BulkFileOperation, Promise<IResourceDiffEditorInput>>(async (fileOperation) => {
|
||||
const fileOperationUri = fileOperation.uri;
|
||||
const previewUri = this._currentProvider!.asPreviewUri(fileOperationUri);
|
||||
// delete
|
||||
if (fileOperation.type & BulkFileOperationType.Delete) {
|
||||
return {
|
||||
original: { resource: URI.revive(previewUri) },
|
||||
modified: { resource: undefined }
|
||||
};
|
||||
|
||||
} else {
|
||||
// rename, create, edits -> show diff editr
|
||||
}
|
||||
// rename, create, edits
|
||||
else {
|
||||
let leftResource: URI | undefined;
|
||||
try {
|
||||
(await this._textModelService.createModelReference(operationUri)).dispose();
|
||||
leftResource = operationUri;
|
||||
(await this._textModelService.createModelReference(fileOperationUri)).dispose();
|
||||
leftResource = fileOperationUri;
|
||||
} catch {
|
||||
leftResource = BulkEditPreviewProvider.emptyPreview;
|
||||
}
|
||||
resources.push({
|
||||
return {
|
||||
original: { resource: URI.revive(leftResource) },
|
||||
modified: { resource: URI.revive(previewUri) }
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const sortedFileOperations = fileOperations.slice().sort(compareBulkFileOperations);
|
||||
const resources: IResourceDiffEditorInput[] = [];
|
||||
for (const operation of sortedFileOperations) {
|
||||
resources.push(await computeDiffEditorInput.get(operation));
|
||||
}
|
||||
this._fileOperations = fileOperations;
|
||||
this._resources = resources;
|
||||
return resources;
|
||||
}
|
||||
const getResourceDiffEditorInputIdOfOperation = async (operation: BulkFileOperation): Promise<IMultiDiffResourceId> => {
|
||||
const resource = await computeDiffEditorInput.get(operation);
|
||||
return { original: resource.original.resource, modified: resource.modified.resource };
|
||||
};
|
||||
return {
|
||||
resources,
|
||||
getResourceDiffEditorInputIdOfOperation
|
||||
};
|
||||
}, key => key);
|
||||
|
||||
private _onContextMenu(e: ITreeContextMenuEvent<any>): void {
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ export function registerChatCodeBlockActions() {
|
|||
when: ContextKeyExpr.or(ContextKeyExpr.and(CONTEXT_IN_CHAT_SESSION, CONTEXT_IN_CHAT_INPUT.negate()), accessibleViewInCodeBlock),
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Enter,
|
||||
mac: { primary: KeyMod.WinCtrl | KeyCode.Enter },
|
||||
weight: KeybindingWeight.WorkbenchContrib
|
||||
weight: KeybindingWeight.ExternalExtension + 1
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ export interface IChatWidgetViewOptions {
|
|||
inputSideToolbar?: MenuId;
|
||||
telemetrySource?: string;
|
||||
};
|
||||
defaultElementHeight?: number;
|
||||
editorOverflowWidgetsDomNode?: HTMLElement;
|
||||
}
|
||||
|
||||
|
@ -115,6 +116,7 @@ export interface IChatWidget {
|
|||
readonly onDidChangeViewModel: Event<void>;
|
||||
readonly onDidAcceptInput: Event<void>;
|
||||
readonly onDidSubmitAgent: Event<{ agent: IChatAgentData; slashCommand?: IChatAgentCommand }>;
|
||||
readonly onDidChangeParsedInput: Event<void>;
|
||||
readonly location: ChatAgentLocation;
|
||||
readonly viewContext: IChatWidgetViewContext;
|
||||
readonly viewModel: IChatViewModel | undefined;
|
||||
|
|
|
@ -452,10 +452,10 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
|
|||
private _layout(height: number, width: number, allowRecurse = true): void {
|
||||
const followupsHeight = this.followupsContainer.offsetHeight;
|
||||
|
||||
const inputPartBorder = 1;
|
||||
const inputPartBorder = 0;
|
||||
const inputPartHorizontalPadding = this.options.renderStyle === 'compact' ? 8 : 40;
|
||||
const inputPartVerticalPadding = this.options.renderStyle === 'compact' ? 12 : 24;
|
||||
const inputEditorHeight = Math.min(this._inputEditor.getContentHeight(), height - followupsHeight - inputPartHorizontalPadding - inputPartBorder, INPUT_EDITOR_MAX_HEIGHT);
|
||||
const inputEditorHeight = Math.min(this._inputEditor.getContentHeight(), height - followupsHeight - inputPartVerticalPadding - inputPartBorder, INPUT_EDITOR_MAX_HEIGHT);
|
||||
const implicitContextHeight = this.implicitContextContainer.offsetHeight;
|
||||
|
||||
const inputEditorBorder = 2;
|
||||
|
|
|
@ -25,7 +25,7 @@ import { ResourceMap } from 'vs/base/common/map';
|
|||
import { FileAccess, Schemas, matchesSomeScheme } from 'vs/base/common/network';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { basenameOrAuthority, dirname } from 'vs/base/common/resources';
|
||||
import { basenameOrAuthority } from 'vs/base/common/resources';
|
||||
import { equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
import { ThemeIcon } from 'vs/base/common/themables';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
@ -33,7 +33,7 @@ import { IMarkdownRenderResult, MarkdownRenderer } from 'vs/editor/browser/widge
|
|||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IMenuEntryActionViewItemOptions, MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IMenuEntryActionViewItemOptions, MenuEntryActionViewItem, createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar';
|
||||
import { MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
|
@ -42,7 +42,6 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
|||
import { FileKind, FileType } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { WorkbenchCompressibleAsyncDataTree, WorkbenchList } from 'vs/platform/list/browser/listService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
|
@ -269,12 +268,14 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
|||
menuOptions: {
|
||||
shouldForwardArgs: true
|
||||
},
|
||||
toolbarOptions: {
|
||||
shouldInlineSubmenu: submenu => submenu.actions.length <= 1
|
||||
},
|
||||
actionViewItemProvider: (action: IAction, options: IActionViewItemOptions) => {
|
||||
if (action instanceof MenuItemAction && (action.item.id === 'workbench.action.chat.voteDown' || action.item.id === 'workbench.action.chat.voteUp')) {
|
||||
return scopedInstantiationService.createInstance(ChatVoteButton, action, options as IMenuEntryActionViewItemOptions);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return createActionViewItem(scopedInstantiationService, action, options);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -495,7 +496,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
|||
}
|
||||
}
|
||||
if (madeChanges) {
|
||||
dom.append(templateData.value, $('.interactive-edits-summary', undefined, localize('editsSummary', "Made text edits")));
|
||||
dom.append(templateData.value, $('.interactive-edits-summary', undefined, localize('editsSummary', "Made changes.")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,6 +514,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
|||
private renderWelcomeMessage(element: IChatWelcomeMessageViewModel, templateData: IChatListItemTemplate) {
|
||||
dom.clearNode(templateData.value);
|
||||
dom.clearNode(templateData.referencesListContainer);
|
||||
dom.hide(templateData.referencesListContainer);
|
||||
|
||||
for (const item of element.content) {
|
||||
if (Array.isArray(item)) {
|
||||
|
@ -814,7 +816,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
|||
editorOptions: {
|
||||
...e.editorOptions,
|
||||
...{
|
||||
selection: 'range' in e.element.reference ? e.element.reference.range : undefined
|
||||
selection: uriOrLocation && 'range' in uriOrLocation ? uriOrLocation.range : undefined
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -916,17 +918,13 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
|||
}
|
||||
|
||||
const sessionId = isResponseVM(element) || isRequestVM(element) ? element.sessionId : '';
|
||||
const modelEntry = this.codeBlockModelCollection.get(sessionId, element, index);
|
||||
if (!modelEntry) {
|
||||
console.error('Trying to render code block without model', element.id, index);
|
||||
return $('div');
|
||||
}
|
||||
const modelEntry = this.codeBlockModelCollection.getOrCreate(sessionId, element, index);
|
||||
vulns = modelEntry.vulns;
|
||||
textModel = modelEntry.model;
|
||||
}
|
||||
|
||||
const hideToolbar = isResponseVM(element) && element.errorDetails?.responseIsFiltered;
|
||||
const ref = this.renderCodeBlock({ languageId, textModel, codeBlockIndex: index, element, range, hideToolbar, parentContextKeyService: templateData.contextKeyService, vulns });
|
||||
const ref = this.renderCodeBlock({ languageId, textModel, codeBlockIndex: index, element, range, hideToolbar, parentContextKeyService: templateData.contextKeyService, vulns }, text);
|
||||
|
||||
// Attach this after updating text/layout of the editor, so it should only be fired when the size updates later (horizontal scrollbar, wrapping)
|
||||
// not during a renderElement OR a progressive render (when we will be firing this event anyway at the end of the render)
|
||||
|
@ -973,9 +971,13 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
|||
};
|
||||
}
|
||||
|
||||
private renderCodeBlock(data: ICodeBlockData): IDisposableReference<CodeBlockPart> {
|
||||
private renderCodeBlock(data: ICodeBlockData, text: string): IDisposableReference<CodeBlockPart> {
|
||||
const ref = this._editorPool.get();
|
||||
const editorInfo = ref.object;
|
||||
if (isResponseVM(data.element)) {
|
||||
this.codeBlockModelCollection.update(data.element.sessionId, data.element, data.codeBlockIndex, { text, languageId: data.languageId });
|
||||
}
|
||||
|
||||
editorInfo.render(data, this._currentLayoutWidth, this.rendererOptions.editableCodeBlock);
|
||||
|
||||
return ref;
|
||||
|
@ -1010,6 +1012,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
|||
|
||||
export class ChatListDelegate implements IListVirtualDelegate<ChatTreeItem> {
|
||||
constructor(
|
||||
private readonly defaultElementHeight: number,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) { }
|
||||
|
||||
|
@ -1023,7 +1026,7 @@ export class ChatListDelegate implements IListVirtualDelegate<ChatTreeItem> {
|
|||
|
||||
getHeight(element: ChatTreeItem): number {
|
||||
const kind = isRequestVM(element) ? 'request' : 'response';
|
||||
const height = ('currentRenderedHeight' in element ? element.currentRenderedHeight : undefined) ?? 200;
|
||||
const height = ('currentRenderedHeight' in element ? element.currentRenderedHeight : undefined) ?? this.defaultElementHeight;
|
||||
this._traceLayout('getHeight', `${kind}, height=${height}`);
|
||||
return height;
|
||||
}
|
||||
|
@ -1223,7 +1226,6 @@ class ContentReferencesListRenderer implements IListRenderer<IChatContentReferen
|
|||
|
||||
constructor(
|
||||
private labels: ResourceLabels,
|
||||
@ILabelService private readonly labelService: ILabelService,
|
||||
@IChatVariablesService private readonly chatVariablesService: IChatVariablesService,
|
||||
) { }
|
||||
|
||||
|
@ -1237,19 +1239,17 @@ class ContentReferencesListRenderer implements IListRenderer<IChatContentReferen
|
|||
const reference = data.reference;
|
||||
templateData.label.element.style.display = 'flex';
|
||||
if ('variableName' in reference) {
|
||||
const variable = this.chatVariablesService.getVariable(reference.variableName);
|
||||
if (reference.value) {
|
||||
const uri = URI.isUri(reference.value) ? reference.value : reference.value.uri;
|
||||
const title = this.labelService.getUriLabel(dirname(uri), { relative: true });
|
||||
templateData.label.setResource(
|
||||
{
|
||||
resource: uri,
|
||||
name: basenameOrAuthority(uri),
|
||||
description: `#${reference.variableName}`,
|
||||
range: 'range' in reference.value ? reference.value.range : undefined
|
||||
},
|
||||
{ title, descriptionTitle: variable?.description });
|
||||
});
|
||||
} else {
|
||||
const variable = this.chatVariablesService.getVariable(reference.variableName);
|
||||
templateData.label.setLabel(`#${reference.variableName}`, undefined, { title: variable?.description });
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -32,7 +32,7 @@ import { ChatListDelegate, ChatListItemRenderer, IChatListItemRendererOptions, I
|
|||
import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions';
|
||||
import { ChatViewPane } from 'vs/workbench/contrib/chat/browser/chatViewPane';
|
||||
import { ChatAgentLocation, IChatAgentCommand, IChatAgentData, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { CONTEXT_CHAT_INPUT_HAS_AGENT, CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_SESSION, CONTEXT_RESPONSE_FILTERED } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { CONTEXT_CHAT_INPUT_HAS_AGENT, CONTEXT_CHAT_LOCATION, CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_SESSION, CONTEXT_RESPONSE_FILTERED } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService';
|
||||
import { ChatModelInitState, IChatModel } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { ChatRequestAgentPart, IParsedChatRequest, chatAgentLeader, chatSubcommandLeader, extractAgentAndCommand } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
|
@ -97,9 +97,15 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
|||
private _onDidAcceptInput = this._register(new Emitter<void>());
|
||||
readonly onDidAcceptInput = this._onDidAcceptInput.event;
|
||||
|
||||
private _onDidChangeParsedInput = this._register(new Emitter<void>());
|
||||
readonly onDidChangeParsedInput = this._onDidChangeParsedInput.event;
|
||||
|
||||
private _onDidChangeHeight = this._register(new Emitter<number>());
|
||||
readonly onDidChangeHeight = this._onDidChangeHeight.event;
|
||||
|
||||
private readonly _onDidChangeContentHeight = new Emitter<void>();
|
||||
readonly onDidChangeContentHeight: Event<void> = this._onDidChangeContentHeight.event;
|
||||
|
||||
private contribs: IChatWidgetContrib[] = [];
|
||||
|
||||
private tree!: WorkbenchObjectTree<ChatTreeItem>;
|
||||
|
@ -175,6 +181,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
|||
) {
|
||||
super();
|
||||
CONTEXT_IN_CHAT_SESSION.bindTo(contextKeyService).set(true);
|
||||
CONTEXT_CHAT_LOCATION.bindTo(contextKeyService).set(location);
|
||||
this.agentInInput = CONTEXT_CHAT_INPUT_HAS_AGENT.bindTo(contextKeyService);
|
||||
this.requestInProgress = CONTEXT_CHAT_REQUEST_IN_PROGRESS.bindTo(contextKeyService);
|
||||
|
||||
|
@ -221,7 +228,9 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
|||
|
||||
private _lastSelectedAgent: IChatAgentData | undefined;
|
||||
set lastSelectedAgent(agent: IChatAgentData | undefined) {
|
||||
this.parsedChatRequest = undefined;
|
||||
this._lastSelectedAgent = agent;
|
||||
this._onDidChangeParsedInput.fire();
|
||||
}
|
||||
|
||||
get lastSelectedAgent(): IChatAgentData | undefined {
|
||||
|
@ -396,7 +405,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
|||
|
||||
private createList(listContainer: HTMLElement, options: IChatListItemRendererOptions): void {
|
||||
const scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection([IContextKeyService, this.contextKeyService]));
|
||||
const delegate = scopedInstantiationService.createInstance(ChatListDelegate);
|
||||
const delegate = scopedInstantiationService.createInstance(ChatListDelegate, this.viewOptions.defaultElementHeight ?? 200);
|
||||
const rendererDelegate: IChatRendererDelegate = {
|
||||
getListLength: () => this.tree.getNode(null).visibleChildrenCount,
|
||||
onDidScroll: this.onDidScroll,
|
||||
|
@ -499,6 +508,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
|||
}
|
||||
|
||||
this.previousTreeScrollHeight = this.tree.scrollHeight;
|
||||
this._onDidChangeContentHeight.fire();
|
||||
}
|
||||
|
||||
private createInput(container: HTMLElement, options?: { renderFollowups: boolean; renderStyle?: 'default' | 'compact' }): void {
|
||||
|
@ -557,7 +567,12 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
|||
},
|
||||
});
|
||||
}));
|
||||
this._register(this.inputPart.onDidChangeHeight(() => this.bodyDimension && this.layout(this.bodyDimension.height, this.bodyDimension.width)));
|
||||
this._register(this.inputPart.onDidChangeHeight(() => {
|
||||
if (this.bodyDimension) {
|
||||
this.layout(this.bodyDimension.height, this.bodyDimension.width);
|
||||
}
|
||||
this._onDidChangeContentHeight.fire();
|
||||
}));
|
||||
this._register(this.inputEditor.onDidChangeModelContent(() => this.updateImplicitContextKinds()));
|
||||
this._register(this.chatAgentService.onDidChangeAgents(() => {
|
||||
if (this.viewModel) {
|
||||
|
|
|
@ -44,6 +44,7 @@ import { MenuPreventer } from 'vs/workbench/contrib/codeEditor/browser/menuPreve
|
|||
import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';
|
||||
import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions';
|
||||
import { IMarkdownVulnerability } from '../common/annotations';
|
||||
import { TabFocus } from 'vs/editor/browser/config/tabFocus';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
|
@ -334,6 +335,10 @@ export class CodeBlockPart extends Disposable {
|
|||
await this.updateEditor(data);
|
||||
|
||||
this.layout(width);
|
||||
if (editable) {
|
||||
this._register(this.editor.onDidFocusEditorWidget(() => TabFocus.setTabFocusMode(true)));
|
||||
this._register(this.editor.onDidBlurEditorWidget(() => TabFocus.setTabFocusMode(false)));
|
||||
}
|
||||
this.editor.updateOptions({ ariaLabel: localize('chat.codeBlockLabel', "Code block {0}", data.codeBlockIndex + 1), readOnly: !editable });
|
||||
|
||||
if (data.hideToolbar) {
|
||||
|
|
|
@ -66,6 +66,7 @@ class InputEditorDecorations extends Disposable {
|
|||
|
||||
this.updateInputEditorDecorations();
|
||||
this._register(this.widget.inputEditor.onDidChangeModelContent(() => this.updateInputEditorDecorations()));
|
||||
this._register(this.widget.onDidChangeParsedInput(() => this.updateInputEditorDecorations()));
|
||||
this._register(this.widget.onDidChangeViewModel(() => {
|
||||
this.registerViewModelListeners();
|
||||
this.previouslyUsedAgents.clear();
|
||||
|
@ -211,7 +212,9 @@ class InputEditorDecorations extends Disposable {
|
|||
|
||||
const textDecorations: IDecorationOptions[] | undefined = [];
|
||||
if (agentPart) {
|
||||
const agentHover = `(${agentPart.agent.name}) ${agentPart.agent.description}`;
|
||||
const isDupe = !!this.chatAgentService.getAgents().find(other => other.name === agentPart.agent.name && other.id !== agentPart.agent.id);
|
||||
const id = isDupe ? `(${agentPart.agent.id}) ` : '';
|
||||
const agentHover = `${id}${agentPart.agent.description}`;
|
||||
textDecorations.push({ range: agentPart.editorRange, hoverMessage: new MarkdownString(agentHover) });
|
||||
if (agentSubcommandPart) {
|
||||
textDecorations.push({ range: agentSubcommandPart.editorRange, hoverMessage: new MarkdownString(agentSubcommandPart.command.description) });
|
||||
|
@ -456,7 +459,8 @@ class AgentCompletions extends Disposable {
|
|||
insertText: `${agentLabel} `,
|
||||
range: new Range(1, 1, 1, 1),
|
||||
kind: CompletionItemKind.Text,
|
||||
sortText: `${chatSubcommandLeader}${agent.name}`,
|
||||
sortText: `${chatSubcommandLeader}${agent.id}`,
|
||||
command: { id: AssignSelectedAgentAction.ID, title: AssignSelectedAgentAction.ID, arguments: [{ agent, widget } satisfies AssignSelectedAgentActionArgs] },
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -473,7 +477,8 @@ class AgentCompletions extends Disposable {
|
|||
detail: `(${agentLabel}) ${c.description ?? ''}`,
|
||||
range: new Range(1, 1, 1, 1),
|
||||
kind: CompletionItemKind.Text, // The icons are disabled here anyway
|
||||
sortText: `${chatSubcommandLeader}${agent.name}${c.name}`,
|
||||
sortText: `${chatSubcommandLeader}${agent.id}${c.name}`,
|
||||
command: { id: AssignSelectedAgentAction.ID, title: AssignSelectedAgentAction.ID, arguments: [{ agent, widget } satisfies AssignSelectedAgentActionArgs] },
|
||||
} satisfies CompletionItem;
|
||||
})))
|
||||
};
|
||||
|
|
|
@ -166,6 +166,11 @@
|
|||
background-color: var(--vscode-chat-list-background);
|
||||
}
|
||||
|
||||
.interactive-item-container.interactive-request .header .monaco-toolbar {
|
||||
/* Take the partially-transparent background color override for request rows */
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.interactive-item-container .header .monaco-toolbar .checked.action-label,
|
||||
.interactive-item-container .header .monaco-toolbar .checked.action-label:hover {
|
||||
color: var(--vscode-inputOption-activeForeground) !important;
|
||||
|
@ -348,6 +353,10 @@
|
|||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.interactive-session .interactive-input-part.compact .interactive-input-and-execute-toolbar {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.interactive-session .interactive-input-and-side-toolbar {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import { localize } from 'vs/nls';
|
||||
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ChatAgentLocation } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
|
||||
export const CONTEXT_RESPONSE_VOTE = new RawContextKey<string>('chatSessionResponseVote', '', { type: 'string', description: localize('interactiveSessionResponseVote', "When the response has been voted up, is set to 'up'. When voted down, is set to 'down'. Otherwise an empty string.") });
|
||||
export const CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND = new RawContextKey<boolean>('chatSessionResponseDetectedAgentOrCommand', false, { type: 'boolean', description: localize('chatSessionResponseDetectedAgentOrCommand', "When the agent or command was automatically detected") });
|
||||
|
@ -23,3 +24,4 @@ export const CONTEXT_IN_CHAT_SESSION = new RawContextKey<boolean>('inChat', fals
|
|||
export const CONTEXT_PROVIDER_EXISTS = new RawContextKey<boolean>('hasChatProvider', false, { type: 'boolean', description: localize('hasChatProvider', "True when some chat provider has been registered.") });
|
||||
export const CONTEXT_CHAT_INPUT_CURSOR_AT_TOP = new RawContextKey<boolean>('chatCursorAtTop', false);
|
||||
export const CONTEXT_CHAT_INPUT_HAS_AGENT = new RawContextKey<boolean>('chatInputHasAgent', false);
|
||||
export const CONTEXT_CHAT_LOCATION = new RawContextKey<ChatAgentLocation>('chatLocation', undefined);
|
||||
|
|
|
@ -241,7 +241,9 @@ export class ChatViewModel extends Disposable implements IChatViewModel {
|
|||
private onAddResponse(responseModel: IChatResponseModel) {
|
||||
const response = this.instantiationService.createInstance(ChatResponseViewModel, responseModel);
|
||||
this._register(response.onDidChange(() => {
|
||||
this.updateCodeBlockTextModels(response);
|
||||
if (response.isComplete) {
|
||||
this.updateCodeBlockTextModels(response);
|
||||
}
|
||||
return this._onDidChange.fire(null);
|
||||
}));
|
||||
this._items.push(response);
|
||||
|
|
|
@ -53,6 +53,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
|||
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { TerminalChatController, TerminalChatContextKeys } from 'vs/workbench/contrib/terminal/browser/terminalContribExports';
|
||||
import { NOTEBOOK_EDITOR_FOCUSED } from 'vs/workbench/contrib/notebook/common/notebookContextKeys';
|
||||
|
||||
const CONTEXT_VOICE_CHAT_GETTING_READY = new RawContextKey<boolean>('voiceChatGettingReady', false, { type: 'boolean', description: localize('voiceChatGettingReady', "True when getting ready for receiving voice input from the microphone for voice chat.") });
|
||||
const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey<boolean>('voiceChatInProgress', false, { type: 'boolean', description: localize('voiceChatInProgress', "True when voice recording from microphone is in progress for voice chat.") });
|
||||
|
@ -461,22 +462,18 @@ async function startVoiceChatWithHoldMode(id: string, accessor: ServicesAccessor
|
|||
|
||||
const holdMode = keybindingService.enableKeybindingHoldMode(id);
|
||||
|
||||
let session: IVoiceChatSession | undefined = undefined;
|
||||
const controller = await VoiceChatSessionControllerFactory.create(accessor, target);
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
const session = await VoiceChatSessions.getInstance(instantiationService).start(controller, context);
|
||||
|
||||
let acceptVoice = false;
|
||||
const handle = disposableTimeout(() => {
|
||||
acceptVoice = true;
|
||||
session?.setTimeoutDisabled(true); // disable accept on timeout when hold mode runs for VOICE_KEY_HOLD_THRESHOLD
|
||||
}, VOICE_KEY_HOLD_THRESHOLD);
|
||||
|
||||
const controller = await VoiceChatSessionControllerFactory.create(accessor, target);
|
||||
if (!controller) {
|
||||
handle.dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
session = await VoiceChatSessions.getInstance(instantiationService).start(controller, context);
|
||||
|
||||
await holdMode;
|
||||
handle.dispose();
|
||||
|
||||
|
@ -524,7 +521,8 @@ export class HoldToVoiceChatInChatViewAction extends Action2 {
|
|||
when: ContextKeyExpr.and(
|
||||
CanVoiceChat,
|
||||
FocusInChatInput.negate(), // when already in chat input, disable this action and prefer to start voice chat directly
|
||||
EditorContextKeys.focus.negate() // do not steal the inline-chat keybinding
|
||||
EditorContextKeys.focus.negate(), // do not steal the inline-chat keybinding
|
||||
NOTEBOOK_EDITOR_FOCUSED.negate() // do not steal the notebook keybinding
|
||||
),
|
||||
primary: KeyMod.CtrlCmd | KeyCode.KeyI
|
||||
}
|
||||
|
@ -607,6 +605,7 @@ export class StartVoiceChatAction extends Action2 {
|
|||
when: ContextKeyExpr.and(
|
||||
FocusInChatInput, // scope this action to chat input fields only
|
||||
EditorContextKeys.focus.negate(), // do not steal the inline-chat keybinding
|
||||
NOTEBOOK_EDITOR_FOCUSED.negate(), // do not steal the notebook keybinding
|
||||
CONTEXT_VOICE_CHAT_IN_VIEW_IN_PROGRESS.negate(),
|
||||
CONTEXT_QUICK_VOICE_CHAT_IN_PROGRESS.negate(),
|
||||
CONTEXT_VOICE_CHAT_IN_EDITOR_IN_PROGRESS.negate(),
|
||||
|
|
|
@ -249,7 +249,7 @@ export class EditorDictation extends Disposable implements IEditorContribution {
|
|||
const cts = new CancellationTokenSource();
|
||||
disposables.add(toDisposable(() => cts.dispose(true)));
|
||||
|
||||
const session = await this.speechService.createSpeechToTextSession(cts.token);
|
||||
const session = await this.speechService.createSpeechToTextSession(cts.token, 'editor');
|
||||
disposables.add(session.onDidChange(e => {
|
||||
if (cts.token.isCancellationRequested) {
|
||||
return;
|
||||
|
|
|
@ -11,7 +11,7 @@ import { EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/diffEditor/em
|
|||
import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/codeEditor/embeddedCodeEditorWidget';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { InlineChatController, InlineChatRunOptions } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController';
|
||||
import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET_DISCARD, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_EDIT_MODE, EditMode, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChatResponseTypes, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_USER_DID_EDIT, CTX_INLINE_CHAT_RESPONSE_FOCUSED, CTX_INLINE_CHAT_SUPPORT_ISSUE_REPORTING, InlineChatResponseFeedbackKind, CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF, CTX_INLINE_CHAT_CHANGE_HAS_DIFF, MENU_INLINE_CHAT_WIDGET } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_HAS_PROVIDER, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_WIDGET_DISCARD, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_EDIT_MODE, EditMode, CTX_INLINE_CHAT_DOCUMENT_CHANGED, CTX_INLINE_CHAT_DID_EDIT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, CTX_INLINE_CHAT_RESPONSE_TYPES, InlineChatResponseTypes, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_USER_DID_EDIT, CTX_INLINE_CHAT_RESPONSE_FOCUSED, CTX_INLINE_CHAT_SUPPORT_ISSUE_REPORTING, InlineChatResponseFeedbackKind, CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF, CTX_INLINE_CHAT_CHANGE_HAS_DIFF, MENU_INLINE_CHAT_WIDGET, ACTION_TOGGLE_DIFF } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { localize, localize2 } from 'vs/nls';
|
||||
import { Action2, IAction2Options, MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
|
@ -32,7 +32,8 @@ import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/brow
|
|||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { CONTEXT_RESPONSE, CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { CONTEXT_CHAT_LOCATION, CONTEXT_RESPONSE, CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { ChatAgentLocation } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
|
||||
CommandsRegistry.registerCommandAlias('interactiveEditor.start', 'inlineChat.start');
|
||||
CommandsRegistry.registerCommandAlias('interactive.acceptChanges', ACTION_ACCEPT_CHANGES);
|
||||
|
@ -170,6 +171,18 @@ export abstract class AbstractInlineChatAction extends EditorAction2 {
|
|||
}
|
||||
|
||||
|
||||
const CHAT_REGENERATE_MENU = MenuId.for('inlineChat.response.rerun');
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.ChatMessageTitle, {
|
||||
submenu: CHAT_REGENERATE_MENU,
|
||||
title: localize('reunmenu', "Regenerate..."),
|
||||
icon: Codicon.refresh,
|
||||
group: 'navigation',
|
||||
order: -10,
|
||||
when: ContextKeyExpr.and(CONTEXT_RESPONSE, CONTEXT_CHAT_LOCATION.isEqualTo(ChatAgentLocation.Editor))
|
||||
});
|
||||
|
||||
|
||||
export class ReRunRequestAction extends AbstractInlineChatAction {
|
||||
|
||||
constructor() {
|
||||
|
@ -179,16 +192,16 @@ export class ReRunRequestAction extends AbstractInlineChatAction {
|
|||
shortTitle: localize('rerunShort', 'Regenerate'),
|
||||
icon: Codicon.refresh,
|
||||
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_EMPTY.negate(), CTX_INLINE_CHAT_RESPONSE_TYPES.notEqualsTo(InlineChatResponseTypes.Empty)),
|
||||
menu: {
|
||||
id: MENU_INLINE_CHAT_WIDGET_STATUS,
|
||||
group: '2_feedback',
|
||||
order: 3,
|
||||
}
|
||||
menu: [{
|
||||
id: CHAT_REGENERATE_MENU,
|
||||
group: 'navigation',
|
||||
order: -120,
|
||||
when: ContextKeyExpr.and(CONTEXT_RESPONSE, CONTEXT_CHAT_LOCATION.isEqualTo(ChatAgentLocation.Editor))
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
override runInlineChatCommand(_accessor: ServicesAccessor, ctrl: InlineChatController): void {
|
||||
// ctrl.regenerate();
|
||||
ctrl.rerun({ retry: true });
|
||||
}
|
||||
}
|
||||
|
@ -198,13 +211,13 @@ export class ReRunRequestWithIntentDetectionAction extends AbstractInlineChatAct
|
|||
constructor() {
|
||||
super({
|
||||
id: 'inlineChat.rerunWithIntentDetection',
|
||||
title: localize('rerunWithout', 'Rerun without command detection'),
|
||||
title: localize('rerunWithout', 'Regenerate without Command Detection'),
|
||||
icon: Codicon.debugRestartFrame,
|
||||
menu: {
|
||||
id: MenuId.ChatMessageTitle,
|
||||
id: CHAT_REGENERATE_MENU,
|
||||
group: 'navigation',
|
||||
order: -100,
|
||||
when: ContextKeyExpr.and(CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND, CONTEXT_RESPONSE)
|
||||
when: ContextKeyExpr.and(CONTEXT_RESPONSE_DETECTED_AGENT_COMMAND, CONTEXT_RESPONSE, CONTEXT_CHAT_LOCATION.isEqualTo(ChatAgentLocation.Editor))
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -394,16 +407,16 @@ export class ToggleDiffForChange extends AbstractInlineChatAction {
|
|||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'inlineChat.toggleDiff',
|
||||
id: ACTION_TOGGLE_DIFF,
|
||||
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_EDIT_MODE.isEqualTo(EditMode.Live), CTX_INLINE_CHAT_CHANGE_HAS_DIFF),
|
||||
title: localize2('showChanges', 'Show Changes'),
|
||||
title: localize2('showChanges', 'Toggle Changes'),
|
||||
icon: Codicon.diffSingle,
|
||||
toggled: {
|
||||
condition: CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF,
|
||||
},
|
||||
menu: [
|
||||
{
|
||||
id: MENU_INLINE_CHAT_WIDGET_FEEDBACK,
|
||||
id: MENU_INLINE_CHAT_WIDGET_STATUS,
|
||||
group: '1_main',
|
||||
when: ContextKeyExpr.and(CTX_INLINE_CHAT_EDIT_MODE.isEqualTo(EditMode.Live), CTX_INLINE_CHAT_CHANGE_HAS_DIFF)
|
||||
}
|
||||
|
@ -454,10 +467,6 @@ export class AcceptChanges extends AbstractInlineChatAction {
|
|||
keybinding: [{
|
||||
weight: KeybindingWeight.WorkbenchContrib + 10,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Enter,
|
||||
}, {
|
||||
primary: KeyCode.Escape,
|
||||
weight: KeybindingWeight.WorkbenchContrib,
|
||||
when: CTX_INLINE_CHAT_USER_DID_EDIT
|
||||
}],
|
||||
menu: {
|
||||
when: ContextKeyExpr.and(CTX_INLINE_CHAT_RESPONSE_TYPES.notEqualsTo(InlineChatResponseTypes.OnlyMessages)),
|
||||
|
@ -480,7 +489,7 @@ export class CancelSessionAction extends AbstractInlineChatAction {
|
|||
id: 'inlineChat.cancel',
|
||||
title: localize('cancel', 'Cancel'),
|
||||
icon: Codicon.clearAll,
|
||||
precondition: CTX_INLINE_CHAT_VISIBLE,
|
||||
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_EDIT_MODE.isEqualTo(EditMode.Preview)),
|
||||
keybinding: {
|
||||
weight: KeybindingWeight.EditorContrib - 1,
|
||||
primary: KeyCode.Escape
|
||||
|
@ -510,7 +519,8 @@ export class CloseAction extends AbstractInlineChatAction {
|
|||
precondition: CTX_INLINE_CHAT_VISIBLE,
|
||||
keybinding: {
|
||||
weight: KeybindingWeight.EditorContrib - 1,
|
||||
primary: KeyCode.Escape
|
||||
primary: KeyCode.Escape,
|
||||
when: CTX_INLINE_CHAT_USER_DID_EDIT.negate()
|
||||
},
|
||||
menu: {
|
||||
id: MENU_INLINE_CHAT_WIDGET,
|
||||
|
@ -521,7 +531,7 @@ export class CloseAction extends AbstractInlineChatAction {
|
|||
}
|
||||
|
||||
async runInlineChatCommand(_accessor: ServicesAccessor, ctrl: InlineChatController, _editor: ICodeEditor, ..._args: any[]): Promise<void> {
|
||||
ctrl.finishExistingSession();
|
||||
ctrl.cancelSession();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import { IDimension } from 'vs/editor/common/core/dimension';
|
|||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { inlineChatBackground } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
|
@ -22,6 +21,7 @@ import { ChatModel } from 'vs/workbench/contrib/chat/common/chatModel';
|
|||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
export class InlineChatContentWidget implements IContentWidget {
|
||||
|
||||
|
@ -64,6 +64,7 @@ export class InlineChatContentWidget implements IContentWidget {
|
|||
ChatAgentLocation.Editor,
|
||||
{ resource: true },
|
||||
{
|
||||
defaultElementHeight: 32,
|
||||
editorOverflowWidgetsDomNode: _editor.getOverflowWidgetsDomNode(),
|
||||
renderStyle: 'compact',
|
||||
renderInputOnTop: true,
|
||||
|
@ -123,20 +124,16 @@ export class InlineChatContentWidget implements IContentWidget {
|
|||
}
|
||||
return {
|
||||
position: this._position,
|
||||
preference: [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW]
|
||||
preference: [ContentWidgetPositionPreference.BELOW]
|
||||
};
|
||||
}
|
||||
|
||||
beforeRender(): IDimension | null {
|
||||
|
||||
const contentWidth = this._editor.getLayoutInfo().contentWidth;
|
||||
const minWidth = Math.round(contentWidth * 0.38);
|
||||
const maxWidth = Math.round(contentWidth * 0.82);
|
||||
|
||||
const width = clamp(220, minWidth, maxWidth);
|
||||
|
||||
const maxHeight = this._widget.input.inputEditor.getOption(EditorOption.lineHeight) * 5;
|
||||
const inputEditorHeight = this._widget.inputEditor.getContentHeight();
|
||||
this._widget.inputEditor.layout(new dom.Dimension(width, inputEditorHeight));
|
||||
|
||||
this._widget.inputEditor.layout(new dom.Dimension(360, Math.min(maxHeight, inputEditorHeight)));
|
||||
|
||||
// const actualHeight = this._widget.inputPartHeight;
|
||||
// return new dom.Dimension(width, actualHeight);
|
||||
|
|
|
@ -934,7 +934,13 @@ export class InlineChatController implements IEditorContribution {
|
|||
this._zone.value.updatePositionAndHeight(widgetPosition);
|
||||
|
||||
} else if (initialRender) {
|
||||
widgetPosition = this._editor.getSelection().getStartPosition();
|
||||
const selection = this._editor.getSelection();
|
||||
widgetPosition = selection.getEndPosition();
|
||||
if (Range.spansMultipleLines(selection) && widgetPosition.column === 1) {
|
||||
// selection ends on "nothing" -> move up to match the
|
||||
// rendered/visible part of the selection
|
||||
widgetPosition = this._editor.getModel().validatePosition(widgetPosition.delta(-1, Number.MAX_SAFE_INTEGER));
|
||||
}
|
||||
this._input.value.show(widgetPosition);
|
||||
|
||||
} else {
|
||||
|
|
|
@ -453,7 +453,7 @@ export class LiveStrategy extends EditModeStrategy {
|
|||
data.viewZoneId = undefined;
|
||||
}
|
||||
});
|
||||
this._ctxCurrentChangeShowsDiff.set(typeof data?.viewZoneId === 'number');
|
||||
this._ctxCurrentChangeShowsDiff.set(typeof data?.viewZoneId === 'string');
|
||||
scrollState.restore(this._editor);
|
||||
};
|
||||
|
||||
|
|
|
@ -189,10 +189,11 @@ export class InlineChatWidget {
|
|||
location,
|
||||
{ resource: true },
|
||||
{
|
||||
// TODO@jrieken support editable code blocks
|
||||
defaultElementHeight: 32,
|
||||
renderStyle: 'compact',
|
||||
renderInputOnTop: true,
|
||||
supportsFileReferences: true,
|
||||
editorOverflowWidgetsDomNode: options.editorOverflowWidgetsDomNode,
|
||||
editableCodeBlocks: options.editableCodeBlocks,
|
||||
menus: {
|
||||
executeToolbar: options.inputMenuId,
|
||||
|
@ -259,6 +260,9 @@ export class InlineChatWidget {
|
|||
this._onDidChangeHeight.fire();
|
||||
}));
|
||||
|
||||
this._store.add(this.chatWidget.onDidChangeContentHeight(() => {
|
||||
this._onDidChangeHeight.fire();
|
||||
}));
|
||||
|
||||
// context keys
|
||||
this._ctxResponseFocused = CTX_INLINE_CHAT_RESPONSE_FOCUSED.bindTo(this._contextKeyService);
|
||||
|
@ -267,8 +271,8 @@ export class InlineChatWidget {
|
|||
this._store.add(tracker.onDidFocus(() => this._ctxResponseFocused.set(true)));
|
||||
|
||||
this._ctxInputEditorFocused = CTX_INLINE_CHAT_FOCUSED.bindTo(_contextKeyService);
|
||||
this._chatWidget.inputEditor.onDidFocusEditorWidget(() => this._ctxInputEditorFocused.set(true));
|
||||
this._chatWidget.inputEditor.onDidBlurEditorWidget(() => this._ctxInputEditorFocused.set(false));
|
||||
this._store.add(this._chatWidget.inputEditor.onDidFocusEditorWidget(() => this._ctxInputEditorFocused.set(true)));
|
||||
this._store.add(this._chatWidget.inputEditor.onDidBlurEditorWidget(() => this._ctxInputEditorFocused.set(false)));
|
||||
|
||||
const statusMenuId = options.statusMenuId instanceof MenuId ? options.statusMenuId : options.statusMenuId.menu;
|
||||
const statusMenuOptions = options.statusMenuId instanceof MenuId ? undefined : options.statusMenuId.options;
|
||||
|
|
|
@ -14,7 +14,7 @@ import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget';
|
|||
import { localize } from 'vs/nls';
|
||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_FEEDBACK, MENU_INLINE_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, ACTION_TOGGLE_DIFF, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_FEEDBACK, MENU_INLINE_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { EditorBasedInlineChatWidget } from './inlineChatWidget';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
|
||||
|
@ -49,7 +49,7 @@ export class InlineChatZoneWidget extends ZoneWidget {
|
|||
menu: MENU_INLINE_CHAT_WIDGET_STATUS,
|
||||
options: {
|
||||
buttonConfigProvider: action => {
|
||||
if (action.id === ACTION_REGENERATE_RESPONSE) {
|
||||
if (action.id === ACTION_REGENERATE_RESPONSE || action.id === ACTION_TOGGLE_DIFF) {
|
||||
return { showIcon: true, showLabel: false, isSecondary: true };
|
||||
} else if (action.id === ACTION_VIEW_IN_CHAT || action.id === ACTION_ACCEPT_CHANGES) {
|
||||
return { isSecondary: false };
|
||||
|
@ -132,14 +132,14 @@ export class InlineChatZoneWidget extends ZoneWidget {
|
|||
const marginWithoutIndentation = info.glyphMarginWidth + info.decorationsWidth + info.lineNumbersWidth;
|
||||
this.container.style.marginLeft = `${marginWithoutIndentation}px`;
|
||||
|
||||
this._setWidgetMargins(position);
|
||||
super.show(position, this._computeHeightInLines());
|
||||
this._setWidgetMargins(position);
|
||||
this.widget.focus();
|
||||
}
|
||||
|
||||
override updatePositionAndHeight(position: Position): void {
|
||||
this._setWidgetMargins(position);
|
||||
super.updatePositionAndHeight(position, this._computeHeightInLines());
|
||||
this._setWidgetMargins(position);
|
||||
}
|
||||
|
||||
protected override _getWidth(info: EditorLayoutInfo): number {
|
||||
|
@ -157,12 +157,17 @@ export class InlineChatZoneWidget extends ZoneWidget {
|
|||
if (!viewModel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const visibleRange = viewModel.getCompletelyVisibleViewRange();
|
||||
const startLineVisibleRange = visibleRange.startLineNumber;
|
||||
const positionLine = position.lineNumber;
|
||||
let indentationLineNumber: number | undefined;
|
||||
let indentationLevel: number | undefined;
|
||||
for (let lineNumber = positionLine; lineNumber >= startLineVisibleRange; lineNumber--) {
|
||||
if (!visibleRange.containsPosition(position)) {
|
||||
// this is needed because `getOffsetForColumn` won't work when the position
|
||||
// isn't visible/rendered
|
||||
return 0;
|
||||
}
|
||||
|
||||
let indentationLevel = viewModel.getLineFirstNonWhitespaceColumn(position.lineNumber);
|
||||
let indentationLineNumber = position.lineNumber;
|
||||
for (let lineNumber = position.lineNumber; lineNumber >= visibleRange.startLineNumber; lineNumber--) {
|
||||
const currentIndentationLevel = viewModel.getLineFirstNonWhitespaceColumn(lineNumber);
|
||||
if (currentIndentationLevel !== 0) {
|
||||
indentationLineNumber = lineNumber;
|
||||
|
@ -170,7 +175,8 @@ export class InlineChatZoneWidget extends ZoneWidget {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return this.editor.getOffsetForColumn(indentationLineNumber ?? positionLine, indentationLevel ?? viewModel.getLineFirstNonWhitespaceColumn(positionLine));
|
||||
|
||||
return Math.max(0, this.editor.getOffsetForColumn(indentationLineNumber, indentationLevel)); // double-guard against invalie getOffsetForColumn-calls
|
||||
}
|
||||
|
||||
private _setWidgetMargins(position: Position): void {
|
||||
|
|
|
@ -50,12 +50,12 @@
|
|||
/* status */
|
||||
|
||||
.monaco-workbench .inline-chat .status {
|
||||
padding-top: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
.monaco-workbench .inline-chat .status .actions.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@
|
|||
overflow: hidden;
|
||||
color: var(--vscode-descriptionForeground);
|
||||
font-size: 11px;
|
||||
align-self: baseline;
|
||||
padding-top: 4px;
|
||||
padding-left: 10px;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
@ -130,6 +130,7 @@
|
|||
|
||||
.monaco-workbench .inline-chat .status .actions {
|
||||
display: flex;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.monaco-workbench .inline-chat .status .actions > .monaco-button,
|
||||
|
@ -234,9 +235,9 @@
|
|||
background-color: var(--vscode-inlineChat-regionHighlight);
|
||||
}
|
||||
|
||||
.monaco-workbench .inline-chat-slash-command {
|
||||
.monaco-workbench .interactive-session .interactive-input-and-execute-toolbar .monaco-editor .inline-chat-slash-command {
|
||||
background-color: var(--vscode-chat-slashCommandBackground);
|
||||
color: var(--vscode-chat-slashCommandForeground);
|
||||
color: var(--vscode-chat-slashCommandForeground); /* Overrides the foreground color rule in chat.css */
|
||||
border-radius: 4px;
|
||||
padding: 1px;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
display: none;
|
||||
}
|
||||
|
||||
.monaco-workbench .inline-chat-content-widget.interactive-session .interactive-session {
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
.monaco-workbench .inline-chat-content-widget.interactive-session .interactive-input-part .interactive-execute-toolbar {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
|
|
@ -176,6 +176,7 @@ export const CTX_INLINE_CHAT_EDIT_MODE = new RawContextKey<EditMode>('config.inl
|
|||
export const ACTION_ACCEPT_CHANGES = 'inlineChat.acceptChanges';
|
||||
export const ACTION_REGENERATE_RESPONSE = 'inlineChat.regenerate';
|
||||
export const ACTION_VIEW_IN_CHAT = 'inlineChat.viewInChat';
|
||||
export const ACTION_TOGGLE_DIFF = 'inlineChat.toggleDiff';
|
||||
|
||||
// --- menus
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ class InteractiveWindowWorkingCopyEditorHandler extends Disposable implements IW
|
|||
}
|
||||
}
|
||||
|
||||
registerWorkbenchContribution2(InteractiveDocumentContribution.ID, InteractiveDocumentContribution, WorkbenchPhase.AfterRestored);
|
||||
registerWorkbenchContribution2(InteractiveDocumentContribution.ID, InteractiveDocumentContribution, WorkbenchPhase.BlockRestore);
|
||||
registerWorkbenchContribution2(InteractiveInputContentProvider.ID, InteractiveInputContentProvider, {
|
||||
editorTypeId: INTERACTIVE_WINDOW_EDITOR_ID
|
||||
});
|
||||
|
|
|
@ -324,7 +324,7 @@ class LanguageStatus {
|
|||
href: URI.from({
|
||||
scheme: 'command', path: command.id, query: command.arguments && JSON.stringify(command.arguments)
|
||||
}).toString()
|
||||
}, undefined, this._openerService));
|
||||
}, { hoverDelegate: nativeHoverDelegate }, this._openerService));
|
||||
}
|
||||
|
||||
// -- pin
|
||||
|
|
|
@ -316,8 +316,8 @@ export class NotebookChatController extends Disposable implements INotebookEdito
|
|||
run(index: number, input: string | undefined, autoSend: boolean | undefined): void {
|
||||
if (this._widget) {
|
||||
if (this._widget.afterModelPosition !== index) {
|
||||
this._disposeWidget();
|
||||
const window = getWindow(this._widget.domNode);
|
||||
this._disposeWidget();
|
||||
|
||||
scheduleAtNextAnimationFrame(window, () => {
|
||||
this._createWidget(index, input, autoSend, undefined);
|
||||
|
|
|
@ -929,7 +929,7 @@ export class NotebookCellList extends WorkbenchList<CellViewModel> implements ID
|
|||
// wait for the editor to be created if the cell is in editing mode
|
||||
cell.getEditState() === CellEditState.Editing
|
||||
// wait for the editor to be created if we are revealing the first line of the cell
|
||||
|| revealType === CellRevealType.FirstLineIfOutsideViewport
|
||||
|| (revealType === CellRevealType.FirstLineIfOutsideViewport && cell.cellKind === CellKind.Code)
|
||||
) && !cell.editorAttached) {
|
||||
return getEditorAttachedPromise(cell);
|
||||
}
|
||||
|
|
|
@ -561,7 +561,7 @@ async function webviewPreloads(ctx: PreloadContext) {
|
|||
let lastTimeScrolled: number | undefined;
|
||||
function flagRecentlyScrolled(node: Element, deltaY?: number) {
|
||||
scrolledElement = node;
|
||||
if (!deltaY) {
|
||||
if (deltaY === undefined) {
|
||||
lastTimeScrolled = Date.now();
|
||||
previousDelta = undefined;
|
||||
node.setAttribute('recentlyScrolled', 'true');
|
||||
|
|
|
@ -97,7 +97,7 @@ export class SyncScroll extends Disposable implements IWorkbenchContribution {
|
|||
}
|
||||
|
||||
if (!isEditorPaneWithScrolling(pane)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
const initialOffset = this.paneInitialScrollTop.get(pane);
|
||||
|
@ -105,10 +105,17 @@ export class SyncScroll extends Disposable implements IWorkbenchContribution {
|
|||
throw new Error('Could not find initial offset for pane');
|
||||
}
|
||||
|
||||
pane.setScrollPosition({
|
||||
const currentPanePosition = pane.getScrollPosition();
|
||||
const newPaneScrollPosition = {
|
||||
scrollTop: initialOffset.scrollTop + scrolledFromInitial.scrollTop,
|
||||
scrollLeft: initialOffset.scrollLeft !== undefined && scrolledFromInitial.scrollLeft !== undefined ? initialOffset.scrollLeft + scrolledFromInitial.scrollLeft : undefined,
|
||||
});
|
||||
};
|
||||
|
||||
if (currentPanePosition.scrollTop === newPaneScrollPosition.scrollTop && currentPanePosition.scrollLeft === newPaneScrollPosition.scrollLeft) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pane.setScrollPosition(newPaneScrollPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,7 @@ export class SpeechService extends Disposable implements ISpeechService {
|
|||
|
||||
const sessionStart = Date.now();
|
||||
let sessionRecognized = false;
|
||||
let sessionContentLength = 0;
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
|
@ -163,16 +164,22 @@ export class SpeechService extends Disposable implements ISpeechService {
|
|||
context: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Context of the session.' };
|
||||
sessionDuration: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Duration of the session.' };
|
||||
sessionRecognized: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'If speech was recognized.' };
|
||||
sessionContentLength: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Length of the recognized text.' };
|
||||
sessionLanguage: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Configured language for the session.' };
|
||||
};
|
||||
type SpeechToTextSessionEvent = {
|
||||
context: string;
|
||||
sessionDuration: number;
|
||||
sessionRecognized: boolean;
|
||||
sessionContentLength: number;
|
||||
sessionLanguage: string;
|
||||
};
|
||||
this.telemetryService.publicLog2<SpeechToTextSessionEvent, SpeechToTextSessionClassification>('speechToTextSession', {
|
||||
context,
|
||||
sessionDuration: Date.now() - sessionStart,
|
||||
sessionRecognized
|
||||
sessionRecognized,
|
||||
sessionContentLength,
|
||||
sessionLanguage: language
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -194,9 +201,13 @@ export class SpeechService extends Disposable implements ISpeechService {
|
|||
}
|
||||
break;
|
||||
case SpeechToTextStatus.Recognizing:
|
||||
case SpeechToTextStatus.Recognized:
|
||||
sessionRecognized = true;
|
||||
break;
|
||||
case SpeechToTextStatus.Recognized:
|
||||
if (typeof e.text === 'string') {
|
||||
sessionContentLength += e.text.length;
|
||||
}
|
||||
break;
|
||||
case SpeechToTextStatus.Stopped:
|
||||
onSessionStoppedOrCanceled();
|
||||
break;
|
||||
|
|
|
@ -139,12 +139,6 @@ export class TerminalProfileQuickpick {
|
|||
if (context.item.profile.env) {
|
||||
newConfigValue[name].env = context.item.profile.env;
|
||||
}
|
||||
if (context.item.profile.color) {
|
||||
newConfigValue[name].color = context.item.profile.color;
|
||||
}
|
||||
if (context.item.profile.icon) {
|
||||
newConfigValue[name].icon = context.item.profile.icon;
|
||||
}
|
||||
await this._configurationService.updateValue(profilesKey, newConfigValue, ConfigurationTarget.USER);
|
||||
},
|
||||
onKeyMods: mods => keyMods = mods
|
||||
|
|
|
@ -259,21 +259,36 @@ export async function showRunRecentQuickPick(
|
|||
}
|
||||
});
|
||||
let terminalScrollStateSaved = false;
|
||||
function restoreScrollState() {
|
||||
terminalScrollStateSaved = false;
|
||||
instance.xterm?.markTracker.restoreScrollState();
|
||||
instance.xterm?.markTracker.clear();
|
||||
}
|
||||
quickPick.onDidChangeActive(async () => {
|
||||
const xterm = instance.xterm;
|
||||
if (!xterm) {
|
||||
return;
|
||||
}
|
||||
const [item] = quickPick.activeItems;
|
||||
if ('command' in item && item.command) {
|
||||
if ('command' in item && item.command && item.command.marker) {
|
||||
if (!terminalScrollStateSaved) {
|
||||
xterm.markTracker.saveScrollState();
|
||||
terminalScrollStateSaved = true;
|
||||
}
|
||||
xterm.markTracker.revealCommand(item.command);
|
||||
const promptRowCount = item.command.getPromptRowCount();
|
||||
const commandRowCount = item.command.getCommandRowCount();
|
||||
xterm.markTracker.revealRange({
|
||||
start: {
|
||||
x: 1,
|
||||
y: item.command.marker.line - (promptRowCount - 1) + 1
|
||||
},
|
||||
end: {
|
||||
x: instance.cols,
|
||||
y: item.command.marker.line + (commandRowCount - 1) + 1
|
||||
}
|
||||
});
|
||||
} else {
|
||||
terminalScrollStateSaved = false;
|
||||
xterm.markTracker.restoreScrollState();
|
||||
restoreScrollState();
|
||||
}
|
||||
});
|
||||
quickPick.onDidAccept(async () => {
|
||||
|
@ -289,13 +304,9 @@ export async function showRunRecentQuickPick(
|
|||
if (quickPick.keyMods.alt) {
|
||||
instance.focus();
|
||||
}
|
||||
terminalScrollStateSaved = false;
|
||||
instance.xterm?.markTracker.restoreScrollState();
|
||||
});
|
||||
quickPick.onDidHide(() => {
|
||||
terminalScrollStateSaved = false;
|
||||
instance.xterm?.markTracker.restoreScrollState();
|
||||
restoreScrollState();
|
||||
});
|
||||
quickPick.onDidHide(() => restoreScrollState());
|
||||
if (value) {
|
||||
quickPick.value = value;
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ export class TerminalVoiceSession extends Disposable {
|
|||
}, voiceTimeout));
|
||||
this._cancellationTokenSource = new CancellationTokenSource();
|
||||
this._register(toDisposable(() => this._cancellationTokenSource?.dispose(true)));
|
||||
const session = await this._speechService.createSpeechToTextSession(this._cancellationTokenSource?.token);
|
||||
const session = await this._speechService.createSpeechToTextSession(this._cancellationTokenSource?.token, 'terminal');
|
||||
|
||||
this._disposables.add(session.onDidChange((e) => {
|
||||
if (this._cancellationTokenSource?.token.isCancellationRequested) {
|
||||
|
|
|
@ -277,8 +277,10 @@ export class TerminalChatController extends Disposable implements ITerminalContr
|
|||
return;
|
||||
}
|
||||
|
||||
if (progress.kind === 'content' || progress.kind === 'markdownContent') {
|
||||
if (progress.kind === 'content') {
|
||||
responseContent += progress.content;
|
||||
} else if (progress.kind === 'markdownContent') {
|
||||
responseContent += progress.content.value;
|
||||
}
|
||||
if (this._currentRequest) {
|
||||
model.acceptResponseProgress(this._currentRequest, progress);
|
||||
|
|
|
@ -221,12 +221,10 @@ export class TerminalLinkQuickpick extends DisposableStore {
|
|||
}
|
||||
|
||||
// Skip the link if it's a duplicate URI + line/col
|
||||
if (description) {
|
||||
if (linkUriKeys.has(label + '|' + description)) {
|
||||
continue;
|
||||
}
|
||||
linkUriKeys.add(label + '|' + description);
|
||||
if (linkUriKeys.has(label + '|' + (description ?? ''))) {
|
||||
continue;
|
||||
}
|
||||
linkUriKeys.add(label + '|' + (description ?? ''));
|
||||
}
|
||||
|
||||
picks.push({ label, link, description });
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions';
|
||||
import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager';
|
||||
import { SuggestAddon } from 'vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon';
|
||||
import { ITerminalProcessManager, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { ITerminalConfiguration, ITerminalProcessManager, TERMINAL_CONFIG_SECTION, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import type { Terminal as RawXtermTerminal } from '@xterm/xterm';
|
||||
import { ContextKeyExpr, IContextKey, IContextKeyService, IReadableSet } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
|
||||
|
@ -18,6 +18,8 @@ import { registerActiveInstanceAction } from 'vs/workbench/contrib/terminal/brow
|
|||
import { localize2 } from 'vs/nls';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TerminalSettingId } from 'vs/platform/terminal/common/terminal';
|
||||
|
||||
class TerminalSuggestContribution extends DisposableStore implements ITerminalContribution {
|
||||
static readonly ID = 'terminal.suggest';
|
||||
|
@ -26,17 +28,18 @@ class TerminalSuggestContribution extends DisposableStore implements ITerminalCo
|
|||
return instance.getContribution<TerminalSuggestContribution>(TerminalSuggestContribution.ID);
|
||||
}
|
||||
|
||||
private _addon: SuggestAddon | undefined;
|
||||
private _addon: MutableDisposable<SuggestAddon> = new MutableDisposable();
|
||||
private _terminalSuggestWidgetContextKeys: IReadableSet<string> = new Set(TerminalContextKeys.suggestWidgetVisible.key);
|
||||
private _terminalSuggestWidgetVisibleContextKey: IContextKey<boolean>;
|
||||
|
||||
get addon(): SuggestAddon | undefined { return this._addon; }
|
||||
get addon(): SuggestAddon | undefined { return this._addon.value; }
|
||||
|
||||
constructor(
|
||||
private readonly _instance: ITerminalInstance,
|
||||
_processManager: ITerminalProcessManager,
|
||||
widgetManager: TerminalWidgetManager,
|
||||
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
|
@ -51,21 +54,31 @@ class TerminalSuggestContribution extends DisposableStore implements ITerminalCo
|
|||
this._loadSuggestAddon(xterm.raw);
|
||||
}
|
||||
}));
|
||||
this.add(this._configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(TerminalSettingId.SendKeybindingsToShell)) {
|
||||
this._loadSuggestAddon(xterm.raw);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private _loadSuggestAddon(xterm: RawXtermTerminal): void {
|
||||
const sendingKeybindingsToShell = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION).sendKeybindingsToShell;
|
||||
if (sendingKeybindingsToShell) {
|
||||
this._addon.dispose();
|
||||
return;
|
||||
}
|
||||
if (this._terminalSuggestWidgetVisibleContextKey) {
|
||||
this._addon = this._instantiationService.createInstance(SuggestAddon, this._terminalSuggestWidgetVisibleContextKey);
|
||||
xterm.loadAddon(this._addon);
|
||||
this._addon?.setPanel(dom.findParentWithClass(xterm.element!, 'panel')!);
|
||||
this._addon?.setScreen(xterm.element!.querySelector('.xterm-screen')!);
|
||||
this.add(this._instance.onDidBlur(() => this._addon?.hideSuggestWidget()));
|
||||
this.add(this._addon.onAcceptedCompletion(async text => {
|
||||
this._addon.value = this._instantiationService.createInstance(SuggestAddon, this._terminalSuggestWidgetVisibleContextKey);
|
||||
xterm.loadAddon(this._addon.value);
|
||||
this._addon.value.setPanel(dom.findParentWithClass(xterm.element!, 'panel')!);
|
||||
this._addon.value.setScreen(xterm.element!.querySelector('.xterm-screen')!);
|
||||
this.add(this._instance.onDidBlur(() => this._addon.value?.hideSuggestWidget()));
|
||||
this.add(this._addon.value.onAcceptedCompletion(async text => {
|
||||
this._instance.focus();
|
||||
this._instance.sendText(text, false);
|
||||
}));
|
||||
this.add(this._instance.onDidSendText((text) => {
|
||||
this._addon?.handleNonXtermData(text);
|
||||
this._addon.value?.handleNonXtermData(text);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ export class WebviewElement extends Disposable implements IWebview, WebviewFindD
|
|||
this.element?.classList.add('ready');
|
||||
|
||||
if (this._state.type === WebviewState.Type.Initializing) {
|
||||
this._state.pendingMessages.forEach(({ channel, data }) => this.doPostMessage(channel, data));
|
||||
this._state.pendingMessages.forEach(({ channel, data, resolve }) => resolve(this.doPostMessage(channel, data)));
|
||||
}
|
||||
this._state = WebviewState.Ready;
|
||||
|
||||
|
|
|
@ -853,17 +853,21 @@ export class GettingStartedPage extends EditorPane {
|
|||
if (gettingStartedList.itemCount) {
|
||||
this.container.classList.remove('noWalkthroughs');
|
||||
if (videoList?.itemCount > 0) {
|
||||
this.container.classList.remove('noVideos');
|
||||
reset(rightColumn, videoList?.getDomElement(), gettingStartedList.getDomElement());
|
||||
} else {
|
||||
this.container.classList.add('noVideos');
|
||||
reset(rightColumn, gettingStartedList.getDomElement());
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.container.classList.add('noWalkthroughs');
|
||||
if (videoList?.itemCount > 0) {
|
||||
this.container.classList.remove('noVideos');
|
||||
reset(rightColumn, videoList?.getDomElement());
|
||||
}
|
||||
else {
|
||||
this.container.classList.add('noVideos');
|
||||
reset(rightColumn);
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +876,7 @@ export class GettingStartedPage extends EditorPane {
|
|||
};
|
||||
|
||||
const layoutRecentList = () => {
|
||||
if (this.container.classList.contains('noWalkthroughs') && videoList?.itemCount === 0) {
|
||||
if (this.container.classList.contains('noWalkthroughs') && this.container.classList.contains('noVideos')) {
|
||||
recentList.setLimit(10);
|
||||
reset(leftColumn, startList.getDomElement());
|
||||
reset(rightColumn, recentList.getDomElement());
|
||||
|
|
|
@ -74,12 +74,17 @@ export class CustomEditorLabelService extends Disposable implements ICustomEdito
|
|||
this.enabled = this.configurationService.getValue<boolean>(CustomEditorLabelService.SETTING_ID_ENABLED);
|
||||
}
|
||||
|
||||
private _templateRegexValidation: RegExp = /[a-zA-Z0-9]/;
|
||||
private storeCustomPatterns(): void {
|
||||
this.patterns = [];
|
||||
const customLabelPatterns = this.configurationService.getValue<ICustomEditorLabelObject>(CustomEditorLabelService.SETTING_ID_PATTERNS);
|
||||
for (const pattern in customLabelPatterns) {
|
||||
const template = customLabelPatterns[pattern];
|
||||
|
||||
if (!this._templateRegexValidation.test(template)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isAbsolutePath = isAbsolute(pattern);
|
||||
const parsedPattern = parseGlob(pattern);
|
||||
|
||||
|
|
|
@ -84,10 +84,6 @@ declare module 'vscode' {
|
|||
/**
|
||||
* Execute a command, sending ^C as necessary to interrupt any running command if needed.
|
||||
*
|
||||
* *Note* This is not guaranteed to work as [shell integration](https://code.visualstudio.com/docs/terminal/shell-integration)
|
||||
* must be activated. Check whether {@link TerminalShellExecution.exitCode} is rejected to
|
||||
* verify whether it was successful.
|
||||
*
|
||||
* @param commandLine The command line to execute, this is the exact text that will be sent
|
||||
* to the terminal.
|
||||
*
|
||||
|
|
47
yarn.lock
47
yarn.lock
|
@ -3563,10 +3563,10 @@ electron-to-chromium@^1.4.648:
|
|||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz#c7b46c9010752c37bb4322739d6d2dd82354fbe4"
|
||||
integrity sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg==
|
||||
|
||||
electron@28.2.6:
|
||||
version "28.2.6"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-28.2.6.tgz#ec4958ff759009e3eb2c9489df5eb02f989f06bf"
|
||||
integrity sha512-RuhbW+ifvh3DqnVlHCcCKhKIFOxTktq1GN1gkIkEZ8y5LEZfcjOkxB2s6Fd1S6MzsMZbiJti+ZJG5hXS4SDVLQ==
|
||||
electron@28.2.8:
|
||||
version "28.2.8"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-28.2.8.tgz#b83d70ca00c0e767f0125fcec85f39aafe39ee4c"
|
||||
integrity sha512-VgXw2OHqPJkobIC7X9eWh3atptjnELaP+zlbF9Oz00ridlaOWmtLPsp6OaXbLw35URpMr0iYesq8okKp7S0k+g==
|
||||
dependencies:
|
||||
"@electron/get" "^2.0.0"
|
||||
"@types/node" "^18.11.18"
|
||||
|
@ -3694,21 +3694,22 @@ es-to-primitive@^1.2.1:
|
|||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
|
||||
version "0.10.53"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
|
||||
integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
|
||||
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
|
||||
version "0.10.63"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.63.tgz#9c222a63b6a332ac80b1e373b426af723b895bd6"
|
||||
integrity sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ==
|
||||
dependencies:
|
||||
es6-iterator "~2.0.3"
|
||||
es6-symbol "~3.1.3"
|
||||
next-tick "~1.0.0"
|
||||
es6-iterator "^2.0.3"
|
||||
es6-symbol "^3.1.3"
|
||||
esniff "^2.0.1"
|
||||
next-tick "^1.1.0"
|
||||
|
||||
es6-error@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
|
||||
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
|
||||
|
||||
es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3:
|
||||
es6-iterator@^2.0.1, es6-iterator@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
|
||||
integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
|
||||
|
@ -3717,7 +3718,7 @@ es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3:
|
|||
es5-ext "^0.10.35"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
es6-symbol@^3.1.1, es6-symbol@~3.1.3:
|
||||
es6-symbol@^3.1.1, es6-symbol@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
|
||||
integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
|
||||
|
@ -3909,6 +3910,16 @@ eslint@^5.0.1:
|
|||
table "^5.2.3"
|
||||
text-table "^0.2.0"
|
||||
|
||||
esniff@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
|
||||
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
|
||||
dependencies:
|
||||
d "^1.0.1"
|
||||
es5-ext "^0.10.62"
|
||||
event-emitter "^0.3.5"
|
||||
type "^2.7.2"
|
||||
|
||||
espree@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a"
|
||||
|
@ -6862,11 +6873,6 @@ next-tick@1, next-tick@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
|
||||
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
|
||||
|
||||
next-tick@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
||||
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
|
@ -9620,6 +9626,11 @@ type@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/type/-/type-2.1.0.tgz#9bdc22c648cf8cf86dd23d32336a41cfb6475e3f"
|
||||
integrity sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==
|
||||
|
||||
type@^2.7.2:
|
||||
version "2.7.2"
|
||||
resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
|
||||
integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
|
||||
|
||||
typedarray@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
|
|
Loading…
Reference in a new issue