Merge branch 'main' into aiday/notRebuildingFullStickyScroll

This commit is contained in:
Aiday Marlen Kyzy
2023-09-03 17:13:51 +02:00
261 changed files with 7332 additions and 3205 deletions
+41
View File
@@ -196,6 +196,47 @@
]
}
},
{
"files": [
"**/vscode.d.ts"
],
"rules": {
"jsdoc/tag-lines": "off",
"jsdoc/valid-types": "off",
"jsdoc/no-multi-asterisks": [
"warn",
{
"allowWhitespace": true
}
],
"jsdoc/require-jsdoc": [
"warn",
{
"enableFixer": false,
"contexts": [
"TSInterfaceDeclaration",
"TSPropertySignature",
"TSMethodSignature",
"TSDeclareFunction",
"ClassDeclaration",
"MethodDefinition",
"PropertyDeclaration",
"TSEnumDeclaration",
"TSEnumMember",
"ExportNamedDeclaration"
]
}
],
"jsdoc/check-param-names": [
"warn",
{
"enableFixer": false,
"checkDestructured": false
}
],
"jsdoc/require-returns": "warn"
}
},
{
"files": [
"src/**/{common,browser}/**/*.ts"
+5 -1
View File
@@ -256,7 +256,11 @@
"browserLaunchLocation": "workspace",
"presentation": {
"hidden": true,
}
},
// This is read by the vscode-diagnostic-tools extension
"vscode-diagnostic-tools.debuggerScripts": [
"${workspaceFolder}/scripts/hot-reload-injected-script.js"
]
},
{
"type": "node",
+1 -1
View File
@@ -177,7 +177,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS $MILESTONE -$MINE is:issue label:bug label:verification-steps-needed"
"value": "$REPOS $MILESTONE -$MINE is:issue label:bug label:verification-steps-needed -label:verified"
},
{
"kind": 1,
+2 -2
View File
@@ -1,5 +1,5 @@
disturl "https://electronjs.org/headers"
target "25.5.0"
ms_build_id "23084831"
target "25.8.0"
ms_build_id "23503258"
runtime "electron"
build_from_source "true"
+700 -591
View File
File diff suppressed because it is too large Load Diff
+27 -27
View File
@@ -1,27 +1,27 @@
c3fb8cb4804143eb25fce55a179a6f2df8c215ed709104ec235c96e357b20f42 *electron-v25.5.0-darwin-arm64-symbols.zip
e6d2a09348d4fe7c9fbd92bf796489a95e625642f0f1ce96169212554cfa6841 *electron-v25.5.0-darwin-arm64.zip
15c28e613dfee0f7e46a296bb4aed64e17f9644d7ef19129aeb6480b8da230ab *electron-v25.5.0-darwin-x64-symbols.zip
a5c5c0b621daf8242258c89edb2387fbdf1c69125c984f8564d89b87927373e3 *electron-v25.5.0-darwin-x64.zip
69d60a69b7f692b9069cdf9e518bcbaca9cec561f40199cc87196929936a34ce *electron-v25.5.0-linux-arm64-symbols.zip
adec2ba09faf5f8d8af8997c8bed43c7712eba5546db1e7d06f8357bf4613921 *electron-v25.5.0-linux-arm64.zip
0fe7a5d152c9c401671e02ebcd9da34ab9bb0c28598ede3657077a79f8b3e70a *electron-v25.5.0-linux-armv7l-symbols.zip
eccb66e4a308a0bd2d90474894370e3d687e32f78672e6b5077c1822c7bc526b *electron-v25.5.0-linux-armv7l.zip
82bd9bc9e66f8ae802fe48a51b8d7e2fb599403e9715fa4b859190200a7376b1 *electron-v25.5.0-linux-x64-symbols.zip
485cbeb206fccfb4ed42f694100eebb80c9db6639b3537a95823c4fcb7f210cd *electron-v25.5.0-linux-x64.zip
ed2c2a7da571b53bcb336b9a2a024753a272df82ece45df83df888df51bf1912 *electron-v25.5.0-win32-arm64-pdb.zip
c316f6364e9b4cd61e19d4763c96abda7247a2c31ae7d30e81219c9a7754f11a *electron-v25.5.0-win32-arm64-symbols.zip
582ccbfc5a85a093f5639ee476bb5fef18c2d25dab4a60e5f5cb47e64c99f7fb *electron-v25.5.0-win32-arm64.zip
5776e650c23e3847b0c52d850f61c57a84a4fa30943c3cc82197250112911b5b *electron-v25.5.0-win32-ia32-pdb.zip
730b429ad2c4cae0fe3ba9600a6ee86c79dada77976bac1c75ca2404993495bc *electron-v25.5.0-win32-ia32-symbols.zip
7e6e68aa33a89c0d647575b06daf415a2401feb170ebb9cd795e221af321f751 *electron-v25.5.0-win32-ia32.zip
0792665fda9255b340a829cdd24601887a2ca8f04cc49f9a6d4557db0c0cd2f2 *electron-v25.5.0-win32-x64-pdb.zip
dc2459546951f8418e866857e9111dd83a0789d401906b2200c2f8dd59d9146b *electron-v25.5.0-win32-x64-symbols.zip
9bf7980fbc024ba77ea8ab3e2d32088a5f69bf32506a7d2db72ede17028abdf4 *electron-v25.5.0-win32-x64.zip
5b1ea601b737842eacf88d7456c4d14e697822753e9a08ede889cce9e20bafb2 *ffmpeg-v25.5.0-darwin-arm64.zip
37bf5c75edefc0b6735b44d0b5b06fdd427179a8501f6e93df9840283cdb4a95 *ffmpeg-v25.5.0-darwin-x64.zip
bd52d57ff97fb56ac01a3482af905d04f0d4e9c13c53858c6d9f99957eca82da *ffmpeg-v25.5.0-linux-arm64.zip
9b3d09177fa1e63e2a6beecfa70aeec30aeb5c1873ff21128a68051c4e23f95d *ffmpeg-v25.5.0-linux-armv7l.zip
edc7b1c9f1a0733f109a2c0375a4e40c5bfe0bf28b7f06dcc76e1ada0aa2f125 *ffmpeg-v25.5.0-linux-x64.zip
2e28767b3570ea247869a20988cddd23af710eb994d6099404f123390cedeba6 *ffmpeg-v25.5.0-win32-arm64.zip
715568eefd7267573a30186ade3de901587baeb1f013200d8ae50b35941b613f *ffmpeg-v25.5.0-win32-ia32.zip
29876504452aaa505f696642178968e24b8dc8cc4b055071e6f0f3f073088acc *ffmpeg-v25.5.0-win32-x64.zip
88cafda8394985e59d3d84cb4a6692ad04d8e32db9ecd6429e748e41526ddad7 *electron-v25.8.0-darwin-arm64-symbols.zip
6e33d3b8041561722ed41777e055a8c15d3f4e61b67367b2618918bcf0cfea76 *electron-v25.8.0-darwin-arm64.zip
438ac9915e062a239fb6d2595323c4783d2c820efc9cbcf3d2c1253d0e057e83 *electron-v25.8.0-darwin-x64-symbols.zip
798907d2a66bc79202c8213c61e7fd147ae2a8c31c485d814950b11d43bbbba8 *electron-v25.8.0-darwin-x64.zip
3243f3764319cff6c942d9f90a86323c36ec05ec51ef01e782c4e9a7194187e1 *electron-v25.8.0-linux-arm64-symbols.zip
f24f858b76bf8a2e18419f62e0f891712b2fa541089123e9caa8d5cd67fc3276 *electron-v25.8.0-linux-arm64.zip
dc3ff0489a0ebeda56d06b31eeae75dd7321a52bb601069c4475c56462b4814a *electron-v25.8.0-linux-armv7l-symbols.zip
3b7a0c3899f828a5cf30043b73992e90231400b90c1afa700a44f892a55e326b *electron-v25.8.0-linux-armv7l.zip
44803b2487406eca8fff9cec405e9e50bd92a911808dfaaa523b9ef52a0e72d8 *electron-v25.8.0-linux-x64-symbols.zip
d54fb2df0ad7318240220aa26327171ed1e891fb296f3c27c58b8b487c4df8eb *electron-v25.8.0-linux-x64.zip
bf7be6c0c8d0df06f0ce22e16c97aea823415d7f5cbf0ffdadf65d75feaf3cd8 *electron-v25.8.0-win32-arm64-pdb.zip
5d91757660b44bf30907f9c2b52225ade4d127d0fe48dc83dec134cc06c949f0 *electron-v25.8.0-win32-arm64-symbols.zip
d1e6f30a8d8c7aed28d08ddf915d79de6b16b3a0a7c84c45fd3cc0d47f2b7f53 *electron-v25.8.0-win32-arm64.zip
e389fef61c14ea0eefad91a9725aa0afd4dbdc982f7b30aba97bd9c2871c2061 *electron-v25.8.0-win32-ia32-pdb.zip
374d6c8897f97fab04e990ecf928e05f643ae33801546bf7d39bf4045b9d8b52 *electron-v25.8.0-win32-ia32-symbols.zip
73fc3382202b70dcaf7928f09a791662de82c701b8f403ed72cc5aa9b1401593 *electron-v25.8.0-win32-ia32.zip
010d248bd2e77585e1fa977e58b016659566de5a91c1e6845c85a7e6e1851bb9 *electron-v25.8.0-win32-x64-pdb.zip
72adb74fd92edff35c177c3c5d96765f230bc7adb8af11b30d5122b9e54c26e1 *electron-v25.8.0-win32-x64-symbols.zip
0051d0f241aedc6cdab4751c60f48758936122796f06c9e3033c7710a531686c *electron-v25.8.0-win32-x64.zip
2956915642c45eb0099228368d0af50e891e4c10014fa4d3d3bcfb135fbb89a7 *ffmpeg-v25.8.0-darwin-arm64.zip
099ee69d44f8ac3802cdd612895f279f7adb043a5b9c9d123479b0f96514a44c *ffmpeg-v25.8.0-darwin-x64.zip
bd52d57ff97fb56ac01a3482af905d04f0d4e9c13c53858c6d9f99957eca82da *ffmpeg-v25.8.0-linux-arm64.zip
9b3d09177fa1e63e2a6beecfa70aeec30aeb5c1873ff21128a68051c4e23f95d *ffmpeg-v25.8.0-linux-armv7l.zip
edc7b1c9f1a0733f109a2c0375a4e40c5bfe0bf28b7f06dcc76e1ada0aa2f125 *ffmpeg-v25.8.0-linux-x64.zip
a58e9480dab981ff973749e9d1e08936b2dd63a4b7f9523c030b1833387a4eb5 *ffmpeg-v25.8.0-win32-arm64.zip
6866b23a4d561c0322aeb7690aae646718c54398739946e352bf80d0dd721bfd *ffmpeg-v25.8.0-win32-ia32.zip
7b906df4ad6252881cf1e58619285b624f74d593379fbc6728e238b852d6abad *ffmpeg-v25.8.0-win32-x64.zip
@@ -757,6 +757,7 @@
"--vscode-sash-hover-size",
"--vscode-sash-size",
"--vscode-editorStickyScroll-scrollableWidth",
"--vscode-editorStickyScroll-foldingOpacityTransition",
"--window-border-color",
"--workspace-trust-check-color",
"--workspace-trust-selected-color",
@@ -779,4 +780,4 @@
"--z-index-notebook-sticky-scroll",
"--zoom-factor"
]
}
}
+2 -1
View File
@@ -110,7 +110,8 @@ export interface ICommandHandler {
#include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange
#include(vs/editor/common/diff/documentDiffProvider): IDocumentDiffProvider, IDocumentDiffProviderOptions, IDocumentDiff
#include(vs/editor/common/core/lineRange): LineRange
#include(vs/editor/common/diff/linesDiffComputer): LineRangeMapping, RangeMapping, MovedText, SimpleLineRangeMapping
#include(vs/editor/common/diff/linesDiffComputer): MovedText
#include(vs/editor/common/diff/rangeMapping): DetailedLineRangeMapping, RangeMapping, LineRangeMapping
#include(vs/editor/common/core/dimension): IDimension
#includeAll(vs/editor/common/editorCommon): IScrollEvent
#includeAll(vs/editor/common/textModelEvents):
+2 -2
View File
@@ -528,12 +528,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
"commitHash": "34be316c404e84cdd967fa0e10fceeb6424eed90"
"commitHash": "84d7f7f071ae11637d4a41b95536410293672750"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "25.5.0"
"version": "25.8.0"
},
{
"component": {
+12
View File
@@ -735,6 +735,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
dependencies = [
"crc32fast",
"libz-sys",
"miniz_oxide",
]
@@ -1217,6 +1218,17 @@ version = "0.2.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
[[package]]
name = "libz-sys"
version = "1.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b"
dependencies = [
"cc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "link-cplusplus"
version = "1.0.9"
+2 -2
View File
@@ -18,8 +18,8 @@ open = "4.1.0"
reqwest = { version = "0.11.18", default-features = false, features = ["json", "stream", "native-tls"] }
tokio = { version = "1.28.2", features = ["full"] }
tokio-util = { version = "0.7.8", features = ["compat", "codec"] }
flate2 = "1.0.26"
zip = { version = "0.6.6", default-features = false, features = ["time", "deflate"] }
flate2 = { version = "1.0.26", default-features = false, features = ["zlib"] }
zip = { version = "0.6.6", default-features = false, features = ["time", "deflate-zlib"] }
regex = "1.8.3"
lazy_static = "1.4.0"
sysinfo = { version = "0.29.0", default-features = false }
+56 -65
View File
@@ -525,35 +525,6 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
atty 0.2.14 - MIT
https://github.com/softprops/atty
The MIT License (MIT)
Copyright (c) 2015-2019 Doug Tangren
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
autocfg 1.1.0 - Apache-2.0 OR MIT
https://github.com/cuviper/autocfg
@@ -1875,7 +1846,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
crossbeam-utils 0.8.12 - MIT OR Apache-2.0
crossbeam-utils 0.8.16 - MIT OR Apache-2.0
https://github.com/crossbeam-rs/crossbeam
The MIT License (MIT)
@@ -1965,7 +1936,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
---------------------------------------------------------
cxx 1.0.78 - MIT OR Apache-2.0
cxx 1.0.97 - MIT OR Apache-2.0
https://github.com/dtolnay/cxx
Permission is hereby granted, free of charge, to any
@@ -1995,7 +1966,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
cxx-build 1.0.78 - MIT OR Apache-2.0
cxx-build 1.0.97 - MIT OR Apache-2.0
https://github.com/dtolnay/cxx
Permission is hereby granted, free of charge, to any
@@ -2025,7 +1996,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
cxxbridge-flags 1.0.78 - MIT OR Apache-2.0
cxxbridge-flags 1.0.97 - MIT OR Apache-2.0
https://github.com/dtolnay/cxx
Permission is hereby granted, free of charge, to any
@@ -2055,7 +2026,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
cxxbridge-macro 1.0.78 - MIT OR Apache-2.0
cxxbridge-macro 1.0.97 - MIT OR Apache-2.0
https://github.com/dtolnay/cxx
Permission is hereby granted, free of charge, to any
@@ -3553,7 +3524,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted
---------------------------------------------------------
http 0.2.8 - MIT OR Apache-2.0
http 0.2.9 - MIT OR Apache-2.0
https://github.com/hyperium/http
Copyright (c) 2017 http-rs authors
@@ -3725,7 +3696,7 @@ THE SOFTWARE.
---------------------------------------------------------
iana-time-zone 0.1.51 - MIT OR Apache-2.0
iana-time-zone 0.1.57 - MIT OR Apache-2.0
https://github.com/strawlab/iana-time-zone
Copyright (c) 2020 Andrew D. Straw
@@ -3757,7 +3728,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
iana-time-zone-haiku 0.1.0 - MIT OR Apache-2.0
iana-time-zone-haiku 0.1.1 - MIT OR Apache-2.0
https://github.com/strawlab/iana-time-zone
Copyright (c) 2020 Andrew D. Straw
@@ -4259,7 +4230,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
link-cplusplus 1.0.7 - MIT OR Apache-2.0
link-cplusplus 1.0.9 - MIT OR Apache-2.0
https://github.com/dtolnay/link-cplusplus
Permission is hereby granted, free of charge, to any
@@ -7734,7 +7705,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
scratch 1.0.2 - MIT OR Apache-2.0
scratch 1.0.7 - MIT OR Apache-2.0
https://github.com/dtolnay/scratch
Permission is hereby granted, free of charge, to any
@@ -8753,7 +8724,7 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
termcolor 1.1.3 - Unlicense OR MIT
termcolor 1.2.0 - Unlicense OR MIT
https://github.com/BurntSushi/termcolor
The MIT License (MIT)
@@ -8841,7 +8812,6 @@ DEALINGS IN THE SOFTWARE.
---------------------------------------------------------
time 0.1.44 - MIT/Apache-2.0
time 0.3.21 - MIT OR Apache-2.0
https://github.com/time-rs/time
@@ -9136,31 +9106,25 @@ DEALINGS IN THE SOFTWARE.
toml 0.5.9 - MIT/Apache-2.0
https://github.com/toml-rs/toml
Copyright (c) 2014 Alex Crichton
Copyright (c) Individual contributors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---------------------------------------------------------
---------------------------------------------------------
@@ -9357,7 +9321,7 @@ THE SOFTWARE.
---------------------------------------------------------
tunnels 2621784a9ad72aa39500372391332a14bad581a3
tunnels 3141ad7be00e18c4231f7c4fb6c11f9219ac49af
https://github.com/microsoft/dev-tunnels
MIT License
@@ -9852,7 +9816,6 @@ THE SOFTWARE.
---------------------------------------------------------
wasi 0.10.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT
wasi 0.11.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT
wasi 0.9.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT
https://github.com/bytecodealliance/wasi
@@ -10272,6 +10235,34 @@ SOFTWARE.
---------------------------------------------------------
windows 0.48.0 - MIT OR Apache-2.0
https://github.com/microsoft/windows-rs
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
---------------------------------------------------------
---------------------------------------------------------
windows-sys 0.36.1 - MIT OR Apache-2.0
windows-sys 0.45.0 - MIT OR Apache-2.0
windows-sys 0.48.0 - MIT OR Apache-2.0
+3
View File
@@ -52,6 +52,7 @@ const VERSION: &str = concatcp!(NUMBER_IN_VERSION, " (commit ", COMMIT_IN_VERSIO
#[clap(
help_template = INTEGRATED_TEMPLATE,
long_about = None,
name = constants::APPLICATION_NAME,
version = VERSION,
)]
pub struct IntegratedCli {
@@ -84,6 +85,7 @@ pub struct CliCore {
help_template = STANDALONE_TEMPLATE,
long_about = None,
version = VERSION,
name = constants::APPLICATION_NAME,
)]
pub struct StandaloneCli {
#[clap(flatten)]
@@ -173,6 +175,7 @@ pub enum Commands {
Version(VersionArgs),
/// Runs a local web version of VS Code.
#[clap(about = concatcp!("Runs a local web version of ", constants::PRODUCT_NAME_LONG))]
ServeWeb(ServeWebArgs),
/// Runs the control server on process stdin/stdout
+179 -18
View File
@@ -10,6 +10,7 @@ use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use const_format::concatcp;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};
use tokio::io::{AsyncBufReadExt, BufReader};
@@ -23,6 +24,8 @@ use crate::constants::VSCODE_CLI_QUALITY;
use crate::download_cache::DownloadCache;
use crate::log;
use crate::options::Quality;
use crate::state::{LauncherPaths, PersistedState};
use crate::tunnels::shutdown_signal::ShutdownRequest;
use crate::update_service::{
unzip_downloaded_release, Platform, Release, TargetKind, UpdateService,
};
@@ -48,6 +51,22 @@ const SERVER_ACTIVE_TIMEOUT_SECS: u64 = SERVER_IDLE_TIMEOUT_SECS * 24 * 30 * 12;
/// How long to cache the "latest" version we get from the update service.
const RELEASE_CACHE_SECS: u64 = 60 * 60;
/// Number of bytes for the secret keys. See workbench.ts for their usage.
const SECRET_KEY_BYTES: usize = 32;
/// Path to mint the key combining server and client parts.
const SECRET_KEY_MINT_PATH: &str = "/_vscode-cli/mint-key";
/// Cookie set to the `SECRET_KEY_MINT_PATH`
const PATH_COOKIE_NAME: &str = "vscode-secret-key-path";
/// Cookie set to the `SECRET_KEY_MINT_PATH`
const PATH_COOKIE_VALUE: &str = concatcp!(
PATH_COOKIE_NAME,
"=",
SECRET_KEY_MINT_PATH,
"; SameSite=Strict; Path=/"
);
/// HTTP-only cookie where the client's secret half is stored.
const SECRET_KEY_COOKIE_NAME: &str = "vscode-cli-secret-half";
/// Implements the vscode "server of servers". Clients who go to the URI get
/// served the latest version of the VS Code server whenever they load the
/// page. The VS Code server prefixes all assets and connections it loads with
@@ -69,19 +88,31 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result<i3
}
let cm = ConnectionManager::new(&ctx, platform, args.clone());
let key = get_server_key_half(&ctx.paths);
let make_svc = move || {
let cm = cm.clone();
let log = cm.log.clone();
let service = service_fn(move |req| handle(cm.clone(), log.clone(), req));
let ctx = HandleContext {
cm: cm.clone(),
log: cm.log.clone(),
server_secret_key: key.clone(),
};
let service = service_fn(move |req| handle(ctx.clone(), req));
async move { Ok::<_, Infallible>(service) }
};
let mut shutdown = ShutdownRequest::create_rx([ShutdownRequest::CtrlC]);
let r = if let Some(s) = args.socket_path {
let socket = listen_socket_rw_stream(&PathBuf::from(&s)).await?;
ctx.log.result(format!("Web UI available on {}", s));
Server::builder(socket.into_pollable())
let s = PathBuf::from(&s);
let socket = listen_socket_rw_stream(&s).await?;
ctx.log
.result(format!("Web UI available on {}", s.display()));
let r = Server::builder(socket.into_pollable())
.serve(make_service_fn(|_| make_svc()))
.await
.with_graceful_shutdown(async {
let _ = shutdown.wait().await;
})
.await;
let _ = std::fs::remove_file(&s); // cleanup
r
} else {
let addr: SocketAddr = match &args.host {
Some(h) => {
@@ -98,6 +129,9 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result<i3
Server::bind(&addr)
.serve(make_service_fn(|_| make_svc()))
.with_graceful_shutdown(async {
let _ = shutdown.wait().await;
})
.await
};
@@ -106,35 +140,82 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result<i3
Ok(0)
}
/// Handler function for an inbound request
async fn handle(
#[derive(Clone)]
struct HandleContext {
cm: Arc<ConnectionManager>,
log: log::Logger,
req: Request<Body>,
) -> Result<Response<Body>, Infallible> {
let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), cm.platform) {
server_secret_key: SecretKeyPart,
}
/// Handler function for an inbound request
async fn handle(ctx: HandleContext, req: Request<Body>) -> Result<Response<Body>, Infallible> {
let client_key_half = get_client_key_half(&req);
let mut res = match req.uri().path() {
SECRET_KEY_MINT_PATH => handle_secret_mint(ctx, req),
_ => handle_proxied(ctx, req).await,
};
append_secret_headers(&mut res, &client_key_half);
Ok(res)
}
async fn handle_proxied(ctx: HandleContext, req: Request<Body>) -> Response<Body> {
let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), ctx.cm.platform) {
r
} else {
match cm.get_latest_release().await {
match ctx.cm.get_latest_release().await {
Ok(r) => r,
Err(e) => {
error!(log, "error getting latest version: {}", e);
return Ok(response::code_err(e));
error!(ctx.log, "error getting latest version: {}", e);
return response::code_err(e);
}
}
};
Ok(match cm.get_connection(release).await {
match ctx.cm.get_connection(release).await {
Ok(rw) => {
if req.headers().contains_key(hyper::header::UPGRADE) {
forward_ws_req_to_server(cm.log.clone(), rw, req).await
forward_ws_req_to_server(ctx.log.clone(), rw, req).await
} else {
forward_http_req_to_server(rw, req).await
}
}
Err(CodeError::ServerNotYetDownloaded) => response::wait_for_download(),
Err(e) => response::code_err(e),
})
}
}
fn handle_secret_mint(ctx: HandleContext, req: Request<Body>) -> Response<Body> {
use sha2::{Digest, Sha256};
let mut hasher = Sha256::new();
hasher.update(ctx.server_secret_key.0.as_ref());
hasher.update(get_client_key_half(&req).0.as_ref());
let hash = hasher.finalize();
let hash = hash[..SECRET_KEY_BYTES].to_vec();
response::secret_key(hash)
}
/// Appends headers to response to maintain the secret storage of the workbench:
/// sets the `PATH_COOKIE_VALUE` so workbench.ts knows about the 'mint' endpoint,
/// and maintains the http-only cookie the client will use for cookies.
fn append_secret_headers(res: &mut Response<Body>, client_key_half: &SecretKeyPart) {
let headers = res.headers_mut();
headers.append(
hyper::header::SET_COOKIE,
PATH_COOKIE_VALUE.parse().unwrap(),
);
headers.append(
hyper::header::SET_COOKIE,
format!(
"{}={}; SameSite=Strict; HttpOnly; Max-Age=2592000; Path=/",
SECRET_KEY_COOKIE_NAME,
client_key_half.encode()
)
.parse()
.unwrap(),
);
}
/// Gets the release info from the VS Code path prefix, which is in the
@@ -258,6 +339,77 @@ fn is_commit_hash(s: &str) -> bool {
s.len() == COMMIT_HASH_LEN && s.chars().all(|c| c.is_ascii_hexdigit())
}
/// Gets a cookie from the request by name.
fn extract_cookie(req: &Request<Body>, name: &str) -> Option<String> {
for h in req.headers().get_all(hyper::header::COOKIE) {
if let Ok(str) = h.to_str() {
for pair in str.split("; ") {
let i = match pair.find('=') {
Some(i) => i,
None => continue,
};
if &pair[..i] == name {
return Some(pair[i + 1..].to_string());
}
}
}
}
None
}
#[derive(Clone)]
struct SecretKeyPart(Box<[u8; SECRET_KEY_BYTES]>);
impl SecretKeyPart {
pub fn new() -> Self {
let key: [u8; SECRET_KEY_BYTES] = rand::random();
Self(Box::new(key))
}
pub fn decode(s: &str) -> Result<Self, base64::DecodeSliceError> {
use base64::{engine::general_purpose, Engine as _};
let mut key: [u8; SECRET_KEY_BYTES] = [0; SECRET_KEY_BYTES];
let v = general_purpose::URL_SAFE.decode(s)?;
if v.len() != SECRET_KEY_BYTES {
return Err(base64::DecodeSliceError::OutputSliceTooSmall);
}
key.copy_from_slice(&v);
Ok(Self(Box::new(key)))
}
pub fn encode(&self) -> String {
use base64::{engine::general_purpose, Engine as _};
general_purpose::URL_SAFE.encode(self.0.as_ref())
}
}
/// Gets the server's half of the secret key.
fn get_server_key_half(paths: &LauncherPaths) -> SecretKeyPart {
let ps = PersistedState::new(paths.root().join("serve-web-key-half"));
let value: String = ps.load();
if let Ok(sk) = SecretKeyPart::decode(&value) {
return sk;
}
let key = SecretKeyPart::new();
let _ = ps.save(key.encode());
key
}
/// Gets the client's half of the secret key.
fn get_client_key_half(req: &Request<Body>) -> SecretKeyPart {
if let Some(c) = extract_cookie(req, SECRET_KEY_COOKIE_NAME) {
if let Ok(sk) = SecretKeyPart::decode(&c) {
return sk;
}
}
SecretKeyPart::new()
}
/// Module holding original responses the CLI's server makes.
mod response {
use const_format::concatcp;
@@ -287,6 +439,14 @@ mod response {
.body(Body::from(concatcp!("The latest version of the ", QUALITYLESS_SERVER_NAME, " is downloading, please wait a moment...<script>setTimeout(()=>location.reload(),1500)</script>", )))
.unwrap()
}
pub fn secret_key(hash: Vec<u8>) -> Response<Body> {
Response::builder()
.status(200)
.header("Content-Type", "application/octet-stream") // todo: get latest
.body(Body::from(hash))
.unwrap()
}
}
/// Handle returned when getting a stream to the server, used to refcount
@@ -515,6 +675,7 @@ impl ConnectionManager {
let executable = path
.join("bin")
.join(args.release.quality.server_entrypoint());
let socket_path = get_socket_name();
#[cfg(not(windows))]
+2 -2
View File
@@ -323,8 +323,8 @@ fn format(level: Level, prefix: &str, message: &str, use_colors: bool) -> String
}
pub fn emit(level: Level, prefix: &str, message: &str) {
let line = format(level, prefix, message, true);
if level == Level::Trace {
let line = format(level, prefix, message, *COLORS_ENABLED);
if level == Level::Trace && *COLORS_ENABLED {
print!("\x1b[2m{}\x1b[0m", line);
} else {
print!("{}", line);
+18 -6
View File
@@ -14,7 +14,7 @@ use crate::tunnels::paths::{get_server_folder_name, SERVER_FOLDER_NAME};
use crate::update_service::{
unzip_downloaded_release, Platform, Release, TargetKind, UpdateService,
};
use crate::util::command::{capture_command, kill_tree};
use crate::util::command::{capture_command, capture_command_and_check_status, kill_tree};
use crate::util::errors::{wrap, AnyError, CodeError, ExtensionInstallFailed, WrappedError};
use crate::util::http::{self, BoxedHttp};
use crate::util::io::SilentCopyProgress;
@@ -416,11 +416,23 @@ impl<'a> ServerBuilder<'a> {
)
.await?;
unzip_downloaded_release(
&archive_path,
&target_dir.join(SERVER_FOLDER_NAME),
SilentCopyProgress(),
)?;
let server_dir = target_dir.join(SERVER_FOLDER_NAME);
unzip_downloaded_release(&archive_path, &server_dir, SilentCopyProgress())?;
let output = capture_command_and_check_status(
server_dir
.join("bin")
.join(self.server_params.release.quality.server_entrypoint()),
&["--version"],
)
.await
.map_err(|e| wrap(e, "error checking server integrity"))?;
trace!(
self.logger,
"Server integrity verified, version: {}",
String::from_utf8_lossy(&output.stdout).replace('\n', " / ")
);
Ok(())
})
+3
View File
@@ -1021,6 +1021,9 @@ where
p.current_dir(cwd);
}
#[cfg(target_os = "windows")]
p.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW);
let mut p = p.spawn().map_err(CodeError::ProcessSpawnFailed)?;
let futs = FuturesUnordered::new();
+8 -5
View File
@@ -212,6 +212,7 @@ impl ActiveTunnel {
const VSCODE_CLI_TUNNEL_TAG: &str = "vscode-server-launcher";
const VSCODE_CLI_FORWARDING_TAG: &str = "vscode-port-forward";
const OWNED_TUNNEL_TAGS: &[&str] = &[VSCODE_CLI_TUNNEL_TAG, VSCODE_CLI_FORWARDING_TAG];
const MAX_TUNNEL_NAME_LENGTH: usize = 20;
fn get_host_token_from_tunnel(tunnel: &Tunnel) -> String {
@@ -635,7 +636,7 @@ impl DevTunnels {
"Tunnel limit hit, trying to recycle an old tunnel"
);
let existing_tunnels = self.list_all_server_tunnels().await?;
let existing_tunnels = self.list_tunnels_with_tag(OWNED_TUNNEL_TAGS).await?;
let recyclable = existing_tunnels
.iter()
@@ -667,13 +668,15 @@ impl DevTunnels {
}
}
async fn list_all_server_tunnels(&mut self) -> Result<Vec<Tunnel>, AnyError> {
async fn list_tunnels_with_tag(
&mut self,
tags: &[&'static str],
) -> Result<Vec<Tunnel>, AnyError> {
let tunnels = spanf!(
self.log,
self.log.span("dev-tunnel.listall"),
self.client.list_all_tunnels(&TunnelRequestOptions {
tags: vec![self.tag.to_string()],
require_all_tags: true,
tags: tags.iter().map(|t| t.to_string()).collect(),
..Default::default()
})
)
@@ -711,7 +714,7 @@ impl DevTunnels {
preferred_name: Option<&str>,
mut use_random_name: bool,
) -> Result<String, AnyError> {
let existing_tunnels = self.list_all_server_tunnels().await?;
let existing_tunnels = self.list_tunnels_with_tag(&[self.tag]).await?;
let is_name_free = |n: &str| {
!existing_tunnels.iter().any(|v| {
v.status
File diff suppressed because one or more lines are too long
@@ -994,7 +994,7 @@
]
},
"dependencies": {
"vscode-languageclient": "^8.2.0-next.1",
"vscode-languageclient": "^8.2.0-next.3",
"vscode-uri": "^3.0.7"
},
"devDependencies": {
@@ -10,9 +10,9 @@
"main": "./out/node/cssServerMain",
"browser": "./dist/browser/cssServerMain",
"dependencies": {
"@vscode/l10n": "^0.0.14",
"vscode-css-languageservice": "^6.2.6",
"vscode-languageserver": "^8.2.0-next.1",
"@vscode/l10n": "^0.0.16",
"vscode-css-languageservice": "^6.2.7",
"vscode-languageserver": "^8.2.0-next.3",
"vscode-uri": "^3.0.7"
},
"devDependencies": {
@@ -12,55 +12,55 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
"@vscode/l10n@^0.0.14":
version "0.0.14"
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.14.tgz#431e5814c35c3cb11ee21873bc70a4b0fbf90fcf"
integrity sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg==
"@vscode/l10n@^0.0.16":
version "0.0.16"
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.16.tgz#f075db346d0b08419a12540171b230bd803c42be"
integrity sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg==
vscode-css-languageservice@^6.2.6:
version "6.2.6"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.6.tgz#bc26c2abaaa2eb117b143fdb9387ee1701d9661a"
integrity sha512-SA2WkeOecIpUiEbZnjOsP/fI5CRITZEiQGSHXKiDQDwLApfKcnLhZwMtOBbIifSzESVcQa7b/shX/nbnF4NoCg==
vscode-css-languageservice@^6.2.7:
version "6.2.7"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.7.tgz#d64e347e9a432d2b9c1a12d1ea5bc77996a2e9dc"
integrity sha512-Jd8wpIg5kJ15CfrieoEPvu3gGFc36sbM3qXCtjVq5zrnLEX5NhHxikMDtf8AgQsYklXiDqiZLKoBnzkJtRbTHQ==
dependencies:
"@vscode/l10n" "^0.0.14"
"@vscode/l10n" "^0.0.16"
vscode-languageserver-textdocument "^1.0.8"
vscode-languageserver-types "^3.17.3"
vscode-uri "^3.0.7"
vscode-jsonrpc@8.2.0-next.0:
version "8.2.0-next.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c"
integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg==
vscode-jsonrpc@8.2.0-next.2:
version "8.2.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68"
integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A==
vscode-languageserver-protocol@3.17.4-next.1:
version "3.17.4-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616"
integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg==
vscode-languageserver-protocol@3.17.4-next.3:
version "3.17.4-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c"
integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ==
dependencies:
vscode-jsonrpc "8.2.0-next.0"
vscode-languageserver-types "3.17.4-next.0"
vscode-jsonrpc "8.2.0-next.2"
vscode-languageserver-types "3.17.4-next.2"
vscode-languageserver-textdocument@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0"
integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==
vscode-languageserver-types@3.17.4-next.0:
version "3.17.4-next.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2"
integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag==
vscode-languageserver-types@3.17.4-next.2:
version "3.17.4-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d"
integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A==
vscode-languageserver-types@^3.17.3:
version "3.17.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64"
integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==
vscode-languageserver@^8.2.0-next.1:
version "8.2.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.1.tgz#ad2558d74392b1cfaccd427febe9a368fc328f8b"
integrity sha512-994AXMKBijzjlnpf8p9M+ntsNJDjR8pr55NJPYxKjy/nUhVkg962dAomelH6Z94401kBZmSbfP/K/20cB54aFA==
vscode-languageserver@^8.2.0-next.3:
version "8.2.0-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.3.tgz#72e4998392260173fb0c35d2d556fb4015f56ce3"
integrity sha512-fqHRwcIRoxfKke7iLDSeUmdo3uk7o/uWNn/44xdWa4urdhsvpTZ5c1GsL1EX4TAvdDg0qeXy89NBZ5Gld2DkgQ==
dependencies:
vscode-languageserver-protocol "3.17.4-next.1"
vscode-languageserver-protocol "3.17.4-next.3"
vscode-uri@^3.0.7:
version "3.0.7"
+19 -19
View File
@@ -40,32 +40,32 @@ semver@^7.3.7:
dependencies:
lru-cache "^6.0.0"
vscode-jsonrpc@8.2.0-next.0:
version "8.2.0-next.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c"
integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg==
vscode-jsonrpc@8.2.0-next.2:
version "8.2.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68"
integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A==
vscode-languageclient@^8.2.0-next.1:
version "8.2.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.1.tgz#a3f98b80cfa3225fde0583aa6a5c9b20219fa37e"
integrity sha512-oITaqHQ10PM3zXCUu/104wriMeDutXMkQXMaRBWh1jKihcNcUBLC/os7RhqiVGypY0nl+F0pwStAf4Koc8inaw==
vscode-languageclient@^8.2.0-next.3:
version "8.2.0-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.3.tgz#a5086f451a679ce77106d8fd1e05c8cbf8e9b886"
integrity sha512-Ojo6L2cb7GSiyD864k8vGb9fHxBdZeciHQQOF595C3IDHWg0w4KQ7iN7qGWVdl4wDNwlGTX3wWZawGfPTxnrPQ==
dependencies:
minimatch "^5.1.0"
semver "^7.3.7"
vscode-languageserver-protocol "3.17.4-next.1"
vscode-languageserver-protocol "3.17.4-next.3"
vscode-languageserver-protocol@3.17.4-next.1:
version "3.17.4-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616"
integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg==
vscode-languageserver-protocol@3.17.4-next.3:
version "3.17.4-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c"
integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ==
dependencies:
vscode-jsonrpc "8.2.0-next.0"
vscode-languageserver-types "3.17.4-next.0"
vscode-jsonrpc "8.2.0-next.2"
vscode-languageserver-types "3.17.4-next.2"
vscode-languageserver-types@3.17.4-next.0:
version "3.17.4-next.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2"
integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag==
vscode-languageserver-types@3.17.4-next.2:
version "3.17.4-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d"
integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A==
vscode-uri@^3.0.7:
version "3.0.7"
+5 -5
View File
@@ -2950,13 +2950,13 @@
{
"view": "scm",
"contents": "%view.workbench.scm.folder%",
"when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == folder && scmRepositoryCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'",
"when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == folder && scm.providerCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'",
"group": "5_scm@1"
},
{
"view": "scm",
"contents": "%view.workbench.scm.workspace%",
"when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == workspace && workspaceFolderCount != 0 && scmRepositoryCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'",
"when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == workspace && workspaceFolderCount != 0 && scm.providerCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'",
"group": "5_scm@1"
},
{
@@ -2992,13 +2992,13 @@
{
"view": "explorer",
"contents": "%view.workbench.cloneRepository%",
"when": "config.git.enabled && git.state == initialized && scmRepositoryCount == 0",
"when": "config.git.enabled && git.state == initialized && scm.providerCount == 0",
"group": "5_scm@1"
},
{
"view": "explorer",
"contents": "%view.workbench.learnMore%",
"when": "config.git.enabled && git.state == initialized && scmRepositoryCount == 0",
"when": "config.git.enabled && git.state == initialized && scm.providerCount == 0",
"group": "5_scm@10"
}
]
@@ -3012,7 +3012,7 @@
"jschardet": "3.0.0",
"picomatch": "2.3.1",
"vscode-uri": "^2.0.0",
"which": "3.0.1"
"which": "4.0.0"
},
"devDependencies": {
"@types/byline": "4.2.31",
+7 -2
View File
@@ -397,8 +397,8 @@ export class Git {
return Versions.compare(Versions.fromString(this.version), Versions.fromString(version));
}
open(repository: string, dotGit: { path: string; commonPath?: string }, logger: LogOutputChannel): Repository {
return new Repository(this, repository, dotGit, logger);
open(repositoryRoot: string, repositoryRootRealPath: string | undefined, dotGit: { path: string; commonPath?: string }, logger: LogOutputChannel): Repository {
return new Repository(this, repositoryRoot, repositoryRootRealPath, dotGit, logger);
}
async init(repository: string, options: InitOptions = {}): Promise<void> {
@@ -956,6 +956,7 @@ export class Repository {
constructor(
private _git: Git,
private repositoryRoot: string,
private repositoryRootRealPath: string | undefined,
readonly dotGit: { path: string; commonPath?: string },
private logger: LogOutputChannel
) { }
@@ -968,6 +969,10 @@ export class Repository {
return this.repositoryRoot;
}
get rootRealPath(): string | undefined {
return this.repositoryRootRealPath;
}
async exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
return await this.git.exec(this.repositoryRoot, args, options);
}
+29 -9
View File
@@ -577,8 +577,8 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
}
// Open repository
const dotGit = await this.git.getRepositoryDotGit(repositoryRoot);
const repository = new Repository(this.git.open(repositoryRoot, dotGit, this.logger), this, this, this, this, this.globalState, this.logger, this.telemetryReporter);
const [dotGit, repositoryRootRealPath] = await Promise.all([this.git.getRepositoryDotGit(repositoryRoot), this.getRepositoryRootRealPath(repositoryRoot)]);
const repository = new Repository(this.git.open(repositoryRoot, repositoryRootRealPath, dotGit, this.logger), this, this, this, this, this.globalState, this.logger, this.telemetryReporter);
this.open(repository);
this._closedRepositoriesManager.deleteRepository(repository.root);
@@ -615,6 +615,16 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
}
}
private async getRepositoryRootRealPath(repositoryRoot: string): Promise<string | undefined> {
try {
const repositoryRootRealPath = await fs.promises.realpath(repositoryRoot);
return !pathEquals(repositoryRoot, repositoryRootRealPath) ? repositoryRootRealPath : undefined;
} catch (err) {
this.logger.warn(`Failed to get repository realpath for: "${repositoryRoot}". ${err}`);
return undefined;
}
}
private shouldRepositoryBeIgnored(repositoryRoot: string): boolean {
const config = workspace.getConfiguration('git');
const ignoredRepos = config.get<string[]>('ignoredRepositories') || [];
@@ -766,15 +776,25 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu
}
private async getRepositoryExact(repoPath: string): Promise<Repository | undefined> {
const repoPathCanonical = await fs.promises.realpath(repoPath, { encoding: 'utf8' });
// Use the repository path
const openRepository = this.openRepositories
.find(r => pathEquals(r.repository.root, repoPath));
for (const openRepository of this.openRepositories) {
const rootPathCanonical = await fs.promises.realpath(openRepository.repository.root, { encoding: 'utf8' });
if (pathEquals(rootPathCanonical, repoPathCanonical)) {
return openRepository.repository;
}
if (openRepository) {
return openRepository.repository;
}
try {
// Use the repository real path
const repoPathRealPath = await fs.promises.realpath(repoPath, { encoding: 'utf8' });
const openRepositoryRealPath = this.openRepositories
.find(r => pathEquals(r.repository.rootRealPath ?? '', repoPathRealPath));
return openRepositoryRealPath?.repository;
} catch (err) {
this.logger.warn(`Failed to get repository realpath for: "${repoPath}". ${err}`);
return undefined;
}
return undefined;
}
private getOpenRepository(repository: Repository): OpenRepository | undefined;
+4
View File
@@ -765,6 +765,10 @@ export class Repository implements Disposable {
return this.repository.root;
}
get rootRealPath(): string | undefined {
return this.repository.rootRealPath;
}
get dotGit(): { path: string; commonPath?: string } {
return this.repository.dotGit;
}
+9 -9
View File
@@ -516,10 +516,10 @@ is-core-module@^2.13.0:
dependencies:
has "^1.0.3"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
isexe@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d"
integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==
jschardet@3.0.0:
version "3.0.0"
@@ -679,12 +679,12 @@ vscode-uri@^2.0.0:
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.0.tgz#2df704222f72b8a71ff266ba0830ed6c51ac1542"
integrity sha512-lWXWofDSYD8r/TIyu64MdwB4FaSirQ608PP/TzUyslyOeHGwQ0eTHUZeJrK1ILOmwUHaJtV693m2JoUYroUDpw==
which@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1"
integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==
which@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a"
integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==
dependencies:
isexe "^2.0.0"
isexe "^3.1.1"
yallist@^4.0.0:
version "4.0.0"
@@ -200,7 +200,9 @@ const allFlows: IFlow[] = [
// other flows that work well.
supportsGitHubEnterpriseServer: false,
supportsHostedGitHubEnterprise: true,
supportsRemoteExtensionHost: true,
// Opening a port on the remote side can't be open in the browser on
// the client side so this flow won't work in remote extension hosts
supportsRemoteExtensionHost: false,
// Web worker can't open a port to listen for the redirect
supportsWebWorkerExtensionHost: false,
// exchanging a code for a token requires a client secret
@@ -258,8 +258,8 @@
]
},
"dependencies": {
"@vscode/extension-telemetry": "^0.7.5",
"vscode-languageclient": "^8.2.0-next.1",
"@vscode/extension-telemetry": "^0.8.4",
"vscode-languageclient": "^8.2.0-next.3",
"vscode-uri": "^3.0.7"
},
"devDependencies": {
@@ -9,10 +9,10 @@
},
"main": "./out/node/htmlServerMain",
"dependencies": {
"@vscode/l10n": "^0.0.14",
"vscode-css-languageservice": "^6.2.6",
"vscode-html-languageservice": "^5.0.6",
"vscode-languageserver": "^8.2.0-next.1",
"@vscode/l10n": "^0.0.16",
"vscode-css-languageservice": "^6.2.7",
"vscode-html-languageservice": "^5.0.7",
"vscode-languageserver": "^8.2.0-next.3",
"vscode-languageserver-textdocument": "^1.0.8",
"vscode-uri": "^3.0.7"
},
@@ -12,65 +12,65 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
"@vscode/l10n@^0.0.14":
version "0.0.14"
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.14.tgz#431e5814c35c3cb11ee21873bc70a4b0fbf90fcf"
integrity sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg==
"@vscode/l10n@^0.0.16":
version "0.0.16"
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.16.tgz#f075db346d0b08419a12540171b230bd803c42be"
integrity sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg==
vscode-css-languageservice@^6.2.6:
version "6.2.6"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.6.tgz#bc26c2abaaa2eb117b143fdb9387ee1701d9661a"
integrity sha512-SA2WkeOecIpUiEbZnjOsP/fI5CRITZEiQGSHXKiDQDwLApfKcnLhZwMtOBbIifSzESVcQa7b/shX/nbnF4NoCg==
vscode-css-languageservice@^6.2.7:
version "6.2.7"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.7.tgz#d64e347e9a432d2b9c1a12d1ea5bc77996a2e9dc"
integrity sha512-Jd8wpIg5kJ15CfrieoEPvu3gGFc36sbM3qXCtjVq5zrnLEX5NhHxikMDtf8AgQsYklXiDqiZLKoBnzkJtRbTHQ==
dependencies:
"@vscode/l10n" "^0.0.14"
"@vscode/l10n" "^0.0.16"
vscode-languageserver-textdocument "^1.0.8"
vscode-languageserver-types "^3.17.3"
vscode-uri "^3.0.7"
vscode-html-languageservice@^5.0.6:
version "5.0.6"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-5.0.6.tgz#e7a7f78e9f98d0f5341c5518dd9305e3cc438bb6"
integrity sha512-gCixNg6fjPO7+kwSMBAVXcwDRHdjz1WOyNfI0n5Wx0J7dfHG8ggb3zD1FI8E2daTZrwS1cooOiSoc1Xxph4qRQ==
vscode-html-languageservice@^5.0.7:
version "5.0.7"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-5.0.7.tgz#8d27773e0197799a9db777ee4fc134cf1c669d84"
integrity sha512-jX+7/kUXrdOaRT8vqYR/jLxrGDib+Far8I7n/A6apuEl88k+mhIHZPwc6ezuLeiCKUCaLG4b0dqFwjVa7QL3/w==
dependencies:
"@vscode/l10n" "^0.0.14"
"@vscode/l10n" "^0.0.16"
vscode-languageserver-textdocument "^1.0.8"
vscode-languageserver-types "^3.17.3"
vscode-uri "^3.0.7"
vscode-jsonrpc@8.2.0-next.0:
version "8.2.0-next.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c"
integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg==
vscode-jsonrpc@8.2.0-next.2:
version "8.2.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68"
integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A==
vscode-languageserver-protocol@3.17.4-next.1:
version "3.17.4-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616"
integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg==
vscode-languageserver-protocol@3.17.4-next.3:
version "3.17.4-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c"
integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ==
dependencies:
vscode-jsonrpc "8.2.0-next.0"
vscode-languageserver-types "3.17.4-next.0"
vscode-jsonrpc "8.2.0-next.2"
vscode-languageserver-types "3.17.4-next.2"
vscode-languageserver-textdocument@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0"
integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==
vscode-languageserver-types@3.17.4-next.0:
version "3.17.4-next.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2"
integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag==
vscode-languageserver-types@3.17.4-next.2:
version "3.17.4-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d"
integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A==
vscode-languageserver-types@^3.17.3:
version "3.17.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64"
integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==
vscode-languageserver@^8.2.0-next.1:
version "8.2.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.1.tgz#ad2558d74392b1cfaccd427febe9a368fc328f8b"
integrity sha512-994AXMKBijzjlnpf8p9M+ntsNJDjR8pr55NJPYxKjy/nUhVkg962dAomelH6Z94401kBZmSbfP/K/20cB54aFA==
vscode-languageserver@^8.2.0-next.3:
version "8.2.0-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.3.tgz#72e4998392260173fb0c35d2d556fb4015f56ce3"
integrity sha512-fqHRwcIRoxfKke7iLDSeUmdo3uk7o/uWNn/44xdWa4urdhsvpTZ5c1GsL1EX4TAvdDg0qeXy89NBZ5Gld2DkgQ==
dependencies:
vscode-languageserver-protocol "3.17.4-next.1"
vscode-languageserver-protocol "3.17.4-next.3"
vscode-uri@^3.0.7:
version "3.0.7"
+296 -118
View File
@@ -17,7 +17,16 @@
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/core-rest-pipeline@^1.10.0":
"@azure/core-auth@^1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44"
integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-util" "^1.1.0"
tslib "^2.2.0"
"@azure/core-rest-pipeline@1.10.1":
version "1.10.1"
resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968"
integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==
@@ -33,13 +42,21 @@
tslib "^2.2.0"
uuid "^8.3.0"
"@azure/core-tracing@^1.0.1":
"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503"
integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==
dependencies:
tslib "^2.2.0"
"@azure/core-util@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392"
integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==
dependencies:
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/core-util@^1.0.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1"
@@ -48,6 +65,14 @@
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/core-util@^1.1.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7"
integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig==
dependencies:
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/logger@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96"
@@ -55,66 +80,100 @@
dependencies:
tslib "^2.2.0"
"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8":
version "3.2.8"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760"
integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ==
"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5":
version "1.0.0-beta.5"
resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb"
integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.9"
"@azure/core-tracing" "^1.0.0"
"@azure/logger" "^1.0.0"
"@opentelemetry/api" "^1.4.1"
"@opentelemetry/core" "^1.15.2"
"@opentelemetry/instrumentation" "^0.41.2"
tslib "^2.2.0"
"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb"
integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.15"
"@microsoft/applicationinsights-shims" "^2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/1ds-post-js@^3.2.8":
version "3.2.8"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110"
integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA==
"@microsoft/1ds-post-js@^3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa"
integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA==
dependencies:
"@microsoft/1ds-core-js" "3.2.8"
"@microsoft/1ds-core-js" "3.2.13"
"@microsoft/applicationinsights-shims" "^2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/applicationinsights-channel-js@2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb"
integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg==
"@microsoft/applicationinsights-channel-js@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5"
integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw==
dependencies:
"@microsoft/applicationinsights-common" "2.8.9"
"@microsoft/applicationinsights-core-js" "2.8.9"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/applicationinsights-common" "3.0.2"
"@microsoft/applicationinsights-core-js" "3.0.2"
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-async" ">= 0.2.4 < 2.x"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-common@2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827"
integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig==
"@microsoft/applicationinsights-common@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05"
integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.9"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/applicationinsights-core-js" "3.0.2"
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-core-js@2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b"
integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w==
"@microsoft/applicationinsights-core-js@2.8.15":
version "2.8.15"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8"
integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ==
dependencies:
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/dynamicproto-js" "^1.1.9"
"@microsoft/applicationinsights-core-js@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a"
integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ==
dependencies:
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-async" ">= 0.2.4 < 2.x"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085"
integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg==
"@microsoft/applicationinsights-web-basic@^2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5"
integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ==
"@microsoft/applicationinsights-shims@3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f"
integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==
dependencies:
"@microsoft/applicationinsights-channel-js" "2.8.9"
"@microsoft/applicationinsights-common" "2.8.9"
"@microsoft/applicationinsights-core-js" "2.8.9"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@nevware21/ts-utils" ">= 0.9.4 < 2.x"
"@microsoft/applicationinsights-web-basic@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a"
integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg==
dependencies:
"@microsoft/applicationinsights-channel-js" "3.0.2"
"@microsoft/applicationinsights-common" "3.0.2"
"@microsoft/applicationinsights-core-js" "3.0.2"
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-async" ">= 0.2.4 < 2.x"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-web-snippet@^1.0.1":
version "1.0.1"
@@ -126,39 +185,74 @@
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2"
integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA==
"@opentelemetry/api@^1.0.4":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686"
integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g==
"@microsoft/dynamicproto-js@^1.1.9":
version "1.1.9"
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6"
integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ==
"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c"
integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ==
"@microsoft/dynamicproto-js@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6"
integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg==
dependencies:
"@opentelemetry/semantic-conventions" "1.7.0"
"@nevware21/ts-utils" ">= 0.9.4 < 2.x"
"@opentelemetry/resources@1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5"
integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg==
"@nevware21/ts-async@>= 0.2.4 < 2.x":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c"
integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA==
dependencies:
"@opentelemetry/core" "1.7.0"
"@opentelemetry/semantic-conventions" "1.7.0"
"@nevware21/ts-utils" ">= 0.10.0 < 2.x"
"@opentelemetry/sdk-trace-base@^1.0.1":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5"
integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg==
"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x":
version "0.10.1"
resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7"
integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg==
"@opentelemetry/api@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f"
integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==
"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f"
integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw==
dependencies:
"@opentelemetry/core" "1.7.0"
"@opentelemetry/resources" "1.7.0"
"@opentelemetry/semantic-conventions" "1.7.0"
"@opentelemetry/semantic-conventions" "1.15.2"
"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763"
integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA==
"@opentelemetry/instrumentation@^0.41.2":
version "0.41.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f"
integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==
dependencies:
"@types/shimmer" "^1.0.2"
import-in-the-middle "1.4.2"
require-in-the-middle "^7.1.1"
semver "^7.5.1"
shimmer "^1.2.1"
"@opentelemetry/resources@1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d"
integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw==
dependencies:
"@opentelemetry/core" "1.15.2"
"@opentelemetry/semantic-conventions" "1.15.2"
"@opentelemetry/sdk-trace-base@^1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a"
integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ==
dependencies:
"@opentelemetry/core" "1.15.2"
"@opentelemetry/resources" "1.15.2"
"@opentelemetry/semantic-conventions" "1.15.2"
"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241"
integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw==
"@tootallnate/once@2":
version "2.0.0"
@@ -170,15 +264,30 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
"@vscode/extension-telemetry@^0.7.5":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b"
integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w==
"@types/shimmer@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f"
integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==
"@vscode/extension-telemetry@^0.8.4":
version "0.8.4"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7"
integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA==
dependencies:
"@microsoft/1ds-core-js" "^3.2.8"
"@microsoft/1ds-post-js" "^3.2.8"
"@microsoft/applicationinsights-web-basic" "^2.8.9"
applicationinsights "2.4.1"
"@microsoft/1ds-core-js" "^3.2.13"
"@microsoft/1ds-post-js" "^3.2.13"
"@microsoft/applicationinsights-web-basic" "^3.0.2"
applicationinsights "^2.7.1"
acorn-import-assertions@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac"
integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==
acorn@^8.8.2:
version "8.10.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
agent-base@6:
version "6.0.2"
@@ -187,22 +296,24 @@ agent-base@6:
dependencies:
debug "4"
applicationinsights@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d"
integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA==
applicationinsights@^2.7.1:
version "2.7.3"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5"
integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw==
dependencies:
"@azure/core-auth" "^1.4.0"
"@azure/core-rest-pipeline" "^1.10.0"
"@azure/core-auth" "^1.5.0"
"@azure/core-rest-pipeline" "1.10.1"
"@azure/core-util" "1.2.0"
"@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5"
"@microsoft/applicationinsights-web-snippet" "^1.0.1"
"@opentelemetry/api" "^1.0.4"
"@opentelemetry/core" "^1.0.1"
"@opentelemetry/sdk-trace-base" "^1.0.1"
"@opentelemetry/semantic-conventions" "^1.0.1"
"@opentelemetry/api" "^1.4.1"
"@opentelemetry/core" "^1.15.2"
"@opentelemetry/sdk-trace-base" "^1.15.2"
"@opentelemetry/semantic-conventions" "^1.15.2"
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "1.1.0"
diagnostic-channel-publishers "1.0.5"
diagnostic-channel "1.1.1"
diagnostic-channel-publishers "1.0.7"
async-hook-jl@^1.7.6:
version "1.7.6"
@@ -236,6 +347,11 @@ brace-expansion@^2.0.1:
dependencies:
balanced-match "^1.0.0"
cjs-module-lexer@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107"
integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
@@ -260,7 +376,7 @@ continuation-local-storage@^3.2.1:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
debug@4:
debug@4, debug@^4.1.1:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -272,17 +388,17 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
diagnostic-channel-publishers@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae"
integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg==
diagnostic-channel-publishers@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a"
integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg==
diagnostic-channel@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e"
integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ==
diagnostic-channel@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0"
integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==
dependencies:
semver "^5.3.0"
semver "^7.5.3"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
@@ -300,6 +416,18 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
http-proxy-agent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
@@ -317,6 +445,23 @@ https-proxy-agent@^5.0.0:
agent-base "6"
debug "4"
import-in-the-middle@1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b"
integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==
dependencies:
acorn "^8.8.2"
acorn-import-assertions "^1.9.0"
cjs-module-lexer "^1.2.2"
module-details-from-path "^1.0.3"
is-core-module@^2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
dependencies:
has "^1.0.3"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -343,24 +488,52 @@ minimatch@^5.1.0:
dependencies:
brace-expansion "^2.0.1"
module-details-from-path@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b"
integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
require-in-the-middle@^7.1.1:
version "7.2.0"
resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf"
integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==
dependencies:
debug "^4.1.1"
module-details-from-path "^1.0.3"
resolve "^1.22.1"
resolve@^1.22.1:
version "1.22.4"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34"
integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==
dependencies:
is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
semver@^5.3.0, semver@^5.4.1:
version "5.7.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
semver@^7.3.7:
semver@^7.3.7, semver@^7.5.1, semver@^7.5.3:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
shimmer@^1.1.0, shimmer@^1.2.0:
shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
@@ -370,6 +543,11 @@ stack-chain@^1.3.7:
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
tslib@^2.2.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
@@ -380,32 +558,32 @@ uuid@^8.3.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
vscode-jsonrpc@8.2.0-next.0:
version "8.2.0-next.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c"
integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg==
vscode-jsonrpc@8.2.0-next.2:
version "8.2.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68"
integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A==
vscode-languageclient@^8.2.0-next.1:
version "8.2.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.1.tgz#a3f98b80cfa3225fde0583aa6a5c9b20219fa37e"
integrity sha512-oITaqHQ10PM3zXCUu/104wriMeDutXMkQXMaRBWh1jKihcNcUBLC/os7RhqiVGypY0nl+F0pwStAf4Koc8inaw==
vscode-languageclient@^8.2.0-next.3:
version "8.2.0-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.3.tgz#a5086f451a679ce77106d8fd1e05c8cbf8e9b886"
integrity sha512-Ojo6L2cb7GSiyD864k8vGb9fHxBdZeciHQQOF595C3IDHWg0w4KQ7iN7qGWVdl4wDNwlGTX3wWZawGfPTxnrPQ==
dependencies:
minimatch "^5.1.0"
semver "^7.3.7"
vscode-languageserver-protocol "3.17.4-next.1"
vscode-languageserver-protocol "3.17.4-next.3"
vscode-languageserver-protocol@3.17.4-next.1:
version "3.17.4-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616"
integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg==
vscode-languageserver-protocol@3.17.4-next.3:
version "3.17.4-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c"
integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ==
dependencies:
vscode-jsonrpc "8.2.0-next.0"
vscode-languageserver-types "3.17.4-next.0"
vscode-jsonrpc "8.2.0-next.2"
vscode-languageserver-types "3.17.4-next.2"
vscode-languageserver-types@3.17.4-next.0:
version "3.17.4-next.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2"
integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag==
vscode-languageserver-types@3.17.4-next.2:
version "3.17.4-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d"
integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A==
vscode-uri@^3.0.7:
version "3.0.7"
+3 -3
View File
@@ -58,8 +58,8 @@
"title": "%cleanInvalidImageAttachment.title%"
},
{
"command": "notebook.cellOutput.copyToClipboard",
"title": "%copyOutputToClipboard.title%"
"command": "notebook.cellOutput.copy",
"title": "%copyCellOutput.title%"
}
],
"notebooks": [
@@ -106,7 +106,7 @@
],
"webview/context": [
{
"command": "notebook.cellOutput.copyToClipboard",
"command": "notebook.cellOutput.copy",
"when": "webviewId == 'notebook.output' && webviewSection == 'image'"
}
]
+1 -1
View File
@@ -6,7 +6,7 @@
"newUntitledIpynb.shortTitle": "Jupyter Notebook",
"openIpynbInNotebookEditor.title": "Open IPYNB File In Notebook Editor",
"cleanInvalidImageAttachment.title": "Clean Invalid Image Attachment Reference",
"copyOutputToClipboard.title": "Copy Output to Clipboard",
"copyCellOutput.title": "Copy Output",
"markdownAttachmentRenderer.displayName": {
"message": "Markdown-It ipynb Cell Attachment renderer",
"comment": [
@@ -8,7 +8,7 @@ export type JSONLanguageStatus = { schemas: string[] };
import {
workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation,
Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange,
ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, TextEditorOptions
ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n
} from 'vscode';
import {
LanguageClientOptions, RequestType, NotificationType, FormattingOptions as LSPFormattingOptions,
@@ -102,7 +102,6 @@ export type JSONSchemaSettings = {
export namespace SettingIds {
export const enableFormatter = 'json.format.enable';
export const enableKeepLines = 'json.format.keepLines';
export const enableSortOnSave = 'json.sortOnSave.enable';
export const enableValidation = 'json.validate.enable';
export const enableSchemaDownload = 'json.schemaDownload.enable';
export const maxItemsComputed = 'json.maxItemsComputed';
@@ -171,15 +170,6 @@ export async function startClient(context: ExtensionContext, newLanguageClient:
window.showInformationMessage(l10n.t('JSON schema cache cleared.'));
}));
toDispose.push(workspace.onWillSaveTextDocument(event => {
const sortOnSave = workspace.getConfiguration().get<boolean>(SettingIds.enableSortOnSave);
const document = event.document;
if (sortOnSave && (document.languageId === 'json' || document.languageId === 'jsonc')) {
const documentOptions = getOptionsForDocument(document);
const textEditsPromise = getSortTextEdits(document, documentOptions?.tabSize, documentOptions?.insertSpaces);
event.waitUntil(textEditsPromise);
}
}));
toDispose.push(commands.registerCommand('json.sort', async () => {
@@ -643,12 +633,3 @@ function updateMarkdownString(h: MarkdownString): MarkdownString {
function isSchemaResolveError(d: Diagnostic) {
return d.code === /* SchemaResolveError */ 0x300;
}
function getOptionsForDocument(document: TextDocument): TextEditorOptions | undefined {
for (const editor of window.visibleTextEditors) {
if (editor.document.uri.toString() === document.uri.toString()) {
return editor.options;
}
}
return;
}
@@ -91,12 +91,6 @@
"default": false,
"description": "%json.format.keepLines.desc%"
},
"json.sortOnSave.enable": {
"type": "boolean",
"scope": "window",
"default": false,
"description": "%json.sortOnSave.enable.desc%"
},
"json.trace.server": {
"type": "string",
"scope": "window",
@@ -164,9 +158,9 @@
]
},
"dependencies": {
"@vscode/extension-telemetry": "^0.7.5",
"@vscode/extension-telemetry": "^0.8.4",
"request-light": "^0.7.0",
"vscode-languageclient": "^8.2.0-next.1"
"vscode-languageclient": "^8.2.0-next.3"
},
"devDependencies": {
"@types/node": "18.x"
@@ -8,7 +8,6 @@
"json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.",
"json.format.enable.desc": "Enable/disable default JSON formatter",
"json.format.keepLines.desc" : "Keep all existing new lines when formatting.",
"json.sortOnSave.enable.desc": "Enable/disable default sorting on save",
"json.validate.enable.desc": "Enable/disable JSON validation.",
"json.tracing.desc": "Traces the communication between VS Code and the JSON language server.",
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
@@ -12,11 +12,11 @@
},
"main": "./out/node/jsonServerMain",
"dependencies": {
"@vscode/l10n": "^0.0.14",
"@vscode/l10n": "^0.0.16",
"jsonc-parser": "^3.2.0",
"request-light": "^0.7.0",
"vscode-json-languageservice": "^5.3.5",
"vscode-languageserver": "^8.2.0-next.1",
"vscode-json-languageservice": "^5.3.6",
"vscode-languageserver": "^8.2.0-next.3",
"vscode-uri": "^3.0.7"
},
"devDependencies": {
@@ -6,7 +6,7 @@
import {
Connection,
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic, CodeAction, CodeActionKind
} from 'vscode-languageserver';
import { runSafe, runSafeAsync } from './utils/runner';
@@ -14,6 +14,7 @@ import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnostics
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position, SortOptions } from 'vscode-json-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import { Utils, URI } from 'vscode-uri';
import * as l10n from '@vscode/l10n';
type ISchemaAssociations = Record<string, string[]>;
@@ -188,7 +189,8 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
documentSelector: null,
interFileDependencies: false,
workspaceDiagnostics: false
}
},
codeActionProvider: true
};
return { capabilities };
@@ -424,6 +426,21 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
}, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token);
});
connection.onCodeAction((codeActionParams, token) => {
return runSafeAsync(runtime, async () => {
const document = documents.get(codeActionParams.textDocument.uri);
if (document) {
const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source.concat('.sort', '.json'));
sortCodeAction.command = {
command: 'json.sort',
title: l10n.t('Sort JSON')
};
return [sortCodeAction];
}
return [];
}, [], `Error while computing code actions for ${codeActionParams.textDocument.uri}`, token);
});
function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] {
options.keepLines = keepLinesEnabled;
@@ -12,15 +12,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
"@vscode/l10n@^0.0.13":
version "0.0.13"
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.13.tgz#f51ff130b8c98f189476c5f812d214b8efb09590"
integrity sha512-A3uY356uOU9nGa+TQIT/i3ziWUgJjVMUrGGXSrtRiTwklyCFjGVWIOHoEIHbJpiyhDkJd9kvIWUOfXK1IkK8XQ==
"@vscode/l10n@^0.0.14":
version "0.0.14"
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.14.tgz#431e5814c35c3cb11ee21873bc70a4b0fbf90fcf"
integrity sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg==
"@vscode/l10n@^0.0.16":
version "0.0.16"
resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.16.tgz#f075db346d0b08419a12540171b230bd803c42be"
integrity sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg==
jsonc-parser@^3.2.0:
version "3.2.0"
@@ -32,51 +27,51 @@ request-light@^0.7.0:
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a"
integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==
vscode-json-languageservice@^5.3.5:
version "5.3.5"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.3.5.tgz#20acd827e13ea4bdeb9976df84ec2bfbb2452c73"
integrity sha512-DasT+bKtpaS2rTPEB4VMROnvO1WES2KD8RZZxXbumnk9sk5wco10VdB6sJgTlsKQN14tHQLZDXuHnSoSAlE8LQ==
vscode-json-languageservice@^5.3.6:
version "5.3.6"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.3.6.tgz#8cbe39dfdf29e7f7e97c9b6966b76031991290f6"
integrity sha512-P4kthBi3GMLKi7Lmp24nkKHAWxbFfCsIDBPlMrK1Tag1aqbl3l60UferDkfAasupDVBM2dekbArzGycUjw8OHA==
dependencies:
"@vscode/l10n" "^0.0.13"
"@vscode/l10n" "^0.0.16"
jsonc-parser "^3.2.0"
vscode-languageserver-textdocument "^1.0.8"
vscode-languageserver-types "^3.17.3"
vscode-uri "^3.0.7"
vscode-jsonrpc@8.2.0-next.0:
version "8.2.0-next.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c"
integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg==
vscode-jsonrpc@8.2.0-next.2:
version "8.2.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68"
integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A==
vscode-languageserver-protocol@3.17.4-next.1:
version "3.17.4-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616"
integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg==
vscode-languageserver-protocol@3.17.4-next.3:
version "3.17.4-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c"
integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ==
dependencies:
vscode-jsonrpc "8.2.0-next.0"
vscode-languageserver-types "3.17.4-next.0"
vscode-jsonrpc "8.2.0-next.2"
vscode-languageserver-types "3.17.4-next.2"
vscode-languageserver-textdocument@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0"
integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==
vscode-languageserver-types@3.17.4-next.0:
version "3.17.4-next.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2"
integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag==
vscode-languageserver-types@3.17.4-next.2:
version "3.17.4-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d"
integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A==
vscode-languageserver-types@^3.17.3:
version "3.17.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64"
integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA==
vscode-languageserver@^8.2.0-next.1:
version "8.2.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.1.tgz#ad2558d74392b1cfaccd427febe9a368fc328f8b"
integrity sha512-994AXMKBijzjlnpf8p9M+ntsNJDjR8pr55NJPYxKjy/nUhVkg962dAomelH6Z94401kBZmSbfP/K/20cB54aFA==
vscode-languageserver@^8.2.0-next.3:
version "8.2.0-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.3.tgz#72e4998392260173fb0c35d2d556fb4015f56ce3"
integrity sha512-fqHRwcIRoxfKke7iLDSeUmdo3uk7o/uWNn/44xdWa4urdhsvpTZ5c1GsL1EX4TAvdDg0qeXy89NBZ5Gld2DkgQ==
dependencies:
vscode-languageserver-protocol "3.17.4-next.1"
vscode-languageserver-protocol "3.17.4-next.3"
vscode-uri@^3.0.7:
version "3.0.7"
+296 -118
View File
@@ -17,7 +17,16 @@
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/core-rest-pipeline@^1.10.0":
"@azure/core-auth@^1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44"
integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw==
dependencies:
"@azure/abort-controller" "^1.0.0"
"@azure/core-util" "^1.1.0"
tslib "^2.2.0"
"@azure/core-rest-pipeline@1.10.1":
version "1.10.1"
resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968"
integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA==
@@ -33,13 +42,21 @@
tslib "^2.2.0"
uuid "^8.3.0"
"@azure/core-tracing@^1.0.1":
"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503"
integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==
dependencies:
tslib "^2.2.0"
"@azure/core-util@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392"
integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng==
dependencies:
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/core-util@^1.0.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1"
@@ -48,6 +65,14 @@
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/core-util@^1.1.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7"
integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig==
dependencies:
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/logger@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96"
@@ -55,66 +80,100 @@
dependencies:
tslib "^2.2.0"
"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8":
version "3.2.8"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760"
integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ==
"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5":
version "1.0.0-beta.5"
resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb"
integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.9"
"@azure/core-tracing" "^1.0.0"
"@azure/logger" "^1.0.0"
"@opentelemetry/api" "^1.4.1"
"@opentelemetry/core" "^1.15.2"
"@opentelemetry/instrumentation" "^0.41.2"
tslib "^2.2.0"
"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb"
integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.15"
"@microsoft/applicationinsights-shims" "^2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/1ds-post-js@^3.2.8":
version "3.2.8"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110"
integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA==
"@microsoft/1ds-post-js@^3.2.13":
version "3.2.13"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa"
integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA==
dependencies:
"@microsoft/1ds-core-js" "3.2.8"
"@microsoft/1ds-core-js" "3.2.13"
"@microsoft/applicationinsights-shims" "^2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/applicationinsights-channel-js@2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb"
integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg==
"@microsoft/applicationinsights-channel-js@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5"
integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw==
dependencies:
"@microsoft/applicationinsights-common" "2.8.9"
"@microsoft/applicationinsights-core-js" "2.8.9"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/applicationinsights-common" "3.0.2"
"@microsoft/applicationinsights-core-js" "3.0.2"
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-async" ">= 0.2.4 < 2.x"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-common@2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827"
integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig==
"@microsoft/applicationinsights-common@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05"
integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.9"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/applicationinsights-core-js" "3.0.2"
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-core-js@2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b"
integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w==
"@microsoft/applicationinsights-core-js@2.8.15":
version "2.8.15"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8"
integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ==
dependencies:
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/dynamicproto-js" "^1.1.9"
"@microsoft/applicationinsights-core-js@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a"
integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ==
dependencies:
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-async" ">= 0.2.4 < 2.x"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085"
integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg==
"@microsoft/applicationinsights-web-basic@^2.8.9":
version "2.8.9"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5"
integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ==
"@microsoft/applicationinsights-shims@3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f"
integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==
dependencies:
"@microsoft/applicationinsights-channel-js" "2.8.9"
"@microsoft/applicationinsights-common" "2.8.9"
"@microsoft/applicationinsights-core-js" "2.8.9"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@nevware21/ts-utils" ">= 0.9.4 < 2.x"
"@microsoft/applicationinsights-web-basic@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a"
integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg==
dependencies:
"@microsoft/applicationinsights-channel-js" "3.0.2"
"@microsoft/applicationinsights-common" "3.0.2"
"@microsoft/applicationinsights-core-js" "3.0.2"
"@microsoft/applicationinsights-shims" "3.0.1"
"@microsoft/dynamicproto-js" "^2.0.2"
"@nevware21/ts-async" ">= 0.2.4 < 2.x"
"@nevware21/ts-utils" ">= 0.9.5 < 2.x"
"@microsoft/applicationinsights-web-snippet@^1.0.1":
version "1.0.1"
@@ -126,39 +185,74 @@
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2"
integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA==
"@opentelemetry/api@^1.0.4":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686"
integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g==
"@microsoft/dynamicproto-js@^1.1.9":
version "1.1.9"
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6"
integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ==
"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c"
integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ==
"@microsoft/dynamicproto-js@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6"
integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg==
dependencies:
"@opentelemetry/semantic-conventions" "1.7.0"
"@nevware21/ts-utils" ">= 0.9.4 < 2.x"
"@opentelemetry/resources@1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5"
integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg==
"@nevware21/ts-async@>= 0.2.4 < 2.x":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c"
integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA==
dependencies:
"@opentelemetry/core" "1.7.0"
"@opentelemetry/semantic-conventions" "1.7.0"
"@nevware21/ts-utils" ">= 0.10.0 < 2.x"
"@opentelemetry/sdk-trace-base@^1.0.1":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5"
integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg==
"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x":
version "0.10.1"
resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7"
integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg==
"@opentelemetry/api@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f"
integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==
"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f"
integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw==
dependencies:
"@opentelemetry/core" "1.7.0"
"@opentelemetry/resources" "1.7.0"
"@opentelemetry/semantic-conventions" "1.7.0"
"@opentelemetry/semantic-conventions" "1.15.2"
"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763"
integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA==
"@opentelemetry/instrumentation@^0.41.2":
version "0.41.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f"
integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw==
dependencies:
"@types/shimmer" "^1.0.2"
import-in-the-middle "1.4.2"
require-in-the-middle "^7.1.1"
semver "^7.5.1"
shimmer "^1.2.1"
"@opentelemetry/resources@1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d"
integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw==
dependencies:
"@opentelemetry/core" "1.15.2"
"@opentelemetry/semantic-conventions" "1.15.2"
"@opentelemetry/sdk-trace-base@^1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a"
integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ==
dependencies:
"@opentelemetry/core" "1.15.2"
"@opentelemetry/resources" "1.15.2"
"@opentelemetry/semantic-conventions" "1.15.2"
"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2":
version "1.15.2"
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241"
integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw==
"@tootallnate/once@2":
version "2.0.0"
@@ -170,15 +264,30 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
"@vscode/extension-telemetry@^0.7.5":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b"
integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w==
"@types/shimmer@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f"
integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg==
"@vscode/extension-telemetry@^0.8.4":
version "0.8.4"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7"
integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA==
dependencies:
"@microsoft/1ds-core-js" "^3.2.8"
"@microsoft/1ds-post-js" "^3.2.8"
"@microsoft/applicationinsights-web-basic" "^2.8.9"
applicationinsights "2.4.1"
"@microsoft/1ds-core-js" "^3.2.13"
"@microsoft/1ds-post-js" "^3.2.13"
"@microsoft/applicationinsights-web-basic" "^3.0.2"
applicationinsights "^2.7.1"
acorn-import-assertions@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac"
integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==
acorn@^8.8.2:
version "8.10.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
agent-base@6:
version "6.0.2"
@@ -187,22 +296,24 @@ agent-base@6:
dependencies:
debug "4"
applicationinsights@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d"
integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA==
applicationinsights@^2.7.1:
version "2.7.3"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5"
integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw==
dependencies:
"@azure/core-auth" "^1.4.0"
"@azure/core-rest-pipeline" "^1.10.0"
"@azure/core-auth" "^1.5.0"
"@azure/core-rest-pipeline" "1.10.1"
"@azure/core-util" "1.2.0"
"@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5"
"@microsoft/applicationinsights-web-snippet" "^1.0.1"
"@opentelemetry/api" "^1.0.4"
"@opentelemetry/core" "^1.0.1"
"@opentelemetry/sdk-trace-base" "^1.0.1"
"@opentelemetry/semantic-conventions" "^1.0.1"
"@opentelemetry/api" "^1.4.1"
"@opentelemetry/core" "^1.15.2"
"@opentelemetry/sdk-trace-base" "^1.15.2"
"@opentelemetry/semantic-conventions" "^1.15.2"
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "1.1.0"
diagnostic-channel-publishers "1.0.5"
diagnostic-channel "1.1.1"
diagnostic-channel-publishers "1.0.7"
async-hook-jl@^1.7.6:
version "1.7.6"
@@ -236,6 +347,11 @@ brace-expansion@^2.0.1:
dependencies:
balanced-match "^1.0.0"
cjs-module-lexer@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107"
integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
@@ -260,7 +376,7 @@ continuation-local-storage@^3.2.1:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
debug@4:
debug@4, debug@^4.1.1:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -272,17 +388,17 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
diagnostic-channel-publishers@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae"
integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg==
diagnostic-channel-publishers@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a"
integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg==
diagnostic-channel@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e"
integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ==
diagnostic-channel@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0"
integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw==
dependencies:
semver "^5.3.0"
semver "^7.5.3"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
@@ -300,6 +416,18 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
http-proxy-agent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
@@ -317,6 +445,23 @@ https-proxy-agent@^5.0.0:
agent-base "6"
debug "4"
import-in-the-middle@1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b"
integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==
dependencies:
acorn "^8.8.2"
acorn-import-assertions "^1.9.0"
cjs-module-lexer "^1.2.2"
module-details-from-path "^1.0.3"
is-core-module@^2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
dependencies:
has "^1.0.3"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -343,29 +488,57 @@ minimatch@^5.1.0:
dependencies:
brace-expansion "^2.0.1"
module-details-from-path@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b"
integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
request-light@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a"
integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==
require-in-the-middle@^7.1.1:
version "7.2.0"
resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf"
integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw==
dependencies:
debug "^4.1.1"
module-details-from-path "^1.0.3"
resolve "^1.22.1"
resolve@^1.22.1:
version "1.22.4"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34"
integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==
dependencies:
is-core-module "^2.13.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
semver@^5.3.0, semver@^5.4.1:
version "5.7.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
semver@^7.3.7:
semver@^7.3.7, semver@^7.5.1, semver@^7.5.3:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
shimmer@^1.1.0, shimmer@^1.2.0:
shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
@@ -375,6 +548,11 @@ stack-chain@^1.3.7:
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
tslib@^2.2.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
@@ -385,32 +563,32 @@ uuid@^8.3.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
vscode-jsonrpc@8.2.0-next.0:
version "8.2.0-next.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c"
integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg==
vscode-jsonrpc@8.2.0-next.2:
version "8.2.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68"
integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A==
vscode-languageclient@^8.2.0-next.1:
version "8.2.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.1.tgz#a3f98b80cfa3225fde0583aa6a5c9b20219fa37e"
integrity sha512-oITaqHQ10PM3zXCUu/104wriMeDutXMkQXMaRBWh1jKihcNcUBLC/os7RhqiVGypY0nl+F0pwStAf4Koc8inaw==
vscode-languageclient@^8.2.0-next.3:
version "8.2.0-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.3.tgz#a5086f451a679ce77106d8fd1e05c8cbf8e9b886"
integrity sha512-Ojo6L2cb7GSiyD864k8vGb9fHxBdZeciHQQOF595C3IDHWg0w4KQ7iN7qGWVdl4wDNwlGTX3wWZawGfPTxnrPQ==
dependencies:
minimatch "^5.1.0"
semver "^7.3.7"
vscode-languageserver-protocol "3.17.4-next.1"
vscode-languageserver-protocol "3.17.4-next.3"
vscode-languageserver-protocol@3.17.4-next.1:
version "3.17.4-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616"
integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg==
vscode-languageserver-protocol@3.17.4-next.3:
version "3.17.4-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c"
integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ==
dependencies:
vscode-jsonrpc "8.2.0-next.0"
vscode-languageserver-types "3.17.4-next.0"
vscode-jsonrpc "8.2.0-next.2"
vscode-languageserver-types "3.17.4-next.2"
vscode-languageserver-types@3.17.4-next.0:
version "3.17.4-next.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2"
integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag==
vscode-languageserver-types@3.17.4-next.2:
version "3.17.4-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d"
integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A==
yallist@^4.0.0:
version "4.0.0"
+12 -12
View File
@@ -25,7 +25,7 @@ const cliPath = process.env.VSCODE_FORWARDING_IS_DEV
? path.join(__dirname, '../../../cli/target/debug/code')
: path.join(
vscode.env.appRoot,
process.platform === 'win32' ? '../../bin' : 'bin',
process.platform === 'darwin' ? 'bin' : '../../bin',
vscode.env.appQuality === 'stable' ? 'code-tunnel' : 'code-tunnel-insiders',
) + (process.platform === 'win32' ? '.exe' : '');
@@ -231,8 +231,8 @@ class TunnelProvider implements vscode.TunnelProvider {
];
this.logger.log('info', '[forwarding] starting CLI');
const process = spawn(cliPath, args, { stdio: 'pipe' });
this.state = { state: State.Starting, process };
const child = spawn(cliPath, args, { stdio: 'pipe', env: { ...process.env, NO_COLOR: '1' } });
this.state = { state: State.Starting, process: child };
const progressP = new DeferredPromise<void>();
vscode.window.withProgress(
@@ -248,29 +248,29 @@ class TunnelProvider implements vscode.TunnelProvider {
);
let lastPortFormat: string | undefined;
process.on('exit', status => {
child.on('exit', status => {
const msg = `[forwarding] exited with code ${status}`;
this.logger.log('info', msg);
progressP.complete(); // make sure to clear progress on unexpected exit
if (this.isInStateWithProcess(process)) {
if (this.isInStateWithProcess(child)) {
this.state = { state: State.Error, error: msg };
}
});
process.on('error', err => {
child.on('error', err => {
this.logger.log('error', `[forwarding] ${err}`);
progressP.complete(); // make sure to clear progress on unexpected exit
if (this.isInStateWithProcess(process)) {
if (this.isInStateWithProcess(child)) {
this.state = { state: State.Error, error: String(err) };
}
});
process.stdout
child.stdout
.pipe(splitNewLines())
.on('data', line => this.logger.log('info', `[forwarding] ${line}`))
.resume();
process.stderr
child.stderr
.pipe(splitNewLines())
.on('data', line => {
try {
@@ -278,7 +278,7 @@ class TunnelProvider implements vscode.TunnelProvider {
if (l.port_format && l.port_format !== lastPortFormat) {
this.state = {
state: State.Active,
portFormat: l.port_format, process,
portFormat: l.port_format, process: child,
cleanupTimeout: 'cleanupTimeout' in this.state ? this.state.cleanupTimeout : undefined,
};
progressP.complete();
@@ -290,8 +290,8 @@ class TunnelProvider implements vscode.TunnelProvider {
.resume();
await new Promise((resolve, reject) => {
process.on('spawn', resolve);
process.on('error', reject);
child.on('spawn', resolve);
child.on('error', reject);
});
}
}
+3 -1
View File
@@ -9,6 +9,8 @@ export const splitNewLines = () => new StreamSplitter('\n'.charCodeAt(0));
/**
* Copied and simplified from src\vs\base\node\nodeStreams.ts
*
* Exception: does not include the split character in the output.
*/
export class StreamSplitter extends Transform {
private buffer: Buffer | undefined;
@@ -31,7 +33,7 @@ export class StreamSplitter extends Transform {
break;
}
this.push(this.buffer.subarray(offset, index + 1));
this.push(this.buffer.subarray(offset, index));
offset = index + 1;
}
@@ -977,6 +977,22 @@ suite('vscode API - workspace', () => {
assert.strictEqual(document.getText(), expected);
});
test('[Bug] Failed to create new test file when in an untitled file #1261', async function () {
const uri = vscode.Uri.parse('untitled:Untitled-5.test');
const contents = `Hello Test File ${uri.toString()}`;
const we = new vscode.WorkspaceEdit();
we.createFile(uri, { ignoreIfExists: true });
we.replace(uri, new vscode.Range(0, 0, 0, 0), contents);
const success = await vscode.workspace.applyEdit(we);
assert.ok(success);
const doc = await vscode.workspace.openTextDocument(uri);
assert.strictEqual(doc.getText(), contents);
});
test('Should send a single FileWillRenameEvent instead of separate events when moving multiple files at once#111867, 1/3', async function () {
const file1 = await createRandomFile();
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
"version": "1.82.0",
"distro": "56bfb9ce4a8d2298f475a1b8d9c7a7b5a72204f2",
"version": "1.83.0",
"distro": "46e7bb69af9f06de037c3d7e8f61de4a679f9ef1",
"author": {
"name": "Microsoft Corporation"
},
@@ -150,10 +150,10 @@
"cssnano": "^4.1.11",
"debounce": "^1.0.0",
"deemon": "^1.8.0",
"electron": "25.5.0",
"electron": "25.8.0",
"eslint": "8.36.0",
"eslint-plugin-header": "3.1.1",
"eslint-plugin-jsdoc": "^39.3.2",
"eslint-plugin-jsdoc": "^46.5.0",
"eslint-plugin-local": "^1.0.0",
"event-stream": "3.3.4",
"fancy-log": "^1.3.3",
+2 -2
View File
@@ -52,8 +52,8 @@
},
{
"name": "ms-vscode.js-debug",
"version": "1.81.0",
"sha256": "6d1c7ee89881afd65e8fee47445b6a1c5fb345bf30e2bdf70cd2fdd8d1ff6dec",
"version": "1.82.0",
"sha256": "4fba41b4b764c3f5a6591d6d9a5bdc59b417f2d799071c889c2b54163f256282",
"repo": "https://github.com/microsoft/vscode-js-debug",
"metadata": {
"id": "25629058-ddac-4e17-abba-74678e126c5d",
+1 -1
View File
@@ -1,5 +1,5 @@
disturl "https://nodejs.org/dist"
target "18.15.0"
ms_build_id "223745"
ms_build_id "229541"
runtime "node"
build_from_source "true"
+22
View File
@@ -0,0 +1,22 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
type RunFunction = ((debugSession: IDebugSession) => IDisposable) | ((debugSession: IDebugSession) => Promise<IDisposable>);
interface IDebugSession {
name: string;
eval(expression: string): Promise<void>;
evalJs<T extends any[]>(bodyFn: (...args: T) => void, ...args: T): Promise<void>;
}
interface IDisposable {
dispose(): void;
}
interface GlobalThisAddition extends globalThis {
$hotReload_applyNewExports?(oldExports: Record<string, unknown>): AcceptNewExportsFn | undefined;
}
type AcceptNewExportsFn = (newExports: Record<string, unknown>) => boolean;
+267
View File
@@ -0,0 +1,267 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// @ts-check
/// <reference path='debugger-scripts-api.d.ts' />
const path = require('path');
const fsPromise = require('fs/promises');
const parcelWatcher = require('@parcel/watcher');
// This file is loaded by the vscode-diagnostic-tools extension and injected into the debugger.
/** @type {RunFunction} */
module.exports.run = async function (debugSession) {
const watcher = await DirWatcher.watchRecursively(path.join(__dirname, '../out/'));
const sub = watcher.onDidChange(changes => {
const supportedChanges = changes.filter(c => c.path.endsWith('.js') || c.path.endsWith('.css'));
debugSession.evalJs(function (changes, debugSessionName) {
// This function is stringified and injected into the debuggee.
/** @type {{ count: number; originalWindowTitle: any; timeout: any; shouldReload: boolean }} */
const hotReloadData = globalThis.$hotReloadData || (globalThis.$hotReloadData = { count: 0, messageHideTimeout: undefined, shouldReload: false });
/**
* @param {string} path
* @param {string} newSrc
*/
function handleChange(path, newSrc) {
const relativePath = path.replace(/\\/g, '/').split('/out/')[1];
if (relativePath.endsWith('.css')) {
handleCssChange(relativePath);
} else if (relativePath.endsWith('.js')) {
handleJsChange(relativePath, newSrc);
}
}
/**
* @param {string} relativePath
*/
function handleCssChange(relativePath) {
if (typeof document === 'undefined') {
return;
}
const styleSheet = (/** @type {HTMLLinkElement[]} */ ([...document.querySelectorAll(`link[rel='stylesheet']`)]))
.find(l => new URL(l.href, document.location.href).pathname.endsWith(relativePath));
if (styleSheet) {
setMessage(`reload ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
console.log(debugSessionName, 'css reloaded', relativePath);
styleSheet.href = styleSheet.href.replace(/\?.*/, '') + '?' + Date.now();
} else {
setMessage(`could not reload ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
console.log(debugSessionName, 'ignoring css change, as stylesheet is not loaded', relativePath);
}
}
/**
* @param {string} relativePath
* @param {string} newSrc
*/
function handleJsChange(relativePath, newSrc) {
const moduleIdStr = trimEnd(relativePath, '.js');
/** @type {any} */
const requireFn = globalThis.require;
const moduleManager = requireFn.moduleManager;
if (!moduleManager) {
console.log(debugSessionName, 'ignoring js change, as moduleManager is not available', relativePath);
return;
}
const moduleId = moduleManager._moduleIdProvider.getModuleId(moduleIdStr);
const oldModule = moduleManager._modules2[moduleId];
if (!oldModule) {
console.log(debugSessionName, 'ignoring js change, as module is not loaded', relativePath);
return;
}
// Check if we can reload
const g = /** @type {GlobalThisAddition} */ (globalThis);
// A frozen copy of the previous exports
const oldExports = Object.freeze({ ...oldModule.exports });
const reloadFn = g.$hotReload_applyNewExports?.(oldExports);
if (!reloadFn) {
console.log(debugSessionName, 'ignoring js change, as module does not support hot-reload', relativePath);
hotReloadData.shouldReload = true;
setMessage(`hot reload not supported for ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
return;
}
const newScript = new Function('define', newSrc); // CodeQL [SM01632] This code is only executed during development. It is required for the hot-reload functionality.
newScript(/* define */ function (deps, callback) {
// Evaluating the new code was successful.
// Redefine the module
delete moduleManager._modules2[moduleId];
moduleManager.defineModule(moduleIdStr, deps, callback);
const newModule = moduleManager._modules2[moduleId];
// Patch the exports of the old module, so that modules using the old module get the new exports
Object.assign(oldModule.exports, newModule.exports);
// We override the exports so that future reloads still patch the initial exports.
newModule.exports = oldModule.exports;
const successful = reloadFn(newModule.exports);
if (!successful) {
hotReloadData.shouldReload = true;
setMessage(`hot reload failed ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
console.log(debugSessionName, 'hot reload was not successful', relativePath);
return;
}
console.log(debugSessionName, 'hot reloaded', moduleIdStr);
setMessage(`successfully reloaded ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`);
});
}
/**
* @param {string} message
*/
function setMessage(message) {
const domElem = /** @type {HTMLDivElement | undefined} */ (document.querySelector('.titlebar-center .window-title'));
if (!domElem) { return; }
if (!hotReloadData.timeout) {
hotReloadData.originalWindowTitle = domElem.innerText;
} else {
clearTimeout(hotReloadData.timeout);
}
if (hotReloadData.shouldReload) {
message += ' (manual reload required)';
}
domElem.innerText = message;
hotReloadData.timeout = setTimeout(() => {
hotReloadData.timeout = undefined;
// If wanted, we can restore the previous title message
// domElem.replaceChildren(hotReloadData.originalWindowTitle);
}, 5000);
}
/**
* @param {string} path
* @returns {string}
*/
function formatPath(path) {
const parts = path.split('/');
parts.reverse();
let result = parts[0];
parts.shift();
for (const p of parts) {
if (result.length + p.length > 40) {
break;
}
result = p + '/' + result;
if (result.length > 20) {
break;
}
}
return result;
}
function trimEnd(str, suffix) {
if (str.endsWith(suffix)) {
return str.substring(0, str.length - suffix.length);
}
return str;
}
for (const change of changes) {
handleChange(change.path, change.newContent);
}
}, supportedChanges, debugSession.name.substring(0, 25));
});
return {
dispose() {
sub.dispose();
watcher.dispose();
}
};
};
class DirWatcher {
/**
*
* @param {string} dir
* @returns {Promise<DirWatcher>}
*/
static async watchRecursively(dir) {
/** @type {((changes: { path: string, newContent: string }[]) => void)[]} */
const listeners = [];
/** @type {Map<string, string> } */
const fileContents = new Map();
/** @type {Map<string, { path: string, newContent: string }>} */
const changes = new Map();
/** @type {(handler: (changes: { path: string, newContent: string }[]) => void) => IDisposable} */
const event = (handler) => {
listeners.push(handler);
return {
dispose: () => {
const idx = listeners.indexOf(handler);
if (idx >= 0) {
listeners.splice(idx, 1);
}
}
};
};
const r = parcelWatcher.subscribe(dir, async (err, events) => {
for (const e of events) {
if (e.type === 'update') {
const newContent = await fsPromise.readFile(e.path, 'utf8');
if (fileContents.get(e.path) !== newContent) {
fileContents.set(e.path, newContent);
changes.set(e.path, { path: e.path, newContent });
}
}
}
if (changes.size > 0) {
debounce(() => {
const uniqueChanges = Array.from(changes.values());
changes.clear();
listeners.forEach(l => l(uniqueChanges));
})();
}
});
const result = await r;
return new DirWatcher(event, () => result.unsubscribe());
}
/**
* @param {(handler: (changes: { path: string, newContent: string }[]) => void) => IDisposable} onDidChange
* @param {() => void} unsub
*/
constructor(onDidChange, unsub) {
this.onDidChange = onDidChange;
this.unsub = unsub;
}
dispose() {
this.unsub();
}
}
/**
* Debounce function calls
* @param {() => void} fn
* @param {number} delay
*/
function debounce(fn, delay = 50) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
Binary file not shown.
+10 -11
View File
@@ -532,13 +532,16 @@ class TypeNavigationController<T> implements IDisposable {
const prefix = matchesPrefix(word, labelStr);
const fuzzy = matchesFuzzy2(word, labelStr);
// ensures that when fuzzy matching, it doesn't clash with prefix matching (1 input vs 1+ should be prefix and fuzzy respecitvely)
const fuzzyScore = fuzzy ? fuzzy[0].end - fuzzy[0].start : 0;
if (prefix || fuzzyScore > 1) {
this.previouslyFocused = start;
this.list.setFocus([index]);
this.list.reveal(index);
return;
if (fuzzy) {
const fuzzyScore = fuzzy[0].end - fuzzy[0].start;
// ensures that when fuzzy matching, doesn't clash with prefix matching (1 input vs 1+ should be prefix and fuzzy respecitvely). Also makes sure that exact matches are prioritized.
if (prefix || (fuzzyScore > 1 && fuzzy.length === 1)) {
this.previouslyFocused = start;
this.list.setFocus([index]);
this.list.reveal(index);
return;
}
}
}
} else {
@@ -729,10 +732,6 @@ export class MouseController<T> implements IDisposable {
return;
}
if (this.isSelectionRangeChangeEvent(e)) {
return this.changeSelection(e);
}
if (this.isSelectionChangeEvent(e)) {
return this.changeSelection(e);
}
+28
View File
@@ -177,6 +177,30 @@ export function groupBy<T>(data: ReadonlyArray<T>, compare: (a: T, b: T) => numb
return result;
}
/**
* Splits the given items into a list of (non-empty) groups.
* `shouldBeGrouped` is used to decide if two consecutive items should be in the same group.
* The order of the items is preserved.
*/
export function* groupAdjacentBy<T>(items: Iterable<T>, shouldBeGrouped: (item1: T, item2: T) => boolean): Iterable<T[]> {
let currentGroup: T[] | undefined;
let last: T | undefined;
for (const item of items) {
if (last !== undefined && shouldBeGrouped(last, item)) {
currentGroup!.push(item);
} else {
if (currentGroup) {
yield currentGroup;
}
currentGroup = [item];
}
last = item;
}
if (currentGroup) {
yield currentGroup;
}
}
interface IMutableSplice<T> extends ISplice<T> {
readonly toInsert: T[];
deleteCount: number;
@@ -666,6 +690,10 @@ export namespace CompareResult {
return result < 0;
}
export function isLessThanOrEqual(result: CompareResult): boolean {
return result <= 0;
}
export function isGreaterThan(result: CompareResult): boolean {
return result > 0;
}
+109
View File
@@ -0,0 +1,109 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/**
* Finds the last item where predicate is true using binary search.
* `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`!
*
* @returns `undefined` if no item matches, otherwise the last item that matches the predicate.
*/
export function findLastMonotonous<T>(arr: T[], predicate: (item: T) => boolean): T | undefined {
const idx = findLastIdxMonotonous(arr, predicate);
return idx === -1 ? undefined : arr[idx];
}
/**
* Finds the last item where predicate is true using binary search.
* `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`!
*
* @returns `startIdx - 1` if predicate is false for all items, otherwise the index of the last item that matches the predicate.
*/
export function findLastIdxMonotonous<T>(arr: T[], predicate: (item: T) => boolean, startIdx = 0, endIdxEx = arr.length): number {
let i = startIdx;
let j = endIdxEx;
while (i < j) {
const k = Math.floor((i + j) / 2);
if (predicate(arr[k])) {
i = k + 1;
} else {
j = k;
}
}
return i - 1;
}
/**
* Finds the first item where predicate is true using binary search.
* `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[false, ..., false, true, ..., true]`!
*
* @returns `undefined` if no item matches, otherwise the first item that matches the predicate.
*/
export function findFirstMonotonous<T>(arr: T[], predicate: (item: T) => boolean): T | undefined {
const idx = findFirstIdxMonotonousOrArrLen(arr, predicate);
return idx === arr.length ? undefined : arr[idx];
}
/**
* Finds the first item where predicate is true using binary search.
* `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[false, ..., false, true, ..., true]`!
*
* @returns `endIdxEx` if predicate is false for all items, otherwise the index of the first item that matches the predicate.
*/
export function findFirstIdxMonotonousOrArrLen<T>(arr: T[], predicate: (item: T) => boolean, startIdx = 0, endIdxEx = arr.length): number {
let i = startIdx;
let j = endIdxEx;
while (i < j) {
const k = Math.floor((i + j) / 2);
if (predicate(arr[k])) {
j = k;
} else {
i = k + 1;
}
}
return i;
}
export function findFirstIdxMonotonous<T>(arr: T[], predicate: (item: T) => boolean, startIdx = 0, endIdxEx = arr.length): number {
const idx = findFirstIdxMonotonousOrArrLen(arr, predicate, startIdx, endIdxEx);
return idx === arr.length ? -1 : idx;
}
/**
* Use this when
* * You have a sorted array
* * You query this array with a monotonous predicate to find the last item that has a certain property.
* * You query this array multiple times with monotonous predicates that get weaker and weaker.
*/
export class MonotonousArray<T> {
public static assertInvariants = false;
private _findLastMonotonousLastIdx = 0;
private _lastPredicate: ((item: T) => boolean) | undefined;
constructor(private readonly _items: T[]) {
}
/**
* The predicate must be monotonous, i.e. `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`!
* For subsequent calls, current predicate must be weaker than (or equal to) the previous predicate, i.e. more entries must be `true`.
*/
findLastMonotonous(predicate: (item: T) => boolean): T | undefined {
if (MonotonousArray.assertInvariants) {
if (this._lastPredicate) {
for (const item of this._items) {
if (this._lastPredicate(item) && !predicate(item)) {
throw new Error('MonotonousArray: current predicate must be weaker than (or equal to) the previous predicate.');
}
}
}
this._lastPredicate = predicate;
}
const idx = findLastIdxMonotonous(this._items, predicate, this._findLastMonotonousLastIdx);
this._findLastMonotonousLastIdx = idx + 1;
return idx === -1 ? undefined : this._items[idx];
}
}
+1
View File
@@ -567,6 +567,7 @@ export const Codicon = {
send: register('send', 0xec0f),
sparkle: register('sparkle', 0xec10),
insert: register('insert', 0xec11),
mic: register('mic', 0xec12),
// derived icons, that could become separate icons
+18
View File
@@ -557,6 +557,24 @@ export namespace Event {
return new Promise(resolve => once(event)(resolve));
}
/**
* Creates an event out of a promise that fires once when the promise is
* resolved with the result of the promise or `undefined`.
*/
export function fromPromise<T>(promise: Promise<T>): Event<T | undefined> {
const result = new Emitter<T | undefined>();
promise.then(res => {
result.fire(res);
}, () => {
result.fire(undefined);
}).finally(() => {
result.dispose();
});
return result.event;
}
/**
* Adds a listener to an event and calls the listener immediately with undefined as the event object.
*
+59
View File
@@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable } from 'vs/base/common/lifecycle';
import { env } from 'vs/base/common/process';
export function isHotReloadEnabled(): boolean {
return !!env['VSCODE_DEV'];
}
export function registerHotReloadHandler(handler: HotReloadHandler): IDisposable {
if (!isHotReloadEnabled()) {
return { dispose() { } };
} else {
const handlers = registerGlobalHotReloadHandler();
handlers.add(handler);
return {
dispose() { handlers.delete(handler); }
};
}
}
/**
* Takes the old exports of the module to reload and returns a function to apply the new exports.
* If `undefined` is returned, this handler is not able to handle the module.
*
* If no handler can apply the new exports, the module will not be reloaded.
*/
export type HotReloadHandler = (oldExports: Record<string, unknown>) => AcceptNewExportsHandler | undefined;
export type AcceptNewExportsHandler = (newExports: Record<string, unknown>) => boolean;
function registerGlobalHotReloadHandler() {
if (!hotReloadHandlers) {
hotReloadHandlers = new Set();
}
const g = globalThis as unknown as GlobalThisAddition;
if (!g.$hotReload_applyNewExports) {
g.$hotReload_applyNewExports = oldExports => {
for (const h of hotReloadHandlers!) {
const result = h(oldExports);
if (result) { return result; }
}
return undefined;
};
}
return hotReloadHandlers;
}
let hotReloadHandlers: Set<(oldExports: Record<string, unknown>) => AcceptNewExportsFn | undefined> | undefined = undefined;
interface GlobalThisAddition {
$hotReload_applyNewExports?(oldExports: Record<string, unknown>): AcceptNewExportsFn | undefined;
}
type AcceptNewExportsFn = (newExports: Record<string, unknown>) => boolean;
+9
View File
@@ -186,6 +186,7 @@ export interface IProductConfiguration {
readonly profileTemplatesUrl?: string;
readonly commonlyUsedSettings?: string[];
readonly aiGeneratedWorkspaceTrust?: IAiGeneratedWorkspaceTrust;
}
export interface ITunnelApplicationConfig {
@@ -279,3 +280,11 @@ export interface ISurveyData {
editCount: number;
userProbability: number;
}
export interface IAiGeneratedWorkspaceTrust {
readonly title: string;
readonly checkboxText: string;
readonly trustOption: string;
readonly dontTrustOption: string;
readonly startupTrustRequestLearnMore: string;
}
@@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import assert = require('assert');
import { MonotonousArray, findFirstMonotonous, findLastMonotonous } from 'vs/base/common/arraysFind';
suite('Arrays', () => {
test('findLastMonotonous', () => {
const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69];
const result = findLastMonotonous(array, n => n <= 60);
assert.strictEqual(result, 60);
const result2 = findLastMonotonous(array, n => n <= 62);
assert.strictEqual(result2, 61);
const result3 = findLastMonotonous(array, n => n <= 1);
assert.strictEqual(result3, 1);
const result4 = findLastMonotonous(array, n => n <= 70);
assert.strictEqual(result4, 69);
const result5 = findLastMonotonous(array, n => n <= 0);
assert.strictEqual(result5, undefined);
});
test('findFirstMonotonous', () => {
const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69];
const result = findFirstMonotonous(array, n => n >= 60);
assert.strictEqual(result, 60);
const result2 = findFirstMonotonous(array, n => n >= 62);
assert.strictEqual(result2, 64);
const result3 = findFirstMonotonous(array, n => n >= 1);
assert.strictEqual(result3, 1);
const result4 = findFirstMonotonous(array, n => n >= 70);
assert.strictEqual(result4, undefined);
const result5 = findFirstMonotonous(array, n => n >= 0);
assert.strictEqual(result5, 1);
});
test('MonotonousArray', () => {
const arr = new MonotonousArray([1, 4, 5, 7, 55, 59, 60, 61, 64, 69]);
assert.strictEqual(arr.findLastMonotonous(n => n <= 0), undefined);
assert.strictEqual(arr.findLastMonotonous(n => n <= 0), undefined);
assert.strictEqual(arr.findLastMonotonous(n => n <= 5), 5);
assert.strictEqual(arr.findLastMonotonous(n => n <= 6), 5);
assert.strictEqual(arr.findLastMonotonous(n => n <= 55), 55);
assert.strictEqual(arr.findLastMonotonous(n => n <= 60), 60);
assert.strictEqual(arr.findLastMonotonous(n => n <= 80), 69);
});
});
+43 -1
View File
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { stub } from 'sinon';
import { timeout } from 'vs/base/common/async';
import { DeferredPromise, timeout } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { errorHandler, setUnexpectedErrorHandler } from 'vs/base/common/errors';
import { AsyncEmitter, DebounceEmitter, DynamicListEventMultiplexer, Emitter, Event, EventBufferer, EventMultiplexer, IWaitUntil, MicrotaskEmitter, PauseableEmitter, Relay, createEventDeliveryQueue } from 'vs/base/common/event';
@@ -1158,6 +1158,48 @@ suite('Event utils', () => {
listener.dispose(); // should not crash
});
suite('fromPromise', () => {
test('not yet resolved', async function () {
return new Promise(resolve => {
let promise = new DeferredPromise<number>();
Event.fromPromise(promise.p)(e => {
assert.strictEqual(e, 1);
promise = new DeferredPromise();
Event.fromPromise(promise.p)(() => {
resolve();
});
promise.error(undefined);
});
promise.complete(1);
});
});
test('already resolved', async function () {
return new Promise(resolve => {
let promise = new DeferredPromise<number>();
promise.complete(1);
Event.fromPromise(promise.p)(e => {
assert.strictEqual(e, 1);
promise = new DeferredPromise();
promise.error(undefined);
Event.fromPromise(promise.p)(() => {
resolve();
});
});
});
});
});
suite('Relay', () => {
test('should input work', () => {
const e1 = new Emitter<number>();
+234 -58
View File
@@ -4,31 +4,197 @@
*--------------------------------------------------------------------------------------------*/
import { isStandalone } from 'vs/base/browser/browser';
import { parse } from 'vs/base/common/marshalling';
import { VSBuffer, decodeBase64, encodeBase64 } from 'vs/base/common/buffer';
import { Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { parse } from 'vs/base/common/marshalling';
import { Schemas } from 'vs/base/common/network';
import { posix } from 'vs/base/common/path';
import { isEqual } from 'vs/base/common/resources';
import { ltrim } from 'vs/base/common/strings';
import { URI, UriComponents } from 'vs/base/common/uri';
import product from 'vs/platform/product/common/product';
import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/window/common/window';
import { create } from 'vs/workbench/workbench.web.main';
import { posix } from 'vs/base/common/path';
import { ltrim } from 'vs/base/common/strings';
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api';
import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService';
import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets';
import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/window/common/window';
import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api';
import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService';
import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService';
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
import { create } from 'vs/workbench/workbench.web.main';
class LocalStorageSecretStorageProvider implements ISecretStorageProvider {
private static readonly STORAGE_KEY = 'secrets.provider';
interface ISecretStorageCrypto {
seal(data: string): Promise<string>;
unseal(data: string): Promise<string>;
}
private _secrets: Record<string, string> | undefined;
class TransparentCrypto implements ISecretStorageCrypto {
async seal(data: string): Promise<string> {
return data;
}
async unseal(data: string): Promise<string> {
return data;
}
}
const enum AESConstants {
ALGORITHM = 'AES-GCM',
KEY_LENGTH = 256,
IV_LENGTH = 12,
}
class ServerKeyedAESCrypto implements ISecretStorageCrypto {
private _serverKey: Uint8Array | undefined;
/** Gets whether the algorithm is supported; requires a secure context */
public static supported() {
return !!crypto.subtle;
}
constructor(private readonly authEndpoint: string) { }
async seal(data: string): Promise<string> {
// Get a new key and IV on every change, to avoid the risk of reusing the same key and IV pair with AES-GCM
// (see also: https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams#properties)
const iv = window.crypto.getRandomValues(new Uint8Array(AESConstants.IV_LENGTH));
// crypto.getRandomValues isn't a good-enough PRNG to generate crypto keys, so we need to use crypto.subtle.generateKey and export the key instead
const clientKeyObj = await window.crypto.subtle.generateKey(
{ name: AESConstants.ALGORITHM as const, length: AESConstants.KEY_LENGTH as const },
true,
['encrypt', 'decrypt']
);
const clientKey = new Uint8Array(await window.crypto.subtle.exportKey('raw', clientKeyObj));
const key = await this.getKey(clientKey);
const dataUint8Array = new TextEncoder().encode(data);
const cipherText: ArrayBuffer = await window.crypto.subtle.encrypt(
{ name: AESConstants.ALGORITHM as const, iv },
key,
dataUint8Array
);
// Base64 encode the result and store the ciphertext, the key, and the IV in localStorage
// Note that the clientKey and IV don't need to be secret
const result = new Uint8Array([...clientKey, ...iv, ...new Uint8Array(cipherText)]);
return encodeBase64(VSBuffer.wrap(result));
}
async unseal(data: string): Promise<string> {
// encrypted should contain, in order: the key (32-byte), the IV for AES-GCM (12-byte) and the ciphertext (which has the GCM auth tag at the end)
// Minimum length must be 44 (key+IV length) + 16 bytes (1 block encrypted with AES - regardless of key size)
const dataUint8Array = decodeBase64(data);
if (dataUint8Array.byteLength < 60) {
throw Error('Invalid length for the value for credentials.crypto');
}
const keyLength = AESConstants.KEY_LENGTH / 8;
const clientKey = dataUint8Array.slice(0, keyLength);
const iv = dataUint8Array.slice(keyLength, keyLength + AESConstants.IV_LENGTH);
const cipherText = dataUint8Array.slice(keyLength + AESConstants.IV_LENGTH);
// Do the decryption and parse the result as JSON
const key = await this.getKey(clientKey.buffer);
const decrypted = await window.crypto.subtle.decrypt(
{ name: AESConstants.ALGORITHM as const, iv: iv.buffer },
key,
cipherText.buffer
);
return new TextDecoder().decode(new Uint8Array(decrypted));
}
/**
* Given a clientKey, returns the CryptoKey object that is used to encrypt/decrypt the data.
* The actual key is (clientKey XOR serverKey)
*/
private async getKey(clientKey: Uint8Array): Promise<CryptoKey> {
if (!clientKey || clientKey.byteLength !== AESConstants.KEY_LENGTH / 8) {
throw Error('Invalid length for clientKey');
}
const serverKey = await this.getServerKeyPart();
const keyData = new Uint8Array(AESConstants.KEY_LENGTH / 8);
for (let i = 0; i < keyData.byteLength; i++) {
keyData[i] = clientKey[i]! ^ serverKey[i]!;
}
return window.crypto.subtle.importKey(
'raw',
keyData,
{
name: AESConstants.ALGORITHM as const,
length: AESConstants.KEY_LENGTH as const,
},
true,
['encrypt', 'decrypt']
);
}
private async getServerKeyPart(): Promise<Uint8Array> {
if (this._serverKey) {
return this._serverKey;
}
let attempt = 0;
let lastError: unknown | undefined;
while (attempt <= 3) {
try {
const res = await fetch(this.authEndpoint, { credentials: 'include', method: 'POST' });
if (!res.ok) {
throw new Error(res.statusText);
}
const serverKey = new Uint8Array(await await res.arrayBuffer());
if (serverKey.byteLength !== AESConstants.KEY_LENGTH / 8) {
throw Error(`The key retrieved by the server is not ${AESConstants.KEY_LENGTH} bit long.`);
}
this._serverKey = serverKey;
return this._serverKey;
} catch (e) {
lastError = e;
attempt++;
// exponential backoff
await new Promise(resolve => setTimeout(resolve, attempt * attempt * 100));
}
}
throw lastError;
}
}
export class LocalStorageSecretStorageProvider implements ISecretStorageProvider {
private readonly _storageKey = 'secrets.provider';
private _secretsPromise: Promise<Record<string, string>> = this.load();
type: 'in-memory' | 'persisted' | 'unknown' = 'persisted';
constructor() {
constructor(
private readonly crypto: ISecretStorageCrypto,
) { }
private async load(): Promise<Record<string, string>> {
const record = this.loadAuthSessionFromElement();
// Get the secrets from localStorage
const encrypted = window.localStorage.getItem(this._storageKey);
if (encrypted) {
try {
const decrypted = JSON.parse(await this.crypto.unseal(encrypted));
return { ...record, ...decrypted };
} catch (err) {
// TODO: send telemetry
console.error('Failed to decrypt secrets from localStorage', err);
window.localStorage.removeItem(this._storageKey);
}
}
return record;
}
private loadAuthSessionFromElement(): Record<string, string> {
let authSessionInfo: (AuthenticationSessionInfo & { scopes: string[][] }) | undefined;
const authSessionElement = document.getElementById('vscode-workbench-auth-session');
const authSessionElementAttribute = authSessionElement ? authSessionElement.getAttribute('data-settings') : undefined;
@@ -38,65 +204,59 @@ class LocalStorageSecretStorageProvider implements ISecretStorageProvider {
} catch (error) { /* Invalid session is passed. Ignore. */ }
}
if (authSessionInfo) {
// Settings Sync Entry
this.set(`${product.urlProtocol}.loginAccount`, JSON.stringify(authSessionInfo));
// Auth extension Entry
if (authSessionInfo.providerId !== 'github') {
console.error(`Unexpected auth provider: ${authSessionInfo.providerId}. Expected 'github'.`);
return;
}
const authAccount = JSON.stringify({ extensionId: 'vscode.github-authentication', key: 'github.auth' });
this.set(authAccount, JSON.stringify(authSessionInfo.scopes.map(scopes => ({
id: authSessionInfo!.id,
scopes,
accessToken: authSessionInfo!.accessToken
}))));
if (!authSessionInfo) {
return {};
}
const record: Record<string, string> = {};
// Settings Sync Entry
record[`${product.urlProtocol}.loginAccount`] = JSON.stringify(authSessionInfo);
// Auth extension Entry
if (authSessionInfo.providerId !== 'github') {
console.error(`Unexpected auth provider: ${authSessionInfo.providerId}. Expected 'github'.`);
return record;
}
const authAccount = JSON.stringify({ extensionId: 'vscode.github-authentication', key: 'github.auth' });
record[authAccount] = JSON.stringify(authSessionInfo.scopes.map(scopes => ({
id: authSessionInfo!.id,
scopes,
accessToken: authSessionInfo!.accessToken
})));
return record;
}
get(key: string): Promise<string | undefined> {
return Promise.resolve(this.secrets[key]);
async get(key: string): Promise<string | undefined> {
const secrets = await this._secretsPromise;
return secrets[key];
}
set(key: string, value: string): Promise<void> {
this.secrets[key] = value;
async set(key: string, value: string): Promise<void> {
const secrets = await this._secretsPromise;
secrets[key] = value;
this._secretsPromise = Promise.resolve(secrets);
this.save();
return Promise.resolve();
}
async delete(key: string): Promise<void> {
delete this.secrets[key];
const secrets = await this._secretsPromise;
delete secrets[key];
this._secretsPromise = Promise.resolve(secrets);
this.save();
return Promise.resolve();
}
private get secrets(): Record<string, string> {
if (!this._secrets) {
try {
const serializedCredentials = window.localStorage.getItem(LocalStorageSecretStorageProvider.STORAGE_KEY);
if (serializedCredentials) {
this._secrets = JSON.parse(serializedCredentials);
}
} catch (error) {
// ignore
}
if (!(this._secrets instanceof Object)) {
this._secrets = {};
}
private async save(): Promise<void> {
try {
const encrypted = await this.crypto.seal(JSON.stringify(await this._secretsPromise));
window.localStorage.setItem(this._storageKey, encrypted);
} catch (err) {
console.error(err);
}
return this._secrets;
}
private save(): void {
window.localStorage.setItem(LocalStorageSecretStorageProvider.STORAGE_KEY, JSON.stringify(this.secrets));
}
}
class LocalStorageURLCallbackProvider extends Disposable implements IURLCallbackProvider {
private static REQUEST_ID = 0;
@@ -390,6 +550,17 @@ class WorkspaceProvider implements IWorkspaceProvider {
}
}
function readCookie(name: string): string | undefined {
const cookies = document.cookie.split('; ');
for (const cookie of cookies) {
if (cookie.startsWith(name + '=')) {
return cookie.substring(name.length + 1);
}
}
return undefined;
}
(function () {
// Find config by checking for DOM
@@ -399,6 +570,9 @@ class WorkspaceProvider implements IWorkspaceProvider {
throw new Error('Missing web configuration element');
}
const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents; callbackRoute: string } = JSON.parse(configElementAttribute);
const secretStorageKeyPath = readCookie('vscode-secret-key-path');
const secretStorageCrypto = secretStorageKeyPath && ServerKeyedAESCrypto.supported()
? new ServerKeyedAESCrypto(secretStorageKeyPath) : new TransparentCrypto();
// Create workbench
create(document.body, {
@@ -407,6 +581,8 @@ class WorkspaceProvider implements IWorkspaceProvider {
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
workspaceProvider: WorkspaceProvider.create(config),
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),
secretStorageProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local secret storage provider */ : new LocalStorageSecretStorageProvider()
secretStorageProvider: config.remoteAuthority && !secretStorageKeyPath
? undefined /* with a remote without embedder-preferred storage, store on the remote */
: new LocalStorageSecretStorageProvider(secretStorageCrypto),
});
})();
+11 -1
View File
@@ -774,7 +774,17 @@ export class CodeApplication extends Disposable {
if (secondSlash !== -1) {
const authority = uri.path.substring(1, secondSlash);
const path = uri.path.substring(secondSlash);
const remoteUri = URI.from({ scheme: Schemas.vscodeRemote, authority, path, query: uri.query, fragment: uri.fragment });
let query = uri.query;
const params = new URLSearchParams(uri.query);
if (params.get('windowId') === '_blank') {
// Make sure to unset any `windowId=_blank` here
// https://github.com/microsoft/vscode/issues/191902
params.delete('windowId');
query = params.toString();
}
const remoteUri = URI.from({ scheme: Schemas.vscodeRemote, authority, path, query, fragment: uri.fragment });
if (hasWorkspaceFileExtension(path)) {
return { workspaceUri: remoteUri };
+4 -4
View File
@@ -251,10 +251,10 @@ class CodeMain {
Promise.all<string | undefined>([
environmentMainService.extensionsPath,
environmentMainService.codeCachePath,
environmentMainService.logsHome.fsPath,
userDataProfilesMainService.defaultProfile.globalStorageHome.fsPath,
environmentMainService.workspaceStorageHome.fsPath,
environmentMainService.localHistoryHome.fsPath,
environmentMainService.logsHome.with({ scheme: Schemas.file }).fsPath,
userDataProfilesMainService.defaultProfile.globalStorageHome.with({ scheme: Schemas.file }).fsPath,
environmentMainService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath,
environmentMainService.localHistoryHome.with({ scheme: Schemas.file }).fsPath,
environmentMainService.backupHome
].map(path => path ? FSPromises.mkdir(path, { recursive: true }) : undefined)),
+1 -1
View File
@@ -121,7 +121,7 @@ class CliMain extends Disposable {
// Init folders
await Promise.all([
environmentService.appSettingsHome.fsPath,
environmentService.appSettingsHome.with({ scheme: Schemas.file }).fsPath,
environmentService.extensionsPath
].map(path => path ? Promises.mkdir(path, { recursive: true }) : undefined));
@@ -6,7 +6,9 @@
import { RunOnceScheduler } from 'vs/base/common/async';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Disposable } from 'vs/base/common/lifecycle';
import { basename, dirname, joinPath } from 'vs/base/common/resources';
import { Schemas } from 'vs/base/common/network';
import { join } from 'vs/base/common/path';
import { basename, dirname } from 'vs/base/common/resources';
import { Promises } from 'vs/base/node/pfs';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogService } from 'vs/platform/log/common/log';
@@ -30,9 +32,8 @@ export class LogsDataCleaner extends Disposable {
try {
const currentLog = basename(this.environmentService.logsHome);
const logsRoot = dirname(this.environmentService.logsHome);
const logFiles = await Promises.readdir(logsRoot.fsPath);
const logsRoot = dirname(this.environmentService.logsHome.with({ scheme: Schemas.file })).fsPath;
const logFiles = await Promises.readdir(logsRoot);
const allSessions = logFiles.filter(logFile => /^\d{8}T\d{6}$/.test(logFile));
const oldSessions = allSessions.sort().filter(session => session !== currentLog);
@@ -41,7 +42,7 @@ export class LogsDataCleaner extends Disposable {
if (sessionsToDelete.length > 0) {
this.logService.trace(`[logs cleanup]: Removing log folders '${sessionsToDelete.join(', ')}'`);
await Promise.all(sessionsToDelete.map(sessionToDelete => Promises.rm(joinPath(logsRoot, sessionToDelete).fsPath)));
await Promise.all(sessionsToDelete.map(sessionToDelete => Promises.rm(join(logsRoot, sessionToDelete))));
}
} catch (error) {
onUnexpectedError(error);
@@ -15,6 +15,7 @@ import { EXTENSION_DEVELOPMENT_EMPTY_WINDOW_WORKSPACE } from 'vs/platform/worksp
import { NON_EMPTY_WORKSPACE_ID_LENGTH } from 'vs/platform/workspaces/node/workspaces';
import { INativeHostService } from 'vs/platform/native/common/native';
import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService';
import { Schemas } from 'vs/base/common/network';
export class UnusedWorkspaceStorageDataCleaner extends Disposable {
@@ -36,11 +37,12 @@ export class UnusedWorkspaceStorageDataCleaner extends Disposable {
this.logService.trace('[storage cleanup]: Starting to clean up workspace storage folders for unused empty workspaces.');
try {
const workspaceStorageFolders = await Promises.readdir(this.environmentService.workspaceStorageHome.fsPath);
const workspaceStorageHome = this.environmentService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath;
const workspaceStorageFolders = await Promises.readdir(workspaceStorageHome);
const storageClient = new StorageClient(this.mainProcessService.getChannel('storage'));
await Promise.all(workspaceStorageFolders.map(async workspaceStorageFolder => {
const workspaceStoragePath = join(this.environmentService.workspaceStorageHome.fsPath, workspaceStorageFolder);
const workspaceStoragePath = join(workspaceStorageHome, workspaceStorageFolder);
if (workspaceStorageFolder.length === NON_EMPTY_WORKSPACE_ID_LENGTH) {
return; // keep workspace storage for folders/workspaces that can be accessed still
@@ -41,12 +41,42 @@ export class ElementSizeObserver extends Disposable {
public startObserving(): void {
if (!this._resizeObserver && this._referenceDomElement) {
this._resizeObserver = new ResizeObserver((entries) => {
if (entries && entries[0] && entries[0].contentRect) {
this.observe({ width: entries[0].contentRect.width, height: entries[0].contentRect.height });
// We want to react to the resize observer only once per animation frame
// The first time the resize observer fires, we will react to it immediately.
// Otherwise we will postpone to the next animation frame.
// We'll use `observeContentRect` to store the content rect we received.
let observeContentRect: DOMRectReadOnly | null = null;
const observeNow = () => {
if (observeContentRect) {
this.observe({ width: observeContentRect.width, height: observeContentRect.height });
} else {
this.observe();
}
};
let shouldObserve = false;
let alreadyObservedThisAnimationFrame = false;
const update = () => {
if (shouldObserve && !alreadyObservedThisAnimationFrame) {
try {
shouldObserve = false;
alreadyObservedThisAnimationFrame = true;
observeNow();
} finally {
requestAnimationFrame(() => {
alreadyObservedThisAnimationFrame = false;
update();
});
}
}
};
this._resizeObserver = new ResizeObserver((entries) => {
observeContentRect = (entries && entries[0] && entries[0].contentRect ? entries[0].contentRect : null);
shouldObserve = true;
update();
});
this._resizeObserver.observe(this._referenceDomElement);
}
@@ -26,7 +26,8 @@ import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer';
import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';
import { ILinesDiffComputerOptions, LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { ILinesDiffComputerOptions, MovedText } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping, RangeMapping, LineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { LineRange } from 'vs/editor/common/core/lineRange';
/**
@@ -107,15 +108,15 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ
quitEarly: result.quitEarly,
changes: toLineRangeMappings(result.changes),
moves: result.moves.map(m => new MovedText(
new SimpleLineRangeMapping(new LineRange(m[0], m[1]), new LineRange(m[2], m[3])),
new LineRangeMapping(new LineRange(m[0], m[1]), new LineRange(m[2], m[3])),
toLineRangeMappings(m[4])
))
};
return diff;
function toLineRangeMappings(changes: readonly ILineChange[]): readonly LineRangeMapping[] {
function toLineRangeMappings(changes: readonly ILineChange[]): readonly DetailedLineRangeMapping[] {
return changes.map(
(c) => new LineRangeMapping(
(c) => new DetailedLineRangeMapping(
new LineRange(c[0], c[1]),
new LineRange(c[2], c[3]),
c[4]?.map(
@@ -17,6 +17,7 @@ import { EditorTheme } from 'vs/editor/common/editorTheme';
import * as viewEvents from 'vs/editor/common/viewEvents';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { OverviewRulerDecorationsGroup } from 'vs/editor/common/viewModel';
import { equals } from 'vs/base/common/arrays';
class Settings {
@@ -212,13 +213,24 @@ const enum OverviewRulerLane {
Full = 7
}
const enum ShouldRenderValue {
NotNeeded = 0,
Maybe = 1,
Needed = 2
}
export class DecorationsOverviewRuler extends ViewPart {
private _actualShouldRender: ShouldRenderValue = ShouldRenderValue.NotNeeded;
private readonly _tokensColorTrackerListener: IDisposable;
private readonly _domNode: FastDomNode<HTMLCanvasElement>;
private _settings!: Settings;
private _cursorPositions: Position[];
private _renderedDecorations: OverviewRulerDecorationsGroup[] = [];
private _renderedCursorPositions: Position[] = [];
constructor(context: ViewContext) {
super(context);
@@ -270,8 +282,18 @@ export class DecorationsOverviewRuler extends ViewPart {
// ---- begin view event handlers
private _markRenderingIsNeeded(): true {
this._actualShouldRender = ShouldRenderValue.Needed;
return true;
}
private _markRenderingIsMaybeNeeded(): true {
this._actualShouldRender = ShouldRenderValue.Maybe;
return true;
}
public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean {
return this._updateSettings(false);
return this._updateSettings(false) ? this._markRenderingIsNeeded() : false;
}
public override onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean {
this._cursorPositions = [];
@@ -279,25 +301,25 @@ export class DecorationsOverviewRuler extends ViewPart {
this._cursorPositions[i] = e.selections[i].getPosition();
}
this._cursorPositions.sort(Position.compare);
return true;
return this._markRenderingIsMaybeNeeded();
}
public override onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean {
if (e.affectsOverviewRuler) {
return true;
return this._markRenderingIsMaybeNeeded();
}
return false;
}
public override onFlushed(e: viewEvents.ViewFlushedEvent): boolean {
return true;
return this._markRenderingIsNeeded();
}
public override onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean {
return e.scrollHeightChanged;
return e.scrollHeightChanged ? this._markRenderingIsNeeded() : false;
}
public override onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean {
return true;
return this._markRenderingIsNeeded();
}
public override onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean {
return this._updateSettings(false);
return this._updateSettings(false) ? this._markRenderingIsNeeded() : false;
}
// ---- end view event handlers
@@ -312,6 +334,7 @@ export class DecorationsOverviewRuler extends ViewPart {
public render(editorCtx: RestrictedRenderingContext): void {
this._render();
this._actualShouldRender = ShouldRenderValue.NotNeeded;
}
private _render(): void {
@@ -322,6 +345,23 @@ export class DecorationsOverviewRuler extends ViewPart {
this._domNode.setDisplay('none');
return;
}
const decorations = this._context.viewModel.getAllOverviewRulerDecorations(this._context.theme);
decorations.sort(OverviewRulerDecorationsGroup.cmp);
if (this._actualShouldRender === ShouldRenderValue.Maybe && !OverviewRulerDecorationsGroup.equalsArr(this._renderedDecorations, decorations)) {
this._actualShouldRender = ShouldRenderValue.Needed;
}
if (this._actualShouldRender === ShouldRenderValue.Maybe && !equals(this._renderedCursorPositions, this._cursorPositions, (a, b) => a.lineNumber === b.lineNumber)) {
this._actualShouldRender = ShouldRenderValue.Needed;
}
if (this._actualShouldRender === ShouldRenderValue.Maybe) {
// both decorations and cursor positions are unchanged, nothing to do
return;
}
this._renderedDecorations = decorations;
this._renderedCursorPositions = this._cursorPositions;
this._domNode.setDisplay('block');
const canvasWidth = this._settings.canvasWidth;
const canvasHeight = this._settings.canvasHeight;
@@ -329,7 +369,6 @@ export class DecorationsOverviewRuler extends ViewPart {
const viewLayout = this._context.viewLayout;
const outerHeight = this._context.viewLayout.getScrollHeight();
const heightRatio = canvasHeight / outerHeight;
const decorations = this._context.viewModel.getAllOverviewRulerDecorations(this._context.theme);
const minDecorationHeight = (Constants.MIN_DECORATION_HEIGHT * this._settings.pixelRatio) | 0;
const halfMinDecorationHeight = (minDecorationHeight / 2) | 0;
@@ -355,7 +394,7 @@ export class DecorationsOverviewRuler extends ViewPart {
const x = this._settings.x;
const w = this._settings.w;
decorations.sort(OverviewRulerDecorationsGroup.cmp);
for (const decorationGroup of decorations) {
const color = decorationGroup.color;
@@ -297,7 +297,14 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
diffAlgorithm: 'advanced',
accessibilityVerbose: false,
experimental: {
collapseUnchangedRegions: false,
showEmptyDecorations: false,
showMoves: false,
},
hideUnchangedRegions: {
enabled: false,
contextLineCount: 0,
minimumLineCount: 0,
revealLineCount: 0,
},
isInEmbeddedEditor: false,
onlyShowAccessibleDiffViewer: false,
@@ -1205,24 +1212,24 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE
let modifiedEndLineNumber: number;
let innerChanges = m.innerChanges;
if (m.originalRange.isEmpty) {
if (m.original.isEmpty) {
// Insertion
originalStartLineNumber = m.originalRange.startLineNumber - 1;
originalStartLineNumber = m.original.startLineNumber - 1;
originalEndLineNumber = 0;
innerChanges = undefined;
} else {
originalStartLineNumber = m.originalRange.startLineNumber;
originalEndLineNumber = m.originalRange.endLineNumberExclusive - 1;
originalStartLineNumber = m.original.startLineNumber;
originalEndLineNumber = m.original.endLineNumberExclusive - 1;
}
if (m.modifiedRange.isEmpty) {
if (m.modified.isEmpty) {
// Deletion
modifiedStartLineNumber = m.modifiedRange.startLineNumber - 1;
modifiedStartLineNumber = m.modified.startLineNumber - 1;
modifiedEndLineNumber = 0;
innerChanges = undefined;
} else {
modifiedStartLineNumber = m.modifiedRange.startLineNumber;
modifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive - 1;
modifiedStartLineNumber = m.modified.startLineNumber;
modifiedEndLineNumber = m.modified.endLineNumberExclusive - 1;
}
return {
@@ -2743,8 +2750,15 @@ function validateDiffEditorOptions(options: Readonly<IDiffEditorOptions>, defaul
diffWordWrap: validateDiffWordWrap(options.diffWordWrap, defaults.diffWordWrap),
diffAlgorithm: validateStringSetOption(options.diffAlgorithm, defaults.diffAlgorithm, ['legacy', 'advanced'], { 'smart': 'legacy', 'experimental': 'advanced' }),
accessibilityVerbose: validateBooleanOption(options.accessibilityVerbose, defaults.accessibilityVerbose),
hideUnchangedRegions: {
enabled: false,
contextLineCount: 0,
minimumLineCount: 0,
revealLineCount: 0,
},
experimental: {
collapseUnchangedRegions: false,
showEmptyDecorations: false,
showMoves: false,
},
isInEmbeddedEditor: validateBooleanOption(options.isInEmbeddedEditor, defaults.isInEmbeddedEditor),
onlyShowAccessibleDiffViewer: false,
@@ -21,7 +21,7 @@ import { LineRange } from 'vs/editor/common/core/lineRange';
import { OffsetRange } from 'vs/editor/common/core/offsetRange';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { LineRangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping, LineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { ILanguageIdCodec } from 'vs/editor/common/languages';
import { ILanguageService } from 'vs/editor/common/languages/language';
import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model';
@@ -45,7 +45,7 @@ export class AccessibleDiffViewer extends Disposable {
private readonly _canClose: IObservable<boolean>,
private readonly _width: IObservable<number>,
private readonly _height: IObservable<number>,
private readonly _diffs: IObservable<LineRangeMapping[] | undefined>,
private readonly _diffs: IObservable<DetailedLineRangeMapping[] | undefined>,
private readonly _editors: DiffEditorEditors,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
) {
@@ -105,7 +105,7 @@ class ViewModel extends Disposable {
= this._currentElementIdx.map((idx, r) => this.currentGroup.read(r)?.lines[idx]);
constructor(
private readonly _diffs: IObservable<LineRangeMapping[] | undefined>,
private readonly _diffs: IObservable<DetailedLineRangeMapping[] | undefined>,
private readonly _editors: DiffEditorEditors,
private readonly _setVisible: (visible: boolean, tx: ITransaction | undefined) => void,
public readonly canClose: IObservable<boolean>,
@@ -154,7 +154,7 @@ class ViewModel extends Disposable {
// This ensures editor commands (like revert/stage) work
const currentViewItem = this.currentElement.read(reader);
if (currentViewItem && currentViewItem.type !== LineType.Header) {
const lineNumber = currentViewItem.modifiedLineNumber ?? currentViewItem.diff.modifiedRange.startLineNumber;
const lineNumber = currentViewItem.modifiedLineNumber ?? currentViewItem.diff.modified.startLineNumber;
this._editors.modified.setSelection(Range.fromPositions(new Position(lineNumber, 1)));
}
}));
@@ -221,44 +221,44 @@ class ViewModel extends Disposable {
const viewElementGroupLineMargin = 3;
function computeViewElementGroups(diffs: LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): ViewElementGroup[] {
function computeViewElementGroups(diffs: DetailedLineRangeMapping[], originalLineCount: number, modifiedLineCount: number): ViewElementGroup[] {
const result: ViewElementGroup[] = [];
for (const g of group(diffs, (a, b) => (b.modifiedRange.startLineNumber - a.modifiedRange.endLineNumberExclusive < 2 * viewElementGroupLineMargin))) {
for (const g of group(diffs, (a, b) => (b.modified.startLineNumber - a.modified.endLineNumberExclusive < 2 * viewElementGroupLineMargin))) {
const viewElements: ViewElement[] = [];
viewElements.push(new HeaderViewElement());
const origFullRange = new LineRange(
Math.max(1, g[0].originalRange.startLineNumber - viewElementGroupLineMargin),
Math.min(g[g.length - 1].originalRange.endLineNumberExclusive + viewElementGroupLineMargin, originalLineCount + 1)
Math.max(1, g[0].original.startLineNumber - viewElementGroupLineMargin),
Math.min(g[g.length - 1].original.endLineNumberExclusive + viewElementGroupLineMargin, originalLineCount + 1)
);
const modifiedFullRange = new LineRange(
Math.max(1, g[0].modifiedRange.startLineNumber - viewElementGroupLineMargin),
Math.min(g[g.length - 1].modifiedRange.endLineNumberExclusive + viewElementGroupLineMargin, modifiedLineCount + 1)
Math.max(1, g[0].modified.startLineNumber - viewElementGroupLineMargin),
Math.min(g[g.length - 1].modified.endLineNumberExclusive + viewElementGroupLineMargin, modifiedLineCount + 1)
);
forEachAdjacentItems(g, (a, b) => {
const origRange = new LineRange(a ? a.originalRange.endLineNumberExclusive : origFullRange.startLineNumber, b ? b.originalRange.startLineNumber : origFullRange.endLineNumberExclusive);
const modifiedRange = new LineRange(a ? a.modifiedRange.endLineNumberExclusive : modifiedFullRange.startLineNumber, b ? b.modifiedRange.startLineNumber : modifiedFullRange.endLineNumberExclusive);
const origRange = new LineRange(a ? a.original.endLineNumberExclusive : origFullRange.startLineNumber, b ? b.original.startLineNumber : origFullRange.endLineNumberExclusive);
const modifiedRange = new LineRange(a ? a.modified.endLineNumberExclusive : modifiedFullRange.startLineNumber, b ? b.modified.startLineNumber : modifiedFullRange.endLineNumberExclusive);
origRange.forEach(origLineNumber => {
viewElements.push(new UnchangedLineViewElement(origLineNumber, modifiedRange.startLineNumber + (origLineNumber - origRange.startLineNumber)));
});
if (b) {
b.originalRange.forEach(origLineNumber => {
b.original.forEach(origLineNumber => {
viewElements.push(new DeletedLineViewElement(b, origLineNumber));
});
b.modifiedRange.forEach(modifiedLineNumber => {
b.modified.forEach(modifiedLineNumber => {
viewElements.push(new AddedLineViewElement(b, modifiedLineNumber));
});
}
});
const modifiedRange = g[0].modifiedRange.join(g[g.length - 1].modifiedRange);
const originalRange = g[0].originalRange.join(g[g.length - 1].originalRange);
const modifiedRange = g[0].modified.join(g[g.length - 1].modified);
const originalRange = g[0].original.join(g[g.length - 1].original);
result.push(new ViewElementGroup(new SimpleLineRangeMapping(modifiedRange, originalRange), viewElements));
result.push(new ViewElementGroup(new LineRangeMapping(modifiedRange, originalRange), viewElements));
}
return result;
}
@@ -272,7 +272,7 @@ enum LineType {
class ViewElementGroup {
constructor(
public readonly range: SimpleLineRangeMapping,
public readonly range: LineRangeMapping,
public readonly lines: readonly ViewElement[],
) { }
}
@@ -289,7 +289,7 @@ class DeletedLineViewElement {
public readonly modifiedLineNumber = undefined;
constructor(
public readonly diff: LineRangeMapping,
public readonly diff: DetailedLineRangeMapping,
public readonly originalLineNumber: number,
) {
}
@@ -301,7 +301,7 @@ class AddedLineViewElement {
public readonly originalLineNumber = undefined;
constructor(
public readonly diff: LineRangeMapping,
public readonly diff: DetailedLineRangeMapping,
public readonly modifiedLineNumber: number,
) {
}
@@ -42,45 +42,45 @@ export class DiffEditorDecorations extends Disposable {
const modifiedDecorations: IModelDeltaDecoration[] = [];
if (!movedTextToCompare) {
for (const m of diff.mappings) {
if (!m.lineRangeMapping.originalRange.isEmpty) {
originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground });
if (!m.lineRangeMapping.original.isEmpty) {
originalDecorations.push({ range: m.lineRangeMapping.original.toInclusiveRange()!, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground });
}
if (!m.lineRangeMapping.modifiedRange.isEmpty) {
modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground });
if (!m.lineRangeMapping.modified.isEmpty) {
modifiedDecorations.push({ range: m.lineRangeMapping.modified.toInclusiveRange()!, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground });
}
if (m.lineRangeMapping.modifiedRange.isEmpty || m.lineRangeMapping.originalRange.isEmpty) {
if (!m.lineRangeMapping.originalRange.isEmpty) {
originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: diffWholeLineDeleteDecoration });
if (m.lineRangeMapping.modified.isEmpty || m.lineRangeMapping.original.isEmpty) {
if (!m.lineRangeMapping.original.isEmpty) {
originalDecorations.push({ range: m.lineRangeMapping.original.toInclusiveRange()!, options: diffWholeLineDeleteDecoration });
}
if (!m.lineRangeMapping.modifiedRange.isEmpty) {
modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: diffWholeLineAddDecoration });
if (!m.lineRangeMapping.modified.isEmpty) {
modifiedDecorations.push({ range: m.lineRangeMapping.modified.toInclusiveRange()!, options: diffWholeLineAddDecoration });
}
} else {
for (const i of m.lineRangeMapping.innerChanges || []) {
// Don't show empty markers outside the line range
if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) {
if (m.lineRangeMapping.original.contains(i.originalRange.startLineNumber)) {
originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration });
}
if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) {
if (m.lineRangeMapping.modified.contains(i.modifiedRange.startLineNumber)) {
modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration });
}
}
}
if (!m.lineRangeMapping.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !movedTextToCompare) {
modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modifiedRange.startLineNumber, 1)), options: arrowRevertChange });
if (!m.lineRangeMapping.modified.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !movedTextToCompare) {
modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modified.startLineNumber, 1)), options: arrowRevertChange });
}
}
}
if (movedTextToCompare) {
for (const m of movedTextToCompare.changes) {
const fullRangeOriginal = m.originalRange.toInclusiveRange();
const fullRangeOriginal = m.original.toInclusiveRange();
if (fullRangeOriginal) {
originalDecorations.push({ range: fullRangeOriginal, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground });
}
const fullRangeModified = m.modifiedRange.toInclusiveRange();
const fullRangeModified = m.modified.toInclusiveRange();
if (fullRangeModified) {
modifiedDecorations.push({ range: fullRangeModified, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground });
}
@@ -147,7 +147,7 @@ export class DiffEditorEditors extends Disposable {
clonedOptions.minimap = { ...(clonedOptions.minimap || {}) };
clonedOptions.minimap.enabled = false;
if (this._options.collapseUnchangedRegions.get()) {
if (this._options.hideUnchangedRegions.get()) {
clonedOptions.stickyScroll = { enabled: false };
} else {
clonedOptions.stickyScroll = this._options.editorOptions.get().stickyScroll;
@@ -6,6 +6,7 @@
import { IObservable, ISettableObservable, derived, observableValue } from 'vs/base/common/observable';
import { Constants } from 'vs/base/common/uint';
import { IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser';
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';
export class DiffEditorOptions {
@@ -37,7 +38,6 @@ export class DiffEditorOptions {
});
public readonly renderIndicators = derived(reader => /** @description renderIndicators */ this._options.read(reader).renderIndicators);
public readonly enableSplitViewResizing = derived(reader => /** @description enableSplitViewResizing */ this._options.read(reader).enableSplitViewResizing);
public readonly collapseUnchangedRegions = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).experimental.collapseUnchangedRegions!);
public readonly splitViewDefaultRatio = derived(reader => /** @description splitViewDefaultRatio */ this._options.read(reader).splitViewDefaultRatio);
public readonly ignoreTrimWhitespace = derived(reader => /** @description ignoreTrimWhitespace */ this._options.read(reader).ignoreTrimWhitespace);
public readonly maxComputationTimeMs = derived(reader => /** @description maxComputationTime */ this._options.read(reader).maxComputationTime);
@@ -51,6 +51,11 @@ export class DiffEditorOptions {
public readonly showEmptyDecorations = derived(reader => /** @description showEmptyDecorations */ this._options.read(reader).experimental.showEmptyDecorations!);
public readonly onlyShowAccessibleDiffViewer = derived(reader => /** @description onlyShowAccessibleDiffViewer */ this._options.read(reader).onlyShowAccessibleDiffViewer);
public readonly hideUnchangedRegions = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.enabled!);
public readonly hideUnchangedRegionsRevealLineCount = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.revealLineCount!);
public readonly hideUnchangedRegionsContextLineCount = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.contextLineCount!);
public readonly hideUnchangedRegionsminimumLineCount = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.minimumLineCount!);
public updateOptions(changedOptions: IDiffEditorOptions): void {
const newDiffEditorOptions = validateDiffEditorOptions(changedOptions, this._options.get());
const newOptions = { ...this._options.get(), ...changedOptions, ...newDiffEditorOptions };
@@ -58,32 +63,6 @@ export class DiffEditorOptions {
}
}
const diffEditorDefaultOptions: ValidDiffEditorBaseOptions = {
enableSplitViewResizing: true,
splitViewDefaultRatio: 0.5,
renderSideBySide: true,
renderMarginRevertIcon: true,
maxComputationTime: 5000,
maxFileSize: 50,
ignoreTrimWhitespace: true,
renderIndicators: true,
originalEditable: false,
diffCodeLens: false,
renderOverviewRuler: true,
diffWordWrap: 'inherit',
diffAlgorithm: 'advanced',
accessibilityVerbose: false,
experimental: {
collapseUnchangedRegions: false,
showMoves: false,
showEmptyDecorations: true,
},
isInEmbeddedEditor: false,
onlyShowAccessibleDiffViewer: false,
renderSideBySideInlineBreakpoint: 900,
useInlineViewWhenSpaceIsLimited: true,
};
function validateDiffEditorOptions(options: Readonly<IDiffEditorOptions>, defaults: ValidDiffEditorBaseOptions): ValidDiffEditorBaseOptions {
return {
enableSplitViewResizing: validateBooleanOption(options.enableSplitViewResizing, defaults.enableSplitViewResizing),
@@ -101,10 +80,15 @@ function validateDiffEditorOptions(options: Readonly<IDiffEditorOptions>, defaul
diffAlgorithm: validateStringSetOption(options.diffAlgorithm, defaults.diffAlgorithm, ['legacy', 'advanced'], { 'smart': 'legacy', 'experimental': 'advanced' }),
accessibilityVerbose: validateBooleanOption(options.accessibilityVerbose, defaults.accessibilityVerbose),
experimental: {
collapseUnchangedRegions: validateBooleanOption(options.experimental?.collapseUnchangedRegions, defaults.experimental.collapseUnchangedRegions!),
showMoves: validateBooleanOption(options.experimental?.showMoves, defaults.experimental.showMoves!),
showEmptyDecorations: validateBooleanOption(options.experimental?.showEmptyDecorations, defaults.experimental.showEmptyDecorations!),
},
hideUnchangedRegions: {
enabled: validateBooleanOption(options.hideUnchangedRegions?.enabled ?? (options.experimental as any)?.collapseUnchangedRegions, defaults.hideUnchangedRegions.enabled!),
contextLineCount: clampedInt(options.hideUnchangedRegions?.contextLineCount, defaults.hideUnchangedRegions.contextLineCount!, 0, Constants.MAX_SAFE_SMALL_INTEGER),
minimumLineCount: clampedInt(options.hideUnchangedRegions?.minimumLineCount, defaults.hideUnchangedRegions.minimumLineCount!, 0, Constants.MAX_SAFE_SMALL_INTEGER),
revealLineCount: clampedInt(options.hideUnchangedRegions?.revealLineCount, defaults.hideUnchangedRegions.revealLineCount!, 0, Constants.MAX_SAFE_SMALL_INTEGER),
},
isInEmbeddedEditor: validateBooleanOption(options.isInEmbeddedEditor, defaults.isInEmbeddedEditor),
onlyShowAccessibleDiffViewer: validateBooleanOption(options.onlyShowAccessibleDiffViewer, defaults.onlyShowAccessibleDiffViewer),
renderSideBySideInlineBreakpoint: clampedInt(options.renderSideBySideInlineBreakpoint, defaults.renderSideBySideInlineBreakpoint, 0, Constants.MAX_SAFE_SMALL_INTEGER),
@@ -4,22 +4,20 @@
*--------------------------------------------------------------------------------------------*/
import { RunOnceScheduler } from 'vs/base/common/async';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IObservable, IReader, ISettableObservable, ITransaction, autorunWithStore, derived, observableSignal, observableSignalFromEvent, observableValue, transaction, waitForState } from 'vs/base/common/observable';
import { isDefined } from 'vs/base/common/types';
import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils';
import { ISerializedLineRange, LineRange } from 'vs/editor/common/core/lineRange';
import { Range } from 'vs/editor/common/core/range';
import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer';
import { IDocumentDiff, IDocumentDiffProvider } from 'vs/editor/common/diff/documentDiffProvider';
import { LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { AdvancedLinesDiffComputer, lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/advancedLinesDiffComputer';
import { MovedText } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { IDiffEditorModel, IDiffEditorViewModel } from 'vs/editor/common/editorCommon';
import { ITextModel } from 'vs/editor/common/model';
import { TextEditInfo } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper';
import { combineTextEditInfos } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos';
import { lengthAdd, lengthDiffNonNegative, lengthGetLineCount, lengthOfRange, lengthToPosition, lengthZero, positionToLength } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length';
import { DiffEditorOptions } from './diffEditorOptions';
import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
export class DiffEditorViewModel extends Disposable implements IDiffEditorViewModel {
private readonly _isDiffUpToDate = observableValue<boolean>('isDiffUpToDate', false);
@@ -35,13 +33,13 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo
);
public readonly unchangedRegions: IObservable<UnchangedRegion[]> = derived(r => {
/** @description unchangedRegions */
if (this._options.collapseUnchangedRegions.read(r)) {
if (this._options.hideUnchangedRegions.read(r)) {
return this._unchangedRegions.read(r).regions;
} else {
// Reset state
transaction(tx => {
for (const r of this._unchangedRegions.get().regions) {
r.setState(0, 0, tx);
r.collapseAll(tx);
}
});
return [];
@@ -79,8 +77,14 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo
const contentChangedSignal = observableSignal('contentChangedSignal');
const debouncer = this._register(new RunOnceScheduler(() => contentChangedSignal.trigger(undefined), 200));
const updateUnchangedRegions = (result: IDocumentDiff, tx: ITransaction) => {
const newUnchangedRegions = UnchangedRegion.fromDiffs(result.changes, model.original.getLineCount(), model.modified.getLineCount());
const updateUnchangedRegions = (result: IDocumentDiff, tx: ITransaction, reader?: IReader) => {
const newUnchangedRegions = UnchangedRegion.fromDiffs(
result.changes,
model.original.getLineCount(),
model.modified.getLineCount(),
this._options.hideUnchangedRegionsminimumLineCount.read(reader),
this._options.hideUnchangedRegionsContextLineCount.read(reader),
);
// Transfer state from cur state
const lastUnchangedRegions = this._unchangedRegions.get();
@@ -122,7 +126,6 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo
);
};
this._register(model.modified.onDidChangeContent((e) => {
const diff = this._diff.get();
if (diff) {
@@ -164,6 +167,11 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo
this._register(autorunWithStore(async (reader, store) => {
/** @description compute diff */
// So that they get recomputed when these settings change
this._options.hideUnchangedRegionsminimumLineCount.read(reader);
this._options.hideUnchangedRegionsContextLineCount.read(reader);
debouncer.cancel();
contentChangedSignal.read(reader);
documentDiffProviderOptionChanged.read(reader);
@@ -286,7 +294,7 @@ export class DiffState {
export class DiffMapping {
constructor(
readonly lineRangeMapping: LineRangeMapping,
readonly lineRangeMapping: DetailedLineRangeMapping,
) {
/*
readonly movedTo: MovedText | undefined,
@@ -310,22 +318,25 @@ export class DiffMapping {
}
export class UnchangedRegion {
public static fromDiffs(changes: readonly LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): UnchangedRegion[] {
const inversedMappings = LineRangeMapping.inverse(changes, originalLineCount, modifiedLineCount);
public static fromDiffs(
changes: readonly DetailedLineRangeMapping[],
originalLineCount: number,
modifiedLineCount: number,
minHiddenLineCount: number,
minContext: number,
): UnchangedRegion[] {
const inversedMappings = DetailedLineRangeMapping.inverse(changes, originalLineCount, modifiedLineCount);
const result: UnchangedRegion[] = [];
const minHiddenLineCount = 3;
const minContext = 3;
for (const mapping of inversedMappings) {
let origStart = mapping.originalRange.startLineNumber;
let modStart = mapping.modifiedRange.startLineNumber;
let length = mapping.originalRange.length;
let origStart = mapping.original.startLineNumber;
let modStart = mapping.modified.startLineNumber;
let length = mapping.original.length;
const atStart = origStart === 1 && modStart === 1;
const atEnd = origStart + length === originalLineCount + 1 && modStart + length === modifiedLineCount + 1;
if ((atStart || atEnd) && length > minContext + minHiddenLineCount) {
if ((atStart || atEnd) && length >= minContext + minHiddenLineCount) {
if (atStart && !atEnd) {
length -= minContext;
}
@@ -335,7 +346,7 @@ export class UnchangedRegion {
length -= minContext;
}
result.push(new UnchangedRegion(origStart, modStart, length, 0, 0));
} else if (length > minContext * 2 + minHiddenLineCount) {
} else if (length >= minContext * 2 + minHiddenLineCount) {
origStart += minContext;
modStart += minContext;
length -= minContext * 2;
@@ -441,6 +452,11 @@ export class UnchangedRegion {
}
}
public collapseAll(tx: ITransaction | undefined): void {
this._visibleLineCountTop.set(0, tx);
this._visibleLineCountBottom.set(0, tx);
}
public setState(visibleLineCountTop: number, visibleLineCountBottom: number, tx: ITransaction | undefined): void {
visibleLineCountTop = Math.max(Math.min(visibleLineCountTop, this.lineCount), 0);
visibleLineCountBottom = Math.max(Math.min(visibleLineCountBottom, this.lineCount - visibleLineCountTop), 0);
@@ -451,6 +467,9 @@ export class UnchangedRegion {
}
function applyOriginalEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], originalTextModel: ITextModel, modifiedTextModel: ITextModel): IDocumentDiff | undefined {
return undefined;
/*
TODO@hediet
if (textEdits.length === 0) {
return diff;
}
@@ -460,9 +479,9 @@ function applyOriginalEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], orig
if (!diff3) {
return undefined;
}
return flip(diff3);
return flip(diff3);*/
}
/*
function flip(diff: IDocumentDiff): IDocumentDiff {
return {
changes: diff.changes.map(c => c.flip()),
@@ -471,8 +490,11 @@ function flip(diff: IDocumentDiff): IDocumentDiff {
quitEarly: diff.quitEarly,
};
}
*/
function applyModifiedEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], originalTextModel: ITextModel, modifiedTextModel: ITextModel): IDocumentDiff | undefined {
return undefined;
/*
TODO@hediet
if (textEdits.length === 0) {
return diff;
}
@@ -496,9 +518,9 @@ function applyModifiedEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], orig
quitEarly: false,
changes,
moves,
};
};*/
}
/*
function applyEditToLineRange(range: LineRange, textEdits: TextEditInfo[]): LineRange | undefined {
let rangeStartLineNumber = range.startLineNumber;
let rangeEndLineNumberEx = range.endLineNumberExclusive;
@@ -565,3 +587,4 @@ function applyModifiedEditsToLineRangeMappings(changes: readonly LineRangeMappin
);
return newChanges;
}
*/
@@ -23,7 +23,7 @@ export class ToggleCollapseUnchangedRegions extends Action2 {
title: { value: localize('toggleCollapseUnchangedRegions', "Toggle Collapse Unchanged Regions"), original: 'Toggle Collapse Unchanged Regions' },
icon: Codicon.map,
precondition: ContextKeyEqualsExpr.create('diffEditorVersion', 2),
toggled: ContextKeyExpr.has('config.diffEditor.experimental.collapseUnchangedRegions'),
toggled: ContextKeyExpr.has('config.diffEditor.hideUnchangedRegions.enabled'),
menu: {
id: MenuId.EditorTitle,
order: 22,
@@ -35,8 +35,8 @@ export class ToggleCollapseUnchangedRegions extends Action2 {
run(accessor: ServicesAccessor, ...args: unknown[]): void {
const configurationService = accessor.get(IConfigurationService);
const newValue = !configurationService.getValue<boolean>('diffEditor.experimental.collapseUnchangedRegions');
configurationService.updateValue('diffEditor.experimental.collapseUnchangedRegions', newValue);
const newValue = !configurationService.getValue<boolean>('diffEditor.hideUnchangedRegions.enabled');
configurationService.updateValue('diffEditor.hideUnchangedRegions.enabled', newValue);
}
}
@@ -108,6 +108,7 @@ const diffEditorCategory: ILocalizedString = {
value: localize('diffEditor', 'Diff Editor'),
original: 'Diff Editor',
};
export class SwitchSide extends EditorAction2 {
constructor() {
super({
@@ -160,3 +161,47 @@ export class ExitCompareMove extends EditorAction2 {
}
registerAction2(ExitCompareMove);
export class CollapseAllUnchangedRegions extends EditorAction2 {
constructor() {
super({
id: 'diffEditor.collapseAllUnchangedRegions',
title: { value: localize('collapseAllUnchangedRegions', "Collapse All Unchanged Regions"), original: 'Collapse All Unchanged Regions' },
icon: Codicon.fold,
precondition: ContextKeyExpr.and(ContextKeyEqualsExpr.create('diffEditorVersion', 2), ContextKeyExpr.has('isInDiffEditor')),
f1: true,
category: diffEditorCategory,
});
}
runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void {
const diffEditor = findFocusedDiffEditor(accessor);
if (diffEditor instanceof DiffEditorWidget2) {
diffEditor.collapseAllUnchangedRegions();
}
}
}
registerAction2(CollapseAllUnchangedRegions);
export class ShowAllUnchangedRegions extends EditorAction2 {
constructor() {
super({
id: 'diffEditor.showAllUnchangedRegions',
title: { value: localize('showAllUnchangedRegions', "Show All Unchanged Regions"), original: 'Show All Unchanged Regions' },
icon: Codicon.unfold,
precondition: ContextKeyExpr.and(ContextKeyEqualsExpr.create('diffEditorVersion', 2), ContextKeyExpr.has('isInDiffEditor')),
f1: true,
category: diffEditorCategory,
});
}
runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void {
const diffEditor = findFocusedDiffEditor(accessor);
if (diffEditor instanceof DiffEditorWidget2) {
diffEditor.showAllUnchangedRegions();
}
}
}
registerAction2(ShowAllUnchangedRegions);
@@ -29,7 +29,7 @@ import { IDimension } from 'vs/editor/common/core/dimension';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { CursorChangeReason } from 'vs/editor/common/cursorEvents';
import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer';
import { EditorType, IDiffEditorModel, IDiffEditorViewModel, IDiffEditorViewState } from 'vs/editor/common/editorCommon';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
@@ -45,6 +45,7 @@ import { DiffEditorEditors } from './diffEditorEditors';
import { DiffEditorOptions } from './diffEditorOptions';
import { DiffEditorViewModel, DiffMapping, DiffState } from './diffEditorViewModel';
import { toDisposable } from 'vs/base/common/lifecycle';
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
private readonly elements = h('div.monaco-diff-editor.side-by-side', { style: { position: 'relative', height: '100%' } }, [
@@ -81,7 +82,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
private readonly movedBlocksLinesPart = observableValue<MovedBlocksLinesPart | undefined>('MovedBlocksLinesPart', undefined);
public get collapseUnchangedRegions() { return this._options.collapseUnchangedRegions.get(); }
public get collapseUnchangedRegions() { return this._options.hideUnchangedRegions.get(); }
constructor(
private readonly _domElement: HTMLElement,
@@ -91,6 +92,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
@IInstantiationService private readonly _parentInstantiationService: IInstantiationService,
@ICodeEditorService codeEditorService: ICodeEditorService,
@IAudioCueService private readonly _audioCueService: IAudioCueService,
@IEditorProgressService private readonly _editorProgressService: IEditorProgressService,
) {
super();
codeEditorService.willCreateDiffEditor();
@@ -230,7 +232,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
this._register(applyStyle(this.elements.overlay, {
width: this._layoutInfo.map((i, r) => i.originalEditor.width + (this._options.renderSideBySide.read(r) ? 0 : i.modifiedEditor.width)),
visibility: derived(reader => /** @description visibility */(this._options.collapseUnchangedRegions.read(reader) && this._diffModel.read(reader)?.diff.read(reader)?.mappings.length === 0)
visibility: derived(reader => /** @description visibility */(this._options.hideUnchangedRegions.read(reader) && this._diffModel.read(reader)?.diff.read(reader)?.mappings.length === 0)
? 'visible' : 'hidden'
),
}));
@@ -246,8 +248,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
const diffs = model.diff.get()?.mappings;
if (!diffs) { return; }
const diff = diffs.find(d =>
viewZone?.detail.afterLineNumber === d.lineRangeMapping.modifiedRange.startLineNumber - 1 ||
d.lineRangeMapping.modifiedRange.startLineNumber === lineNumber
viewZone?.detail.afterLineNumber === d.lineRangeMapping.modified.startLineNumber - 1 ||
d.lineRangeMapping.modified.startLineNumber === lineNumber
);
if (!diff) { return; }
this.revert(diff.lineRangeMapping);
@@ -258,16 +260,24 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
this._register(Event.runAndSubscribe(this._editors.modified.onDidChangeCursorPosition, (e) => {
if (e?.reason === CursorChangeReason.Explicit) {
const diff = this._diffModel.get()?.diff.get()?.mappings.find(m => m.lineRangeMapping.modifiedRange.contains(e.position.lineNumber));
if (diff?.lineRangeMapping.modifiedRange.isEmpty) {
const diff = this._diffModel.get()?.diff.get()?.mappings.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber));
if (diff?.lineRangeMapping.modified.isEmpty) {
this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { source: 'diffEditor.cursorPositionChanged' });
} else if (diff?.lineRangeMapping.originalRange.isEmpty) {
} else if (diff?.lineRangeMapping.original.isEmpty) {
this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { source: 'diffEditor.cursorPositionChanged' });
} else if (diff) {
this._audioCueService.playAudioCue(AudioCue.diffLineModified, { source: 'diffEditor.cursorPositionChanged' });
}
}
}));
const isDiffUpToDate = this._diffModel.map((m, reader) => m?.isDiffUpToDate.read(reader));
this._register(autorunWithStore((reader, store) => {
if (isDiffUpToDate.read(reader) === false) {
const r = this._editorProgressService.show(true, 1000);
store.add(toDisposable(() => r.done()));
}
}));
}
public getContentHeight() {
@@ -426,7 +436,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
};
}
revert(diff: LineRangeMapping): void {
revert(diff: DetailedLineRangeMapping): void {
const model = this._diffModel.get()?.model;
if (!model) { return; }
@@ -437,8 +447,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
}))
: [
{
range: diff.modifiedRange.toExclusiveRange(),
text: model.original.getValueInRange(diff.originalRange.toExclusiveRange())
range: diff.modified.toExclusiveRange(),
text: model.original.getValueInRange(diff.original.toExclusiveRange())
}
];
@@ -446,8 +456,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
}
private _goTo(diff: DiffMapping): void {
this._editors.modified.setPosition(new Position(diff.lineRangeMapping.modifiedRange.startLineNumber, 1));
this._editors.modified.revealRangeInCenter(diff.lineRangeMapping.modifiedRange.toExclusiveRange());
this._editors.modified.setPosition(new Position(diff.lineRangeMapping.modified.startLineNumber, 1));
this._editors.modified.revealRangeInCenter(diff.lineRangeMapping.modified.toExclusiveRange());
}
goToDiff(target: 'previous' | 'next'): void {
@@ -460,15 +470,15 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
let diff: DiffMapping | undefined;
if (target === 'next') {
diff = diffs.find(d => d.lineRangeMapping.modifiedRange.startLineNumber > curLineNumber) ?? diffs[0];
diff = diffs.find(d => d.lineRangeMapping.modified.startLineNumber > curLineNumber) ?? diffs[0];
} else {
diff = findLast(diffs, d => d.lineRangeMapping.modifiedRange.startLineNumber < curLineNumber) ?? diffs[diffs.length - 1];
diff = findLast(diffs, d => d.lineRangeMapping.modified.startLineNumber < curLineNumber) ?? diffs[diffs.length - 1];
}
this._goTo(diff);
if (diff.lineRangeMapping.modifiedRange.isEmpty) {
if (diff.lineRangeMapping.modified.isEmpty) {
this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { source: 'diffEditor.goToDiff' });
} else if (diff.lineRangeMapping.originalRange.isEmpty) {
} else if (diff.lineRangeMapping.original.isEmpty) {
this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { source: 'diffEditor.goToDiff' });
} else if (diff) {
this._audioCueService.playAudioCue(AudioCue.diffLineModified, { source: 'diffEditor.goToDiff' });
@@ -532,28 +542,48 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor {
if (!model) { return; }
model.movedTextToCompare.set(undefined, undefined);
}
collapseAllUnchangedRegions(): void {
const unchangedRegions = this._diffModel.get()?.unchangedRegions.get();
if (!unchangedRegions) { return; }
transaction(tx => {
for (const region of unchangedRegions) {
region.collapseAll(tx);
}
});
}
showAllUnchangedRegions(): void {
const unchangedRegions = this._diffModel.get()?.unchangedRegions.get();
if (!unchangedRegions) { return; }
transaction(tx => {
for (const region of unchangedRegions) {
region.showAll(tx);
}
});
}
}
function translatePosition(posInOriginal: Position, mappings: LineRangeMapping[]): Range {
const mapping = findLast(mappings, m => m.originalRange.startLineNumber <= posInOriginal.lineNumber);
function translatePosition(posInOriginal: Position, mappings: DetailedLineRangeMapping[]): Range {
const mapping = findLast(mappings, m => m.original.startLineNumber <= posInOriginal.lineNumber);
if (!mapping) {
// No changes before the position
return Range.fromPositions(posInOriginal);
}
if (mapping.originalRange.endLineNumberExclusive <= posInOriginal.lineNumber) {
const newLineNumber = posInOriginal.lineNumber - mapping.originalRange.endLineNumberExclusive + mapping.modifiedRange.endLineNumberExclusive;
if (mapping.original.endLineNumberExclusive <= posInOriginal.lineNumber) {
const newLineNumber = posInOriginal.lineNumber - mapping.original.endLineNumberExclusive + mapping.modified.endLineNumberExclusive;
return Range.fromPositions(new Position(newLineNumber, posInOriginal.column));
}
if (!mapping.innerChanges) {
// Only for legacy algorithm
return Range.fromPositions(new Position(mapping.modifiedRange.startLineNumber, 1));
return Range.fromPositions(new Position(mapping.modified.startLineNumber, 1));
}
const innerMapping = findLast(mapping.innerChanges, m => m.originalRange.getStartPosition().isBeforeOrEqual(posInOriginal));
if (!innerMapping) {
const newLineNumber = posInOriginal.lineNumber - mapping.originalRange.startLineNumber + mapping.modifiedRange.startLineNumber;
const newLineNumber = posInOriginal.lineNumber - mapping.original.startLineNumber + mapping.modified.startLineNumber;
return Range.fromPositions(new Position(newLineNumber, posInOriginal.column));
}
@@ -590,24 +620,24 @@ function toLineChanges(state: DiffState): ILineChange[] {
let modifiedEndLineNumber: number;
let innerChanges = m.innerChanges;
if (m.originalRange.isEmpty) {
if (m.original.isEmpty) {
// Insertion
originalStartLineNumber = m.originalRange.startLineNumber - 1;
originalStartLineNumber = m.original.startLineNumber - 1;
originalEndLineNumber = 0;
innerChanges = undefined;
} else {
originalStartLineNumber = m.originalRange.startLineNumber;
originalEndLineNumber = m.originalRange.endLineNumberExclusive - 1;
originalStartLineNumber = m.original.startLineNumber;
originalEndLineNumber = m.original.endLineNumberExclusive - 1;
}
if (m.modifiedRange.isEmpty) {
if (m.modified.isEmpty) {
// Deletion
modifiedStartLineNumber = m.modifiedRange.startLineNumber - 1;
modifiedStartLineNumber = m.modified.startLineNumber - 1;
modifiedEndLineNumber = 0;
innerChanges = undefined;
} else {
modifiedStartLineNumber = m.modifiedRange.startLineNumber;
modifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive - 1;
modifiedStartLineNumber = m.modified.startLineNumber;
modifiedEndLineNumber = m.modified.endLineNumberExclusive - 1;
}
return {
@@ -13,7 +13,7 @@ import { IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrow
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import { DiffEditorWidget2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { EndOfLineSequence, ITextModel } from 'vs/editor/common/model';
import { localize } from 'vs/nls';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
@@ -39,7 +39,7 @@ export class InlineDiffDeletedCodeMargin extends Disposable {
private readonly _getViewZoneId: () => string,
private readonly _marginDomNode: HTMLElement,
private readonly _modifiedEditor: CodeEditorWidget,
private readonly _diff: LineRangeMapping,
private readonly _diff: DetailedLineRangeMapping,
private readonly _editor: DiffEditorWidget2,
private readonly _viewLineCounts: number[],
private readonly _originalTextModel: ITextModel,
@@ -70,38 +70,38 @@ export class InlineDiffDeletedCodeMargin extends Disposable {
getAnchor: () => ({ x, y }),
getActions: () => {
const actions: Action[] = [];
const isDeletion = _diff.modifiedRange.isEmpty;
const isDeletion = _diff.modified.isEmpty;
// default action
actions.push(new Action(
'diff.clipboard.copyDeletedContent',
isDeletion
? (_diff.originalRange.length > 1
? (_diff.original.length > 1
? localize('diff.clipboard.copyDeletedLinesContent.label', "Copy deleted lines")
: localize('diff.clipboard.copyDeletedLinesContent.single.label', "Copy deleted line"))
: (_diff.originalRange.length > 1
: (_diff.original.length > 1
? localize('diff.clipboard.copyChangedLinesContent.label', "Copy changed lines")
: localize('diff.clipboard.copyChangedLinesContent.single.label', "Copy changed line")),
undefined,
true,
async () => {
const originalText = this._originalTextModel.getValueInRange(_diff.originalRange.toExclusiveRange());
const originalText = this._originalTextModel.getValueInRange(_diff.original.toExclusiveRange());
await this._clipboardService.writeText(originalText);
}
));
if (_diff.originalRange.length > 1) {
if (_diff.original.length > 1) {
actions.push(new Action(
'diff.clipboard.copyDeletedLineContent',
isDeletion
? localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line ({0})",
_diff.originalRange.startLineNumber + currentLineNumberOffset)
_diff.original.startLineNumber + currentLineNumberOffset)
: localize('diff.clipboard.copyChangedLineContent.label', "Copy changed line ({0})",
_diff.originalRange.startLineNumber + currentLineNumberOffset),
_diff.original.startLineNumber + currentLineNumberOffset),
undefined,
true,
async () => {
let lineContent = this._originalTextModel.getLineContent(_diff.originalRange.startLineNumber + currentLineNumberOffset);
let lineContent = this._originalTextModel.getLineContent(_diff.original.startLineNumber + currentLineNumberOffset);
if (lineContent === '') {
// empty line -> new line
const eof = this._originalTextModel.getEndOfLineSequence();
@@ -25,7 +25,7 @@ import { animatedObservable, joinCombine } from 'vs/editor/browser/widget/diffEd
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { LineRange } from 'vs/editor/common/core/lineRange';
import { Position } from 'vs/editor/common/core/position';
import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { ScrollType } from 'vs/editor/common/editorCommon';
import { BackgroundTokenizationState } from 'vs/editor/common/tokenizationTextModelPart';
import { InlineDecoration, InlineDecorationType } from 'vs/editor/common/viewModel';
@@ -193,7 +193,7 @@ export class ViewZoneManager extends Disposable {
const decorations: InlineDecoration[] = [];
for (const i of a.diff.innerChanges || []) {
decorations.push(new InlineDecoration(
i.originalRange.delta(-(a.diff.originalRange.startLineNumber - 1)),
i.originalRange.delta(-(a.diff.original.startLineNumber - 1)),
diffDeleteDecoration.className!,
InlineDecorationType.Regular
));
@@ -287,7 +287,7 @@ export class ViewZoneManager extends Disposable {
}
let marginDomNode: HTMLElement | undefined = undefined;
if (a.diff && a.diff.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader)) {
if (a.diff && a.diff.modified.isEmpty && this._options.shouldRenderRevertArrows.read(reader)) {
marginDomNode = createViewZoneMarginArrow();
}
@@ -472,7 +472,7 @@ interface ILineRangeAlignment {
* If this range alignment is a direct result of a diff, then this is the diff's line mapping.
* Only used for inline-view.
*/
diff?: LineRangeMapping;
diff?: DetailedLineRangeMapping;
}
function computeRangeAlignment(
@@ -540,11 +540,11 @@ function computeRangeAlignment(
for (const m of diffs) {
const c = m.lineRangeMapping;
handleAlignmentsOutsideOfDiffs(c.originalRange.startLineNumber, c.modifiedRange.startLineNumber);
handleAlignmentsOutsideOfDiffs(c.original.startLineNumber, c.modified.startLineNumber);
let first = true;
let lastModLineNumber = c.modifiedRange.startLineNumber;
let lastOrigLineNumber = c.originalRange.startLineNumber;
let lastModLineNumber = c.modified.startLineNumber;
let lastOrigLineNumber = c.original.startLineNumber;
function emitAlignment(origLineNumberExclusive: number, modLineNumberExclusive: number) {
if (origLineNumberExclusive < lastOrigLineNumber || modLineNumberExclusive < lastModLineNumber) {
@@ -593,10 +593,10 @@ function computeRangeAlignment(
}
}
emitAlignment(c.originalRange.endLineNumberExclusive, c.modifiedRange.endLineNumberExclusive);
emitAlignment(c.original.endLineNumberExclusive, c.modified.endLineNumberExclusive);
lastOriginalLineNumber = c.originalRange.endLineNumberExclusive;
lastModifiedLineNumber = c.modifiedRange.endLineNumberExclusive;
lastOriginalLineNumber = c.original.endLineNumberExclusive;
lastModifiedLineNumber = c.modified.endLineNumberExclusive;
}
handleAlignmentsOutsideOfDiffs(Number.MAX_VALUE, Number.MAX_VALUE);
@@ -9,7 +9,7 @@ import { Action } from 'vs/base/common/actions';
import { booleanComparator, compareBy, findMaxIdxBy, numberComparator, tieBreakComparators } from 'vs/base/common/arrays';
import { Codicon } from 'vs/base/common/codicons';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { IObservable, autorun, autorunWithStore, constObservable, derived, derivedWithStore, keepAlive, observableFromEvent, observableSignalFromEvent, observableValue } from 'vs/base/common/observable';
import { IObservable, autorun, autorunHandleChanges, autorunWithStore, constObservable, derived, derivedWithStore, keepAlive, observableFromEvent, observableSignalFromEvent, observableValue } from 'vs/base/common/observable';
import { ThemeIcon } from 'vs/base/common/themables';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors';
@@ -82,19 +82,50 @@ export class MovedBlocksLinesPart extends Disposable {
}
}));
this._register(this._editors.original.onDidChangeCursorPosition(e => {
const m = this._diffModel.get();
if (!m) { return; }
const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.original.contains(e.position.lineNumber));
if (movedText !== m.movedTextToCompare.get()) {
m.movedTextToCompare.set(undefined, undefined);
const originalCursorPosition = observableFromEvent(this._editors.original.onDidChangeCursorPosition, () => this._editors.original.getPosition());
const modifiedCursorPosition = observableFromEvent(this._editors.modified.onDidChangeCursorPosition, () => this._editors.modified.getPosition());
const originalHasFocus = observableSignalFromEvent(
'original.onDidFocusEditorWidget',
e => this._editors.original.onDidFocusEditorWidget(() => setTimeout(() => e(undefined), 0))
);
const modifiedHasFocus = observableSignalFromEvent(
'modified.onDidFocusEditorWidget',
e => this._editors.modified.onDidFocusEditorWidget(() => setTimeout(() => e(undefined), 0))
);
let lastChangedEditor: 'original' | 'modified' = 'modified';
this._register(autorunHandleChanges({
createEmptyChangeSummary: () => undefined,
handleChange: (ctx, summary) => {
if (ctx.didChange(originalHasFocus)) { lastChangedEditor = 'original'; }
if (ctx.didChange(modifiedHasFocus)) { lastChangedEditor = 'modified'; }
return true;
}
m.setActiveMovedText(movedText);
}));
this._register(this._editors.modified.onDidChangeCursorPosition(e => {
const m = this._diffModel.get();
}, reader => {
originalHasFocus.read(reader);
modifiedHasFocus.read(reader);
const m = this._diffModel.read(reader);
if (!m) { return; }
const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber));
const diff = m.diff.read(reader);
let movedText: MovedText | undefined = undefined;
if (diff && lastChangedEditor === 'original') {
const originalPos = originalCursorPosition.read(reader);
if (originalPos) {
movedText = diff.movedTexts.find(m => m.lineRangeMapping.original.contains(originalPos.lineNumber));
}
}
if (diff && lastChangedEditor === 'modified') {
const modifiedPos = modifiedCursorPosition.read(reader);
if (modifiedPos) {
movedText = diff.movedTexts.find(m => m.lineRangeMapping.modified.contains(modifiedPos.lineNumber));
}
}
if (movedText !== m.movedTextToCompare.get()) {
m.movedTextToCompare.set(undefined, undefined);
}
@@ -324,7 +355,7 @@ class MovedBlockOverlayWidget extends ViewZoneOverlayWidget {
true,
() => {
this._editor.focus();
this._diffModel.movedTextToCompare.set(this._diffModel.movedTextToCompare.get() ? undefined : this._move, undefined);
this._diffModel.movedTextToCompare.set(this._diffModel.movedTextToCompare.get() === _move ? undefined : this._move, undefined);
},
);
this._register(autorun(reader => {
@@ -127,8 +127,8 @@ export class OverviewRulerPart extends Disposable {
});
}
const originalZones = createZones((diff || []).map(d => d.lineRangeMapping.originalRange), colors.removeColor, this._editors.original);
const modifiedZones = createZones((diff || []).map(d => d.lineRangeMapping.modifiedRange), colors.insertColor, this._editors.modified);
const originalZones = createZones((diff || []).map(d => d.lineRangeMapping.original), colors.removeColor, this._editors.original);
const modifiedZones = createZones((diff || []).map(d => d.lineRangeMapping.modified), colors.insertColor, this._editors.modified);
originalOverviewRuler?.setZones(originalZones);
modifiedOverviewRuler?.setZones(modifiedZones);
}));
@@ -94,13 +94,13 @@ export class UnchangedRangesFeature extends Disposable {
const d = derived(reader => /** @description hiddenOriginalRangeStart */ r.getHiddenOriginalRange(reader).startLineNumber - 1);
const origVz = new PlaceholderViewZone(d, 24);
origViewZones.push(origVz);
store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, r.originalRange, !sideBySide, modifiedOutlineSource, l => this._diffModel.get()!.ensureOriginalLineIsVisible(l, undefined)));
store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, r.originalRange, !sideBySide, modifiedOutlineSource, l => this._diffModel.get()!.ensureModifiedLineIsVisible(l, undefined), this._options));
}
{
const d = derived(reader => /** @description hiddenModifiedRangeStart */ r.getHiddenModifiedRange(reader).startLineNumber - 1);
const modViewZone = new PlaceholderViewZone(d, 24);
modViewZones.push(modViewZone);
store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, r.modifiedRange, false, modifiedOutlineSource, l => this._diffModel.get()!.ensureModifiedLineIsVisible(l, undefined)));
store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, r.modifiedRange, false, modifiedOutlineSource, l => this._diffModel.get()!.ensureModifiedLineIsVisible(l, undefined), this._options));
}
}
@@ -174,7 +174,7 @@ export class UnchangedRangesFeature extends Disposable {
if (!model) { return; }
const region = model.unchangedRegions.get().find(r => r.modifiedRange.includes(lineNumber));
if (!region) { return; }
region.setState(0, 0, undefined);
region.collapseAll(undefined);
event.event.stopPropagation();
event.event.preventDefault();
}
@@ -187,7 +187,7 @@ export class UnchangedRangesFeature extends Disposable {
if (!model) { return; }
const region = model.unchangedRegions.get().find(r => r.originalRange.includes(lineNumber));
if (!region) { return; }
region.setState(0, 0, undefined);
region.collapseAll(undefined);
event.event.stopPropagation();
event.event.preventDefault();
}
@@ -250,7 +250,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget {
private readonly _nodes = h('div.diff-hidden-lines', [
h('div.top@top', { title: localize('diff.hiddenLines.top', 'Click or drag to show more above') }),
h('div.center@content', { style: { display: 'flex' } }, [
h('div@first', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' } },
h('div@first', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: '0' } },
[$('a', { title: localize('showAll', 'Show all'), role: 'button', onclick: () => { this.showAll(); } }, ...renderLabelWithIcons('$(unfold)'))]
),
h('div@others', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' } }),
@@ -265,7 +265,8 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget {
private readonly _unchangedRegionRange: LineRange,
private readonly hide: boolean,
private readonly _modifiedOutlineSource: OutlineSource,
private readonly _revealHiddenLine: (lineNumber: number) => void,
private readonly _revealModifiedHiddenLine: (lineNumber: number) => void,
private readonly _options: DiffEditorOptions,
) {
const root = h('div.diff-hidden-lines-widget');
super(_editor, _viewZone, root.root);
@@ -307,7 +308,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget {
const mouseUpListener = addDisposableListener(window, 'mouseup', e => {
if (!didMove) {
this._unchangedRegion.showMoreAbove(20, undefined);
this._unchangedRegion.showMoreAbove(this._options.hideUnchangedRegionsRevealLineCount.get(), undefined);
}
this._nodes.top.classList.toggle('dragging', false);
this._nodes.root.classList.toggle('dragging', false);
@@ -347,7 +348,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget {
if (!didMove) {
const top = editor.getTopForLineNumber(this._unchangedRegionRange.endLineNumberExclusive);
this._unchangedRegion.showMoreBelow(20, undefined);
this._unchangedRegion.showMoreBelow(this._options.hideUnchangedRegionsRevealLineCount.get(), undefined);
const top2 = editor.getTopForLineNumber(this._unchangedRegionRange.endLineNumberExclusive);
editor.setScrollTop(editor.getScrollTop() + (top2 - top));
}
@@ -364,7 +365,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget {
const children: HTMLElement[] = [];
if (!this.hide) {
const lineCount = _unchangedRegion.getHiddenModifiedRange(reader).length;
const linesHiddenText = localize('hiddenLines', '{0} Hidden Lines', lineCount);
const linesHiddenText = localize('hiddenLines', '{0} hidden lines', lineCount);
const span = $('span', { title: localize('diff.hiddenLines.expandAll', 'Double click to unfold') }, linesHiddenText);
span.addEventListener('dblclick', e => {
if (e.button !== 0) { return; }
@@ -395,7 +396,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget {
]).root;
children.push(divItem);
divItem.onclick = () => {
this._revealHiddenLine(item.startLineNumber);
this._revealModifiedHiddenLine(item.startLineNumber);
};
}
}
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IDimension } from 'vs/base/browser/dom';
import { isHotReloadEnabled, registerHotReloadHandler } from 'vs/base/common/hotReload';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { IObservable, IReader, ISettableObservable, autorun, autorunHandleChanges, autorunOpts, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable';
import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver';
@@ -294,28 +295,21 @@ export function readHotReloadableExport<T>(value: T, reader: IReader | undefined
}
export function observeHotReloadableExports(values: any[], reader: IReader | undefined): void {
const hotReload_deprecateExports = (globalThis as unknown as {
// This property it defined by the monaco editor playground server
$hotReload_deprecateExports: Set<(oldExports: Record<string, unknown>, newExports: Record<string, unknown>) => boolean>;
}).$hotReload_deprecateExports;
if (!hotReload_deprecateExports) {
return;
if (isHotReloadEnabled()) {
const o = observableSignalFromEvent(
'reload',
event => registerHotReloadHandler(oldExports => {
if (![...Object.values(oldExports)].some(v => values.includes(v))) {
return undefined;
}
return (_newExports) => {
event(undefined);
return true;
};
})
);
o.read(reader);
}
const o = observableSignalFromEvent('reload', e => {
function handleExports(oldExports: Record<string, unknown>, _newExports: Record<string, unknown>) {
if ([...Object.values(oldExports)].some(v => values.includes(v))) {
e(undefined);
return true;
}
return false;
}
hotReload_deprecateExports.add(handleExports);
return {
dispose() { hotReload_deprecateExports.delete(handleExports); }
};
});
o.read(reader);
}
export function applyViewZones(editor: ICodeEditor, viewZones: IObservable<IObservableViewZone[]>, setIsUpdating?: (isUpdatingViewZones: boolean) => void): IDisposable {
@@ -134,8 +134,9 @@ export class EmbeddedDiffEditorWidget2 extends DiffEditorWidget2 {
@IInstantiationService instantiationService: IInstantiationService,
@ICodeEditorService codeEditorService: ICodeEditorService,
@IAudioCueService audioCueService: IAudioCueService,
@IEditorProgressService editorProgressService: IEditorProgressService,
) {
super(domElement, parentEditor.getRawOptions(), codeEditorWidgetOptions, contextKeyService, instantiationService, codeEditorService, audioCueService);
super(domElement, parentEditor.getRawOptions(), codeEditorWidgetOptions, contextKeyService, instantiationService, codeEditorService, audioCueService, editorProgressService);
this._parentEditor = parentEditor;
this._overwriteOptions = options;
@@ -9,7 +9,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import { StopWatch } from 'vs/base/common/stopwatch';
import { LineRange } from 'vs/editor/common/core/lineRange';
import { IDocumentDiff, IDocumentDiffProvider, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';
import { LineRangeMapping, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping, RangeMapping } from 'vs/editor/common/diff/rangeMapping';
import { ITextModel } from 'vs/editor/common/model';
import { DiffAlgorithmName, IEditorWorkerService } from 'vs/editor/common/services/editorWorker';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -53,7 +53,7 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I
return {
changes: [
new LineRangeMapping(
new DetailedLineRangeMapping(
new LineRange(1, 2),
new LineRange(1, modified.getLineCount() + 1),
[
@@ -84,16 +84,19 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I
this.telemetryService.publicLog2<{
timeMs: number;
timedOut: boolean;
detectedMoves: number;
}, {
owner: 'hediet';
timeMs: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To understand if the new diff algorithm is slower/faster than the old one' };
timedOut: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To understand how often the new diff algorithm times out' };
detectedMoves: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To understand how often the new diff algorithm detects moves' };
comment: 'This event gives insight about the performance of the new diff algorithm.';
}>('diffEditor.computeDiff', {
timeMs,
timedOut: result?.quitEarly ?? true,
detectedMoves: options.computeMoves ? (result?.moves.length ?? 0) : -1,
});
if (cancellationToken.isCancellationRequested) {
+37
View File
@@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ValidDiffEditorBaseOptions } from 'vs/editor/common/config/editorOptions';
export const diffEditorDefaultOptions = {
enableSplitViewResizing: true,
splitViewDefaultRatio: 0.5,
renderSideBySide: true,
renderMarginRevertIcon: true,
maxComputationTime: 5000,
maxFileSize: 50,
ignoreTrimWhitespace: true,
renderIndicators: true,
originalEditable: false,
diffCodeLens: false,
renderOverviewRuler: true,
diffWordWrap: 'inherit',
diffAlgorithm: 'advanced',
accessibilityVerbose: false,
experimental: {
showMoves: false,
showEmptyDecorations: true,
},
hideUnchangedRegions: {
enabled: false,
contextLineCount: 3,
minimumLineCount: 3,
revealLineCount: 20,
},
isInEmbeddedEditor: false,
onlyShowAccessibleDiffViewer: false,
renderSideBySideInlineBreakpoint: 900,
useInlineViewWhenSpaceIsLimited: true,
} satisfies ValidDiffEditorBaseOptions;
@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { diffEditorDefaultOptions } from 'vs/editor/common/config/diffEditor';
import { editorOptionsRegistry } from 'vs/editor/common/config/editorOptions';
import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/core/textModelDefaults';
import * as nls from 'vs/nls';
@@ -150,53 +151,53 @@ const editorConfiguration: IConfigurationNode = {
},
'diffEditor.maxComputationTime': {
type: 'number',
default: 5000,
default: diffEditorDefaultOptions.maxComputationTime,
description: nls.localize('maxComputationTime', "Timeout in milliseconds after which diff computation is cancelled. Use 0 for no timeout.")
},
'diffEditor.maxFileSize': {
type: 'number',
default: 50,
default: diffEditorDefaultOptions.maxFileSize,
description: nls.localize('maxFileSize', "Maximum file size in MB for which to compute diffs. Use 0 for no limit.")
},
'diffEditor.renderSideBySide': {
type: 'boolean',
default: true,
default: diffEditorDefaultOptions.renderSideBySide,
description: nls.localize('sideBySide', "Controls whether the diff editor shows the diff side by side or inline.")
},
'diffEditor.renderSideBySideInlineBreakpoint': {
type: 'number',
default: true,
default: diffEditorDefaultOptions.renderSideBySideInlineBreakpoint,
description: nls.localize('renderSideBySideInlineBreakpoint', "If the diff editor width is smaller than this value, the inline view is used.")
},
'diffEditor.useInlineViewWhenSpaceIsLimited': {
type: 'boolean',
default: true,
default: diffEditorDefaultOptions.useInlineViewWhenSpaceIsLimited,
description: nls.localize('useInlineViewWhenSpaceIsLimited', "If enabled and the editor width is too small, the inline view is used.")
},
'diffEditor.renderMarginRevertIcon': {
type: 'boolean',
default: true,
default: diffEditorDefaultOptions.renderMarginRevertIcon,
description: nls.localize('renderMarginRevertIcon', "When enabled, the diff editor shows arrows in its glyph margin to revert changes.")
},
'diffEditor.ignoreTrimWhitespace': {
type: 'boolean',
default: true,
default: diffEditorDefaultOptions.ignoreTrimWhitespace,
description: nls.localize('ignoreTrimWhitespace', "When enabled, the diff editor ignores changes in leading or trailing whitespace.")
},
'diffEditor.renderIndicators': {
type: 'boolean',
default: true,
default: diffEditorDefaultOptions.renderIndicators,
description: nls.localize('renderIndicators', "Controls whether the diff editor shows +/- indicators for added/removed changes.")
},
'diffEditor.codeLens': {
type: 'boolean',
default: false,
default: diffEditorDefaultOptions.diffCodeLens,
description: nls.localize('codeLens', "Controls whether the editor shows CodeLens.")
},
'diffEditor.wordWrap': {
type: 'string',
enum: ['off', 'on', 'inherit'],
default: 'inherit',
default: diffEditorDefaultOptions.diffWordWrap,
markdownEnumDescriptions: [
nls.localize('wordWrap.off', "Lines will never wrap."),
nls.localize('wordWrap.on', "Lines will wrap at the viewport width."),
@@ -206,32 +207,50 @@ const editorConfiguration: IConfigurationNode = {
'diffEditor.diffAlgorithm': {
type: 'string',
enum: ['legacy', 'advanced'],
default: 'advanced',
default: diffEditorDefaultOptions.diffAlgorithm,
markdownEnumDescriptions: [
nls.localize('diffAlgorithm.legacy', "Uses the legacy diffing algorithm."),
nls.localize('diffAlgorithm.advanced', "Uses the advanced diffing algorithm."),
],
tags: ['experimental'],
},
'diffEditor.experimental.collapseUnchangedRegions': {
'diffEditor.hideUnchangedRegions.enabled': {
type: 'boolean',
default: false,
markdownDescription: nls.localize('collapseUnchangedRegions', "Controls whether the diff editor shows unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'),
default: diffEditorDefaultOptions.hideUnchangedRegions.enabled,
markdownDescription: nls.localize('hideUnchangedRegions.enabled', "Controls whether the diff editor shows unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'),
},
'diffEditor.hideUnchangedRegions.revealLineCount': {
type: 'integer',
default: diffEditorDefaultOptions.hideUnchangedRegions.revealLineCount,
markdownDescription: nls.localize('hideUnchangedRegions.revealLineCount', "Controls how many lines are used for unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'),
minimum: 1,
},
'diffEditor.hideUnchangedRegions.minimumLineCount': {
type: 'integer',
default: diffEditorDefaultOptions.hideUnchangedRegions.minimumLineCount,
markdownDescription: nls.localize('hideUnchangedRegions.minimumLineCount', "Controls how many lines are used as a minimum for unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'),
minimum: 1,
},
'diffEditor.hideUnchangedRegions.contextLineCount': {
type: 'integer',
default: diffEditorDefaultOptions.hideUnchangedRegions.contextLineCount,
markdownDescription: nls.localize('hideUnchangedRegions.contextLineCount', "Controls how many lines are used as context when comparing unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'),
minimum: 1,
},
'diffEditor.experimental.showMoves': {
type: 'boolean',
default: false,
default: diffEditorDefaultOptions.experimental.showMoves,
markdownDescription: nls.localize('showMoves', "Controls whether the diff editor should show detected code moves. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`')
},
'diffEditor.experimental.useVersion2': {
type: 'boolean',
default: false,
default: true,
description: nls.localize('useVersion2', "Controls whether the diff editor uses the new or the old implementation."),
tags: ['experimental'],
},
'diffEditor.experimental.showEmptyDecorations': {
type: 'boolean',
default: true,
default: diffEditorDefaultOptions.experimental.showEmptyDecorations,
description: nls.localize('showEmptyDecorations', "Controls whether the diff editor shows empty decorations to see where characters got inserted or deleted."),
}
}
+8 -5
View File
@@ -825,10 +825,6 @@ export interface IDiffEditorBaseOptions {
accessibilityVerbose?: boolean;
experimental?: {
/**
* Defaults to false.
*/
collapseUnchangedRegions?: boolean;
/**
* Defaults to false.
*/
@@ -847,6 +843,13 @@ export interface IDiffEditorBaseOptions {
* If the diff editor should only show the difference review mode.
*/
onlyShowAccessibleDiffViewer?: boolean;
hideUnchangedRegions?: {
enabled?: boolean;
revealLineCount?: number;
minimumLineCount?: number;
contextLineCount?: number;
};
}
/**
@@ -2796,7 +2799,7 @@ class EditorStickyScroll extends BaseEditorOption<EditorOption.stickyScroll, IEd
'editor.stickyScroll.scrollWithEditor': {
type: 'boolean',
default: defaults.scrollWithEditor,
description: nls.localize('editor.stickyScroll.scrollWithEditor', "When enabled it is possible to scroll the sticky scroll widget with the editor horizontal scrollbar.")
description: nls.localize('editor.stickyScroll.scrollWithEditor', "Enable scrolling of the sticky scroll widget with the editor's horizontal scrollbar.")
},
}
);
+164 -58
View File
@@ -6,6 +6,7 @@
import { BugIndicatingError } from 'vs/base/common/errors';
import { OffsetRange } from 'vs/editor/common/core/offsetRange';
import { Range } from 'vs/editor/common/core/range';
import { findFirstIdxMonotonousOrArrLen, findLastIdxMonotonous, findLastMonotonous } from 'vs/base/common/arraysFind';
/**
* A range of lines (1-based).
@@ -40,66 +41,11 @@ export class LineRange {
if (lineRanges.length === 0) {
return [];
}
let result = lineRanges[0];
let result = new LineRangeSet(lineRanges[0].slice());
for (let i = 1; i < lineRanges.length; i++) {
result = this.join(result, lineRanges[i]);
result = result.getUnion(new LineRangeSet(lineRanges[i].slice()));
}
return result;
}
/**
* @param lineRanges1 Must be sorted.
* @param lineRanges2 Must be sorted.
*/
public static join(lineRanges1: readonly LineRange[], lineRanges2: readonly LineRange[]): readonly LineRange[] {
if (lineRanges1.length === 0) {
return lineRanges2;
}
if (lineRanges2.length === 0) {
return lineRanges1;
}
const result: LineRange[] = [];
let i1 = 0;
let i2 = 0;
let current: LineRange | null = null;
while (i1 < lineRanges1.length || i2 < lineRanges2.length) {
let next: LineRange | null = null;
if (i1 < lineRanges1.length && i2 < lineRanges2.length) {
const lineRange1 = lineRanges1[i1];
const lineRange2 = lineRanges2[i2];
if (lineRange1.startLineNumber < lineRange2.startLineNumber) {
next = lineRange1;
i1++;
} else {
next = lineRange2;
i2++;
}
} else if (i1 < lineRanges1.length) {
next = lineRanges1[i1];
i1++;
} else {
next = lineRanges2[i2];
i2++;
}
if (current === null) {
current = next;
} else {
if (current.endLineNumberExclusive >= next.startLineNumber) {
// merge
current = new LineRange(current.startLineNumber, Math.max(current.endLineNumberExclusive, next.endLineNumberExclusive));
} else {
// push
result.push(current);
current = next;
}
}
}
if (current !== null) {
result.push(current);
}
return result;
return result.ranges;
}
public static ofLength(startLineNumber: number, length: number): LineRange {
@@ -251,3 +197,163 @@ export class LineRange {
}
export type ISerializedLineRange = [startLineNumber: number, endLineNumberExclusive: number];
export class LineRangeSet {
constructor(
/**
* Sorted by start line number.
* No two line ranges are touching or intersecting.
*/
private readonly _normalizedRanges: LineRange[] = []
) {
}
get ranges(): readonly LineRange[] {
return this._normalizedRanges;
}
addRange(range: LineRange): void {
if (range.length === 0) {
return;
}
// Idea: Find joinRange such that:
// replaceRange = _normalizedRanges.replaceRange(joinRange, range.joinAll(joinRange.map(idx => this._normalizedRanges[idx])))
// idx of first element that touches range or that is after range
const joinRangeStartIdx = findFirstIdxMonotonousOrArrLen(this._normalizedRanges, r => r.endLineNumberExclusive >= range.startLineNumber);
// idx of element after { last element that touches range or that is before range }
const joinRangeEndIdxExclusive = findLastIdxMonotonous(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1;
if (joinRangeStartIdx === joinRangeEndIdxExclusive) {
// If there is no element that touches range, then joinRangeStartIdx === joinRangeEndIdxExclusive and that value is the index of the element after range
this._normalizedRanges.splice(joinRangeStartIdx, 0, range);
} else if (joinRangeStartIdx === joinRangeEndIdxExclusive - 1) {
// Else, there is an element that touches range and in this case it is both the first and last element. Thus we can replace it
const joinRange = this._normalizedRanges[joinRangeStartIdx];
this._normalizedRanges[joinRangeStartIdx] = joinRange.join(range);
} else {
// First and last element are different - we need to replace the entire range
const joinRange = this._normalizedRanges[joinRangeStartIdx].join(this._normalizedRanges[joinRangeEndIdxExclusive - 1]).join(range);
this._normalizedRanges.splice(joinRangeStartIdx, joinRangeEndIdxExclusive - joinRangeStartIdx, joinRange);
}
}
intersects(range: LineRange): boolean {
const rangeThatStartsBeforeEnd = findLastMonotonous(this._normalizedRanges, r => r.startLineNumber < range.endLineNumberExclusive);
return !!rangeThatStartsBeforeEnd && rangeThatStartsBeforeEnd.endLineNumberExclusive > range.startLineNumber;
}
getUnion(other: LineRangeSet): LineRangeSet {
if (this._normalizedRanges.length === 0) {
return other;
}
if (other._normalizedRanges.length === 0) {
return this;
}
const result: LineRange[] = [];
let i1 = 0;
let i2 = 0;
let current: LineRange | null = null;
while (i1 < this._normalizedRanges.length || i2 < other._normalizedRanges.length) {
let next: LineRange | null = null;
if (i1 < this._normalizedRanges.length && i2 < other._normalizedRanges.length) {
const lineRange1 = this._normalizedRanges[i1];
const lineRange2 = other._normalizedRanges[i2];
if (lineRange1.startLineNumber < lineRange2.startLineNumber) {
next = lineRange1;
i1++;
} else {
next = lineRange2;
i2++;
}
} else if (i1 < this._normalizedRanges.length) {
next = this._normalizedRanges[i1];
i1++;
} else {
next = other._normalizedRanges[i2];
i2++;
}
if (current === null) {
current = next;
} else {
if (current.endLineNumberExclusive >= next.startLineNumber) {
// merge
current = new LineRange(current.startLineNumber, Math.max(current.endLineNumberExclusive, next.endLineNumberExclusive));
} else {
// push
result.push(current);
current = next;
}
}
}
if (current !== null) {
result.push(current);
}
return new LineRangeSet(result);
}
/**
* Subtracts all ranges in this set from `range` and returns the result.
*/
subtractFrom(range: LineRange): LineRangeSet {
// idx of first element that touches range or that is after range
const joinRangeStartIdx = findFirstIdxMonotonousOrArrLen(this._normalizedRanges, r => r.endLineNumberExclusive >= range.startLineNumber);
// idx of element after { last element that touches range or that is before range }
const joinRangeEndIdxExclusive = findLastIdxMonotonous(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1;
if (joinRangeStartIdx === joinRangeEndIdxExclusive) {
return new LineRangeSet([range]);
}
const result: LineRange[] = [];
let startLineNumber = range.startLineNumber;
for (let i = joinRangeStartIdx; i < joinRangeEndIdxExclusive; i++) {
const r = this._normalizedRanges[i];
if (r.startLineNumber > startLineNumber) {
result.push(new LineRange(startLineNumber, r.startLineNumber));
}
startLineNumber = r.endLineNumberExclusive;
}
if (startLineNumber < range.endLineNumberExclusive) {
result.push(new LineRange(startLineNumber, range.endLineNumberExclusive));
}
return new LineRangeSet(result);
}
toString() {
return this._normalizedRanges.map(r => r.toString()).join(', ');
}
getIntersection(other: LineRangeSet): LineRangeSet {
const result: LineRange[] = [];
let i1 = 0;
let i2 = 0;
while (i1 < this._normalizedRanges.length && i2 < other._normalizedRanges.length) {
const r1 = this._normalizedRanges[i1];
const r2 = other._normalizedRanges[i2];
const i = r1.intersect(r2);
if (i && !i.isEmpty) {
result.push(i);
}
if (r1.endLineNumberExclusive < r2.endLineNumberExclusive) {
i1++;
} else {
i2++;
}
}
return new LineRangeSet(result);
}
getWithDelta(value: number): LineRangeSet {
return new LineRangeSet(this._normalizedRanges.map(r => r.delta(value)));
}
}
+8
View File
@@ -136,6 +136,14 @@ export class OffsetRange {
}
return value;
}
public map<T>(f: (offset: number) => T): T[] {
const result: T[] = [];
for (let i = this.start; i < this.endExclusive; i++) {
result.push(f(i));
}
return result;
}
}
export class OffsetRangeSet {
@@ -3,11 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { compareBy, equals, findLastIndex, numberComparator, reverseOrder } from 'vs/base/common/arrays';
import { compareBy, equals, groupAdjacentBy, numberComparator, pushMany, reverseOrder } from 'vs/base/common/arrays';
import { assertFn, checkAdjacentItems } from 'vs/base/common/assert';
import { CharCode } from 'vs/base/common/charCode';
import { SetMap } from 'vs/base/common/collections';
import { LineRange } from 'vs/editor/common/core/lineRange';
import { LineRange, LineRangeSet } from 'vs/editor/common/core/lineRange';
import { OffsetRange } from 'vs/editor/common/core/offsetRange';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
@@ -15,7 +15,9 @@ import { DateTimeout, ISequence, ITimeout, InfiniteTimeout, SequenceDiff } from
import { DynamicProgrammingDiffing } from 'vs/editor/common/diff/algorithms/dynamicProgrammingDiffing';
import { optimizeSequenceDiffs, removeRandomLineMatches, removeRandomMatches, smoothenSequenceDiffs } from 'vs/editor/common/diff/algorithms/joinSequenceDiffs';
import { MyersDiffAlgorithm } from 'vs/editor/common/diff/algorithms/myersDiffAlgorithm';
import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping, LinesDiff, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { ILinesDiffComputer, ILinesDiffComputerOptions, LinesDiff, MovedText } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping, LineRangeMapping, RangeMapping } from './rangeMapping';
import { MonotonousArray, findLastIdxMonotonous, findLastMonotonous, findFirstMonotonous } from 'vs/base/common/arraysFind';
export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
private readonly dynamicProgrammingDiffing = new DynamicProgrammingDiffing();
@@ -28,7 +30,7 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
if (originalLines.length === 1 && originalLines[0].length === 0 || modifiedLines.length === 1 && modifiedLines[0].length === 0) {
return new LinesDiff([
new LineRangeMapping(
new DetailedLineRangeMapping(
new LineRange(1, originalLines.length + 1),
new LineRange(1, modifiedLines.length + 1),
[
@@ -166,7 +168,7 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
validatePosition(ic.originalRange.getStartPosition(), originalLines) && validatePosition(ic.originalRange.getEndPosition(), originalLines);
if (!valid) { return false; }
}
if (!validateRange(c.modifiedRange, modifiedLines) || !validateRange(c.originalRange, originalLines)) {
if (!validateRange(c.modified, modifiedLines) || !validateRange(c.original, originalLines)) {
return false;
}
}
@@ -176,16 +178,94 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
return new LinesDiff(changes, moves, hitTimeout);
}
private computeMoves(changes: LineRangeMapping[], originalLines: string[], modifiedLines: string[], hashedOriginalLines: number[], hashedModifiedLines: number[], timeout: ITimeout, considerWhitespaceChanges: boolean): MovedText[] {
const moves: SimpleLineRangeMapping[] = [];
const deletions = changes
.filter(c => c.modifiedRange.isEmpty && c.originalRange.length >= 3)
.map(d => new LineRangeFragment(d.originalRange, originalLines, d));
const insertions = new Set(changes
.filter(c => c.originalRange.isEmpty && c.modifiedRange.length >= 3)
.map(d => new LineRangeFragment(d.modifiedRange, modifiedLines, d)));
private computeMoves(
changes: DetailedLineRangeMapping[],
originalLines: string[],
modifiedLines: string[],
hashedOriginalLines: number[],
hashedModifiedLines: number[],
timeout: ITimeout,
considerWhitespaceChanges: boolean,
): MovedText[] {
const { moves, excludedChanges } = this.computeMovesFromSimpleDeletionsToSimpleInsertions(changes, originalLines, modifiedLines, timeout);
const excludedChanges = new Set<LineRangeMapping>();
if (!timeout.isValid()) { return []; }
const unchangedMoves = this.computeUnchangedMoves(
changes.filter(c => !excludedChanges.has(c)),
hashedOriginalLines,
hashedModifiedLines,
timeout
);
pushMany(moves, unchangedMoves);
// join moves
moves.sort(compareBy(m => m.original.startLineNumber, numberComparator));
if (moves.length === 0) {
return [];
}
let joinedMoves = [moves[0]];
for (let i = 1; i < moves.length; i++) {
const last = joinedMoves[joinedMoves.length - 1];
const current = moves[i];
const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive;
const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive;
const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0;
if (currentMoveAfterLast && originalDist + modifiedDist <= 2) {
joinedMoves[joinedMoves.length - 1] = last.join(current);
continue;
}
const originalText = current.original.toOffsetRange().slice(originalLines).map(l => l.trim()).join('\n');
if (originalText.length <= 10) {
// Ignore small moves
continue;
}
joinedMoves.push(current);
}
// Ignore non moves
const changesMonotonous = new MonotonousArray(changes);
joinedMoves = joinedMoves.filter(m => {
const diffBeforeOriginalMove = changesMonotonous.findLastMonotonous(c => c.original.endLineNumberExclusive <= m.original.startLineNumber)
|| new LineRangeMapping(new LineRange(1, 1), new LineRange(1, 1));
const modifiedDistToPrevDiff = m.modified.startLineNumber - diffBeforeOriginalMove.modified.endLineNumberExclusive;
const originalDistToPrevDiff = m.original.startLineNumber - diffBeforeOriginalMove.original.endLineNumberExclusive;
const differentDistances = modifiedDistToPrevDiff !== originalDistToPrevDiff;
return differentDistances;
});
const movesWithDiffs = joinedMoves.map(m => {
const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff(
m.original.toOffsetRange(),
m.modified.toOffsetRange(),
), timeout, considerWhitespaceChanges);
const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true);
return new MovedText(m, mappings);
});
return movesWithDiffs;
}
private computeMovesFromSimpleDeletionsToSimpleInsertions(
changes: DetailedLineRangeMapping[],
originalLines: string[],
modifiedLines: string[],
timeout: ITimeout,
) {
const moves: LineRangeMapping[] = [];
const deletions = changes
.filter(c => c.modified.isEmpty && c.original.length >= 3)
.map(d => new LineRangeFragment(d.original, originalLines, d));
const insertions = new Set(changes
.filter(c => c.original.isEmpty && c.modified.length >= 3)
.map(d => new LineRangeFragment(d.modified, modifiedLines, d)));
const excludedChanges = new Set<DetailedLineRangeMapping>();
for (const deletion of deletions) {
let highestSimilarity = -1;
@@ -200,24 +280,31 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
if (highestSimilarity > 0.90 && best) {
insertions.delete(best);
moves.push(new SimpleLineRangeMapping(deletion.range, best.range));
moves.push(new LineRangeMapping(deletion.range, best.range));
excludedChanges.add(deletion.source);
excludedChanges.add(best.source);
}
if (!timeout.isValid()) {
return [];
return { moves, excludedChanges };
}
}
return { moves, excludedChanges };
}
private computeUnchangedMoves(
changes: DetailedLineRangeMapping[],
hashedOriginalLines: number[],
hashedModifiedLines: number[],
timeout: ITimeout,
) {
const moves: LineRangeMapping[] = [];
const original3LineHashes = new SetMap<string, { range: LineRange }>();
for (const change of changes) {
if (excludedChanges.has(change)) {
continue;
}
for (let i = change.originalRange.startLineNumber; i < change.originalRange.endLineNumberExclusive - 2; i++) {
for (let i = change.original.startLineNumber; i < change.original.endLineNumberExclusive - 2; i++) {
const key = `${hashedOriginalLines[i - 1]}:${hashedOriginalLines[i + 1 - 1]}:${hashedOriginalLines[i + 2 - 1]}`;
original3LineHashes.add(key, { range: new LineRange(i, i + 3) });
}
@@ -230,15 +317,11 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
const possibleMappings: PossibleMapping[] = [];
changes.sort(compareBy(c => c.modifiedRange.startLineNumber, numberComparator));
changes.sort(compareBy(c => c.modified.startLineNumber, numberComparator));
for (const change of changes) {
if (excludedChanges.has(change)) {
continue;
}
let lastMappings: PossibleMapping[] = [];
for (let i = change.modifiedRange.startLineNumber; i < change.modifiedRange.endLineNumberExclusive - 2; i++) {
for (let i = change.modified.startLineNumber; i < change.modified.endLineNumberExclusive - 2; i++) {
const key = `${hashedModifiedLines[i - 1]}:${hashedModifiedLines[i + 1 - 1]}:${hashedModifiedLines[i + 2 - 1]}`;
const currentModifiedRange = new LineRange(i, i + 3);
@@ -279,60 +362,25 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
const diffOrigToMod = mapping.modifiedLineRange.startLineNumber - mapping.originalLineRange.startLineNumber;
const modifiedSections = modifiedSet.subtractFrom(mapping.modifiedLineRange);
const originalTranslatedSections = originalSet.subtractFrom(mapping.originalLineRange).map(r => r.delta(diffOrigToMod));
const originalTranslatedSections = originalSet.subtractFrom(mapping.originalLineRange).getWithDelta(diffOrigToMod);
const modifiedIntersectedSections = intersectRanges(modifiedSections, originalTranslatedSections);
const modifiedIntersectedSections = modifiedSections.getIntersection(originalTranslatedSections);
for (const s of modifiedIntersectedSections) {
for (const s of modifiedIntersectedSections.ranges) {
if (s.length < 3) {
continue;
}
const modifiedLineRange = s;
const originalLineRange = s.delta(-diffOrigToMod);
moves.push(new SimpleLineRangeMapping(originalLineRange, modifiedLineRange));
moves.push(new LineRangeMapping(originalLineRange, modifiedLineRange));
modifiedSet.addRange(modifiedLineRange);
originalSet.addRange(originalLineRange);
}
}
// join moves
moves.sort(compareBy(m => m.original.startLineNumber, numberComparator));
if (moves.length === 0) {
return [];
}
const joinedMoves = [moves[0]];
for (let i = 1; i < moves.length; i++) {
const last = joinedMoves[joinedMoves.length - 1];
const current = moves[i];
const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive;
const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive;
const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0;
if (currentMoveAfterLast && originalDist + modifiedDist <= 2) {
joinedMoves[joinedMoves.length - 1] = last.join(current);
continue;
}
const originalText = current.original.toOffsetRange().slice(originalLines).map(l => l.trim()).join('\n');
if (originalText.length <= 10) {
// Ignore small moves
continue;
}
joinedMoves.push(current);
}
const fullMoves = joinedMoves.map(m => {
const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff(
m.original.toOffsetRange(),
m.modified.toOffsetRange(),
), timeout, considerWhitespaceChanges);
const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true);
return new MovedText(m, mappings);
});
return fullMoves;
return moves;
}
private refineDiff(originalLines: string[], modifiedLines: string[], diff: SequenceDiff, timeout: ITimeout, considerWhitespaceChanges: boolean): { mappings: RangeMapping[]; hitTimeout: boolean } {
@@ -366,100 +414,6 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer {
}
}
function intersectRanges(ranges1: LineRange[], ranges2: LineRange[]): LineRange[] {
const result: LineRange[] = [];
let i1 = 0;
let i2 = 0;
while (i1 < ranges1.length && i2 < ranges2.length) {
const r1 = ranges1[i1];
const r2 = ranges2[i2];
const i = r1.intersect(r2);
if (i && !i.isEmpty) {
result.push(i);
}
if (r1.endLineNumberExclusive < r2.endLineNumberExclusive) {
i1++;
} else {
i2++;
}
}
return result;
}
// TODO make this fast
class LineRangeSet {
private readonly _normalizedRanges: LineRange[] = [];
addRange(range: LineRange): void {
// Idea: Find joinRange such that:
// replaceRange = _normalizedRanges.replaceRange(joinRange, range.joinAll(joinRange.map(idx => this._normalizedRanges[idx])))
// idx of first element that touches range or that is after range
const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length);
// idx of element after { last element that touches range or that is before range }
const joinRangeEndIdxExclusive = findLastIndex(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1;
if (joinRangeStartIdx === joinRangeEndIdxExclusive) {
// If there is no element that touches range, then joinRangeStartIdx === joinRangeEndIdxExclusive and that value is the index of the element after range
this._normalizedRanges.splice(joinRangeStartIdx, 0, range);
} else if (joinRangeStartIdx === joinRangeEndIdxExclusive - 1) {
// Else, there is an element that touches range and in this case it is both the first and last element. Thus we can replace it
const joinRange = this._normalizedRanges[joinRangeStartIdx];
this._normalizedRanges[joinRangeStartIdx] = joinRange.join(range);
} else {
// First and last element are different - we need to replace the entire range
const joinRange = this._normalizedRanges[joinRangeStartIdx].join(this._normalizedRanges[joinRangeEndIdxExclusive - 1]).join(range);
this._normalizedRanges.splice(joinRangeStartIdx, joinRangeEndIdxExclusive - joinRangeStartIdx, joinRange);
}
}
intersects(range: LineRange): boolean {
for (const r of this._normalizedRanges) {
if (r.intersectsStrict(range)) {
return true;
}
}
return false;
}
/**
* Subtracts all ranges in this set from `range` and returns the result.
*/
subtractFrom(range: LineRange): LineRange[] {
// idx of first element that touches range or that is after range
const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length);
// idx of element after { last element that touches range or that is before range }
const joinRangeEndIdxExclusive = findLastIndex(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1;
if (joinRangeStartIdx === joinRangeEndIdxExclusive) {
return [range];
}
const result: LineRange[] = [];
let startLineNumber = range.startLineNumber;
for (let i = joinRangeStartIdx; i < joinRangeEndIdxExclusive; i++) {
const r = this._normalizedRanges[i];
if (r.startLineNumber > startLineNumber) {
result.push(new LineRange(startLineNumber, r.startLineNumber));
}
startLineNumber = r.endLineNumberExclusive;
}
if (startLineNumber < range.endLineNumberExclusive) {
result.push(new LineRange(startLineNumber, range.endLineNumberExclusive));
}
return result;
}
}
function mapMinusOne(idx: number, mapTo: number): number {
return idx === -1 ? mapTo : idx;
}
function coverFullWords(sequence1: LinesSliceCharSequence, sequence2: LinesSliceCharSequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] {
const additional: SequenceDiff[] = [];
@@ -555,42 +509,42 @@ function mergeSequenceDiffs(sequenceDiffs1: SequenceDiff[], sequenceDiffs2: Sequ
return result;
}
export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[], dontAssertStartLine: boolean = false): LineRangeMapping[] {
const changes: LineRangeMapping[] = [];
for (const g of group(
export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[], dontAssertStartLine: boolean = false): DetailedLineRangeMapping[] {
const changes: DetailedLineRangeMapping[] = [];
for (const g of groupAdjacentBy(
alignments.map(a => getLineRangeMapping(a, originalLines, modifiedLines)),
(a1, a2) =>
a1.originalRange.overlapOrTouch(a2.originalRange)
|| a1.modifiedRange.overlapOrTouch(a2.modifiedRange)
a1.original.overlapOrTouch(a2.original)
|| a1.modified.overlapOrTouch(a2.modified)
)) {
const first = g[0];
const last = g[g.length - 1];
changes.push(new LineRangeMapping(
first.originalRange.join(last.originalRange),
first.modifiedRange.join(last.modifiedRange),
changes.push(new DetailedLineRangeMapping(
first.original.join(last.original),
first.modified.join(last.modified),
g.map(a => a.innerChanges![0]),
));
}
assertFn(() => {
if (!dontAssertStartLine) {
if (changes.length > 0 && changes[0].originalRange.startLineNumber !== changes[0].modifiedRange.startLineNumber) {
if (changes.length > 0 && changes[0].original.startLineNumber !== changes[0].modified.startLineNumber) {
return false;
}
}
return checkAdjacentItems(changes,
(m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&
(m1, m2) => m2.original.startLineNumber - m1.original.endLineNumberExclusive === m2.modified.startLineNumber - m1.modified.endLineNumberExclusive &&
// There has to be an unchanged line in between (otherwise both diffs should have been joined)
m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&
m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber,
m1.original.endLineNumberExclusive < m2.original.startLineNumber &&
m1.modified.endLineNumberExclusive < m2.modified.startLineNumber,
);
});
return changes;
}
export function getLineRangeMapping(rangeMapping: RangeMapping, originalLines: string[], modifiedLines: string[]): LineRangeMapping {
export function getLineRangeMapping(rangeMapping: RangeMapping, originalLines: string[], modifiedLines: string[]): DetailedLineRangeMapping {
let lineStartDelta = 0;
let lineEndDelta = 0;
@@ -624,26 +578,7 @@ export function getLineRangeMapping(rangeMapping: RangeMapping, originalLines: s
rangeMapping.modifiedRange.endLineNumber + 1 + lineEndDelta
);
return new LineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]);
}
function* group<T>(items: Iterable<T>, shouldBeGrouped: (item1: T, item2: T) => boolean): Iterable<T[]> {
let currentGroup: T[] | undefined;
let last: T | undefined;
for (const item of items) {
if (last !== undefined && shouldBeGrouped(last, item)) {
currentGroup!.push(item);
} else {
if (currentGroup) {
yield currentGroup;
}
currentGroup = [item];
}
last = item;
}
if (currentGroup) {
yield currentGroup;
}
return new DetailedLineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]);
}
export class LineSequence implements ISequence {
@@ -685,7 +620,7 @@ function getIndentation(str: string): number {
export class LinesSliceCharSequence implements ISequence {
private readonly elements: number[] = [];
private readonly firstCharOffsetByLineMinusOne: number[] = [];
private readonly firstCharOffsetByLine: number[] = [];
public readonly lineRange: OffsetRange;
// To account for trimming
private readonly additionalOffsetByLine: number[] = [];
@@ -703,6 +638,7 @@ export class LinesSliceCharSequence implements ISequence {
this.lineRange = lineRange;
this.firstCharOffsetByLine[0] = 0;
for (let i = this.lineRange.start; i < this.lineRange.endExclusive; i++) {
let line = lines[i];
let offset = 0;
@@ -725,7 +661,7 @@ export class LinesSliceCharSequence implements ISequence {
// Don't add an \n that does not exist in the document.
if (i < lines.length - 1) {
this.elements.push('\n'.charCodeAt(0));
this.firstCharOffsetByLineMinusOne[i - this.lineRange.start] = this.elements.length;
this.firstCharOffsetByLine[i - this.lineRange.start + 1] = this.elements.length;
}
}
// To account for the last line
@@ -784,19 +720,8 @@ export class LinesSliceCharSequence implements ISequence {
return new Position(this.lineRange.start + 1, 1);
}
let i = 0;
let j = this.firstCharOffsetByLineMinusOne.length;
while (i < j) {
const k = Math.floor((i + j) / 2);
if (this.firstCharOffsetByLineMinusOne[k] > offset) {
j = k;
} else {
i = k + 1;
}
}
const offsetOfFirstCharInLine = i === 0 ? 0 : this.firstCharOffsetByLineMinusOne[i - 1];
return new Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.additionalOffsetByLine[i]);
const i = findLastIdxMonotonous(this.firstCharOffsetByLine, (value) => value <= offset);
return new Position(this.lineRange.start + i + 1, offset - this.firstCharOffsetByLine[i] + this.additionalOffsetByLine[i] + 1);
}
public translateRange(range: OffsetRange): Range {
@@ -839,49 +764,12 @@ export class LinesSliceCharSequence implements ISequence {
}
public extendToFullLines(range: OffsetRange): OffsetRange {
const firstIdx = findLastIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => x <= range.start);
const lastIdx = findFirstIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => range.endExclusive <= x);
const start = firstIdx === -1 ? 0 : this.firstCharOffsetByLineMinusOne[firstIdx];
const end = lastIdx === this.firstCharOffsetByLineMinusOne.length ? this.elements.length : this.firstCharOffsetByLineMinusOne[lastIdx];
const start = findLastMonotonous(this.firstCharOffsetByLine, x => x <= range.start) ?? 0;
const end = findFirstMonotonous(this.firstCharOffsetByLine, x => range.endExclusive <= x) ?? this.elements.length;
return new OffsetRange(start, end);
}
}
/**
* @returns -1 if predicate is false for all items
*/
function findLastIdxMonotonous<T>(arr: T[], predicate: (item: T) => boolean): number {
let i = 0;
let j = arr.length;
while (i < j) {
const k = Math.floor((i + j) / 2);
if (predicate(arr[k])) {
i = k + 1;
} else {
j = k;
}
}
return i - 1;
}
/**
* @returns arr.length if predicate is false for all items
*/
function findFirstIdxMonotonous<T>(arr: T[], predicate: (item: T) => boolean): number {
let i = 0;
let j = arr.length;
while (i < j) {
const k = Math.floor((i + j) / 2);
if (predicate(arr[k])) {
j = k;
} else {
i = k + 1;
}
}
return i;
}
function isWordChar(charCode: number): boolean {
return charCode >= CharCode.a && charCode <= CharCode.z
|| charCode >= CharCode.A && charCode <= CharCode.Z
@@ -954,7 +842,7 @@ class LineRangeFragment {
constructor(
public readonly range: LineRange,
public readonly lines: string[],
public readonly source: LineRangeMapping,
public readonly source: DetailedLineRangeMapping,
) {
let counter = 0;
for (let i = range.startLineNumber - 1; i < range.endLineNumberExclusive - 1; i++) {
@@ -5,7 +5,8 @@
import { CancellationToken } from 'vs/base/common/cancellation';
import { Event } from 'vs/base/common/event';
import { LineRangeMapping, MovedText } from 'vs/editor/common/diff/linesDiffComputer';
import { MovedText } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping } from './rangeMapping';
import { ITextModel } from 'vs/editor/common/model';
/**
@@ -61,7 +62,7 @@ export interface IDocumentDiff {
/**
* Maps all modified line ranges in the original to the corresponding line ranges in the modified text model.
*/
readonly changes: readonly LineRangeMapping[];
readonly changes: readonly DetailedLineRangeMapping[];
/**
* Sorted by original line ranges.
@@ -5,7 +5,8 @@
import { CharCode } from 'vs/base/common/charCode';
import { IDiffChange, ISequence, LcsDiff, IDiffResult } from 'vs/base/common/diff/diff';
import { ILinesDiffComputer, ILinesDiffComputerOptions, RangeMapping, LineRangeMapping, LinesDiff } from 'vs/editor/common/diff/linesDiffComputer';
import { ILinesDiffComputer, ILinesDiffComputerOptions, LinesDiff } from 'vs/editor/common/diff/linesDiffComputer';
import { RangeMapping, DetailedLineRangeMapping } from './rangeMapping';
import * as strings from 'vs/base/common/strings';
import { Range } from 'vs/editor/common/core/range';
import { assertFn, checkAdjacentItems } from 'vs/base/common/assert';
@@ -23,8 +24,8 @@ export class LegacyLinesDiffComputer implements ILinesDiffComputer {
shouldPostProcessCharChanges: true,
});
const result = diffComputer.computeDiff();
const changes: LineRangeMapping[] = [];
let lastChange: LineRangeMapping | null = null;
const changes: DetailedLineRangeMapping[] = [];
let lastChange: DetailedLineRangeMapping | null = null;
for (const c of result.changes) {
@@ -44,17 +45,17 @@ export class LegacyLinesDiffComputer implements ILinesDiffComputer {
modifiedRange = new LineRange(c.modifiedStartLineNumber, c.modifiedEndLineNumber + 1);
}
let change = new LineRangeMapping(originalRange, modifiedRange, c.charChanges?.map(c => new RangeMapping(
let change = new DetailedLineRangeMapping(originalRange, modifiedRange, c.charChanges?.map(c => new RangeMapping(
new Range(c.originalStartLineNumber, c.originalStartColumn, c.originalEndLineNumber, c.originalEndColumn),
new Range(c.modifiedStartLineNumber, c.modifiedStartColumn, c.modifiedEndLineNumber, c.modifiedEndColumn),
)));
if (lastChange) {
if (lastChange.modifiedRange.endLineNumberExclusive === change.modifiedRange.startLineNumber
|| lastChange.originalRange.endLineNumberExclusive === change.originalRange.startLineNumber) {
if (lastChange.modified.endLineNumberExclusive === change.modified.startLineNumber
|| lastChange.original.endLineNumberExclusive === change.original.startLineNumber) {
// join touching diffs. Probably moving diffs up/down in the algorithm causes touching diffs.
change = new LineRangeMapping(
lastChange.originalRange.join(change.originalRange),
lastChange.modifiedRange.join(change.modifiedRange),
change = new DetailedLineRangeMapping(
lastChange.original.join(change.original),
lastChange.modified.join(change.modified),
lastChange.innerChanges && change.innerChanges ?
lastChange.innerChanges.concat(change.innerChanges) : undefined
);
@@ -68,10 +69,10 @@ export class LegacyLinesDiffComputer implements ILinesDiffComputer {
assertFn(() => {
return checkAdjacentItems(changes,
(m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&
(m1, m2) => m2.original.startLineNumber - m1.original.endLineNumberExclusive === m2.modified.startLineNumber - m1.modified.endLineNumberExclusive &&
// There has to be an unchanged line in between (otherwise both diffs should have been joined)
m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&
m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber,
m1.original.endLineNumberExclusive < m2.original.startLineNumber &&
m1.modified.endLineNumberExclusive < m2.modified.startLineNumber,
);
});
@@ -92,7 +93,7 @@ export interface IDiffComputationResult {
/**
* The changes as (modern) line range mapping array.
*/
changes2: readonly LineRangeMapping[];
changes2: readonly DetailedLineRangeMapping[];
}
/**
+6 -136
View File
@@ -3,8 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LineRange } from 'vs/editor/common/core/lineRange';
import { Range } from 'vs/editor/common/core/range';
import { DetailedLineRangeMapping, LineRangeMapping } from './rangeMapping';
export interface ILinesDiffComputer {
computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff;
@@ -18,7 +17,7 @@ export interface ILinesDiffComputerOptions {
export class LinesDiff {
constructor(
readonly changes: readonly LineRangeMapping[],
readonly changes: readonly DetailedLineRangeMapping[],
/**
* Sorted by original line ranges.
@@ -35,148 +34,19 @@ export class LinesDiff {
}
}
/**
* Maps a line range in the original text model to a line range in the modified text model.
*/
export class LineRangeMapping {
public static inverse(mapping: readonly LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): LineRangeMapping[] {
const result: LineRangeMapping[] = [];
let lastOriginalEndLineNumber = 1;
let lastModifiedEndLineNumber = 1;
for (const m of mapping) {
const r = new LineRangeMapping(
new LineRange(lastOriginalEndLineNumber, m.originalRange.startLineNumber),
new LineRange(lastModifiedEndLineNumber, m.modifiedRange.startLineNumber),
undefined
);
if (!r.modifiedRange.isEmpty) {
result.push(r);
}
lastOriginalEndLineNumber = m.originalRange.endLineNumberExclusive;
lastModifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive;
}
const r = new LineRangeMapping(
new LineRange(lastOriginalEndLineNumber, originalLineCount + 1),
new LineRange(lastModifiedEndLineNumber, modifiedLineCount + 1),
undefined
);
if (!r.modifiedRange.isEmpty) {
result.push(r);
}
return result;
}
/**
* The line range in the original text model.
*/
public readonly originalRange: LineRange;
/**
* The line range in the modified text model.
*/
public readonly modifiedRange: LineRange;
/**
* If inner changes have not been computed, this is set to undefined.
* Otherwise, it represents the character-level diff in this line range.
* The original range of each range mapping should be contained in the original line range (same for modified), exceptions are new-lines.
* Must not be an empty array.
*/
public readonly innerChanges: RangeMapping[] | undefined;
constructor(
originalRange: LineRange,
modifiedRange: LineRange,
innerChanges: RangeMapping[] | undefined,
) {
this.originalRange = originalRange;
this.modifiedRange = modifiedRange;
this.innerChanges = innerChanges;
}
public toString(): string {
return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;
}
public get changedLineCount() {
return Math.max(this.originalRange.length, this.modifiedRange.length);
}
public flip(): LineRangeMapping {
return new LineRangeMapping(this.modifiedRange, this.originalRange, this.innerChanges?.map(c => c.flip()));
}
}
/**
* Maps a range in the original text model to a range in the modified text model.
*/
export class RangeMapping {
/**
* The original range.
*/
readonly originalRange: Range;
/**
* The modified range.
*/
readonly modifiedRange: Range;
constructor(
originalRange: Range,
modifiedRange: Range,
) {
this.originalRange = originalRange;
this.modifiedRange = modifiedRange;
}
public toString(): string {
return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;
}
public flip(): RangeMapping {
return new RangeMapping(this.modifiedRange, this.originalRange);
}
}
// TODO@hediet: Make LineRangeMapping extend from this!
export class SimpleLineRangeMapping {
constructor(
public readonly original: LineRange,
public readonly modified: LineRange,
) {
}
public toString(): string {
return `{${this.original.toString()}->${this.modified.toString()}}`;
}
public flip(): SimpleLineRangeMapping {
return new SimpleLineRangeMapping(this.modified, this.original);
}
public join(other: SimpleLineRangeMapping): SimpleLineRangeMapping {
return new SimpleLineRangeMapping(
this.original.join(other.original),
this.modified.join(other.modified),
);
}
}
export class MovedText {
public readonly lineRangeMapping: SimpleLineRangeMapping;
public readonly lineRangeMapping: LineRangeMapping;
/**
* The diff from the original text to the moved text.
* Must be contained in the original/modified line range.
* Can be empty if the text didn't change (only moved).
*/
public readonly changes: readonly LineRangeMapping[];
public readonly changes: readonly DetailedLineRangeMapping[];
constructor(
lineRangeMapping: SimpleLineRangeMapping,
changes: readonly LineRangeMapping[],
lineRangeMapping: LineRangeMapping,
changes: readonly DetailedLineRangeMapping[],
) {
this.lineRangeMapping = lineRangeMapping;
this.changes = changes;
+133
View File
@@ -0,0 +1,133 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LineRange } from 'vs/editor/common/core/lineRange';
import { Range } from 'vs/editor/common/core/range';
export class LineRangeMapping {
public static inverse(mapping: readonly DetailedLineRangeMapping[], originalLineCount: number, modifiedLineCount: number): DetailedLineRangeMapping[] {
const result: DetailedLineRangeMapping[] = [];
let lastOriginalEndLineNumber = 1;
let lastModifiedEndLineNumber = 1;
for (const m of mapping) {
const r = new DetailedLineRangeMapping(
new LineRange(lastOriginalEndLineNumber, m.original.startLineNumber),
new LineRange(lastModifiedEndLineNumber, m.modified.startLineNumber),
undefined
);
if (!r.modified.isEmpty) {
result.push(r);
}
lastOriginalEndLineNumber = m.original.endLineNumberExclusive;
lastModifiedEndLineNumber = m.modified.endLineNumberExclusive;
}
const r = new DetailedLineRangeMapping(
new LineRange(lastOriginalEndLineNumber, originalLineCount + 1),
new LineRange(lastModifiedEndLineNumber, modifiedLineCount + 1),
undefined
);
if (!r.modified.isEmpty) {
result.push(r);
}
return result;
}
/**
* The line range in the original text model.
*/
public readonly original: LineRange;
/**
* The line range in the modified text model.
*/
public readonly modified: LineRange;
constructor(
originalRange: LineRange,
modifiedRange: LineRange
) {
this.original = originalRange;
this.modified = modifiedRange;
}
public toString(): string {
return `{${this.original.toString()}->${this.modified.toString()}}`;
}
public flip(): LineRangeMapping {
return new LineRangeMapping(this.modified, this.original);
}
public join(other: LineRangeMapping): LineRangeMapping {
return new LineRangeMapping(
this.original.join(other.original),
this.modified.join(other.modified)
);
}
public get changedLineCount() {
return Math.max(this.original.length, this.modified.length);
}
}
/**
* Maps a line range in the original text model to a line range in the modified text model.
*/
export class DetailedLineRangeMapping extends LineRangeMapping {
/**
* If inner changes have not been computed, this is set to undefined.
* Otherwise, it represents the character-level diff in this line range.
* The original range of each range mapping should be contained in the original line range (same for modified), exceptions are new-lines.
* Must not be an empty array.
*/
public readonly innerChanges: RangeMapping[] | undefined;
constructor(
originalRange: LineRange,
modifiedRange: LineRange,
innerChanges: RangeMapping[] | undefined
) {
super(originalRange, modifiedRange);
this.innerChanges = innerChanges;
}
public override flip(): DetailedLineRangeMapping {
return new DetailedLineRangeMapping(this.modified, this.original, this.innerChanges?.map(c => c.flip()));
}
}
/**
* Maps a range in the original text model to a range in the modified text model.
*/
export class RangeMapping {
/**
* The original range.
*/
readonly originalRange: Range;
/**
* The modified range.
*/
readonly modifiedRange: Range;
constructor(
originalRange: Range,
modifiedRange: Range
) {
this.originalRange = originalRange;
this.modifiedRange = modifiedRange;
}
public toString(): string {
return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;
}
public flip(): RangeMapping {
return new RangeMapping(this.modifiedRange, this.originalRange);
}
}
@@ -21,7 +21,8 @@ import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost';
import { StopWatch } from 'vs/base/common/stopwatch';
import { UnicodeTextModelHighlighter, UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter';
import { DiffComputer, IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer';
import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer';
import { ILinesDiffComputer, ILinesDiffComputerOptions } from 'vs/editor/common/diff/linesDiffComputer';
import { DetailedLineRangeMapping } from '../diff/rangeMapping';
import { linesDiffComputers } from 'vs/editor/common/diff/linesDiffComputers';
import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects';
import { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider';
@@ -422,8 +423,8 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable {
const identical = (result.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel));
function getLineChanges(changes: readonly LineRangeMapping[]): ILineChange[] {
return changes.map(m => ([m.originalRange.startLineNumber, m.originalRange.endLineNumberExclusive, m.modifiedRange.startLineNumber, m.modifiedRange.endLineNumberExclusive, m.innerChanges?.map(m => [
function getLineChanges(changes: readonly DetailedLineRangeMapping[]): ILineChange[] {
return changes.map(m => ([m.original.startLineNumber, m.original.endLineNumberExclusive, m.modified.startLineNumber, m.modified.endLineNumberExclusive, m.innerChanges?.map(m => [
m.originalRange.startLineNumber,
m.originalRange.startColumn,
m.originalRange.endLineNumber,
+4 -4
View File
@@ -10,17 +10,17 @@ export namespace AccessibilityHelpNLS {
export const openingDocs = nls.localize("openingDocs", "Now opening the Accessibility documentation page.");
export const readonlyDiffEditor = nls.localize("readonlyDiffEditor", "You are in a read-only pane of a diff editor.");
export const editableDiffEditor = nls.localize("editableDiffEditor", "You are in a pane of a diff editor.");
export const readonlyEditor = nls.localize("readonlyEditor", "You are in a read-only code editor");
export const editableEditor = nls.localize("editableEditor", "You are in a code editor");
export const readonlyEditor = nls.localize("readonlyEditor", "You are in a read-only code editor.");
export const editableEditor = nls.localize("editableEditor", "You are in a code editor.");
export const changeConfigToOnMac = nls.localize("changeConfigToOnMac", "To configure the application to be optimized for usage with a Screen Reader press Command+E now.");
export const changeConfigToOnWinLinux = nls.localize("changeConfigToOnWinLinux", "To configure the application to be optimized for usage with a Screen Reader press Control+E now.");
export const auto_on = nls.localize("auto_on", "The application is configured to be optimized for usage with a Screen Reader.");
export const auto_off = nls.localize("auto_off", "The application is configured to never be optimized for usage with a Screen Reader");
export const auto_off = nls.localize("auto_off", "The application is configured to never be optimized for usage with a Screen Reader.");
export const screenReaderModeEnabled = nls.localize("screenReaderModeEnabled", "Screen Reader Optimized Mode enabled.");
export const screenReaderModeDisabled = nls.localize("screenReaderModeDisabled", "Screen Reader Optimized Mode disabled.");
export const tabFocusModeOnMsg = nls.localize("tabFocusModeOnMsg", "Pressing Tab in the current editor will move focus to the next focusable element. Toggle this behavior by pressing {0}.");
export const tabFocusModeOnMsgNoKb = nls.localize("tabFocusModeOnMsgNoKb", "Pressing Tab in the current editor will move focus to the next focusable element. The command {0} is currently not triggerable by a keybinding.");
export const stickScrollKb = nls.localize("stickScrollKb", "Run the command: Focus Sticky Scroll ({0}) to focus the currently nested scopes");
export const stickScrollKb = nls.localize("stickScrollKb", "Run the command: Focus Sticky Scroll ({0}) to focus the currently nested scopes.");
export const stickScrollNoKb = nls.localize("stickScrollNoKb", "Run the command: Focus Sticky Scroll to focus the currently nested scopes. It is currently not triggerable by a keybinding.");
export const tabFocusModeOffMsg = nls.localize("tabFocusModeOffMsg", "Pressing Tab in the current editor will insert the tab character. Toggle this behavior by pressing {0}.");
export const tabFocusModeOffMsgNoKb = nls.localize("tabFocusModeOffMsgNoKb", "Pressing Tab in the current editor will insert the tab character. The command {0} is currently not triggerable by a keybinding.");
+12
View File
@@ -445,4 +445,16 @@ export class OverviewRulerDecorationsGroup {
}
return a.zIndex - b.zIndex;
}
public static equalsArr(a: OverviewRulerDecorationsGroup[], b: OverviewRulerDecorationsGroup[]): boolean {
if (a.length !== b.length) {
return false;
}
for (let i = 0, len = a.length; i < len; i++) {
if (OverviewRulerDecorationsGroup.cmp(a[i], b[i]) !== 0) {
return false;
}
}
return true;
}
}
@@ -232,6 +232,9 @@ export class CodeLensContribution implements IEditorContribution {
this._localToDispose.add(this._editor.onDidFocusEditorWidget(() => {
scheduler.schedule();
}));
this._localToDispose.add(this._editor.onDidBlurEditorText(() => {
scheduler.cancel();
}));
this._localToDispose.add(this._editor.onDidScrollChange(e => {
if (e.scrollTopChanged && this._lenses.length > 0) {
this._resolveCodeLensesInViewportSoon();
@@ -444,8 +447,12 @@ export class CodeLensContribution implements IEditorContribution {
});
}
getModel(): CodeLensModel | undefined {
return this._currentCodeLensModel;
async getModel(): Promise<CodeLensModel | undefined> {
await this._getCodeLensModelPromise;
await this._resolveCodeLensesPromise;
return !this._currentCodeLensModel?.isDisposed
? this._currentCodeLensModel
: undefined;
}
}
@@ -478,7 +485,7 @@ registerEditorAction(class ShowLensesInCurrentLine extends EditorAction {
return;
}
const model = codelensController.getModel();
const model = await codelensController.getModel();
if (!model) {
// nothing
return;
@@ -499,19 +506,31 @@ registerEditorAction(class ShowLensesInCurrentLine extends EditorAction {
return;
}
const item = await quickInputService.pick(items, { canPickMany: false });
const item = await quickInputService.pick(items, {
canPickMany: false,
placeHolder: localize('placeHolder', "Select a command")
});
if (!item) {
// Nothing picked
return;
}
let command = item.command;
if (model.isDisposed) {
// retry whenever the model has been disposed
return await commandService.executeCommand(this.id);
// try to find the same command again in-case the model has been re-created in the meantime
// this is a best attempt approach which shouldn't be needed because eager model re-creates
// shouldn't happen due to focus in/out anymore
const newModel = await codelensController.getModel();
const newLens = newModel?.lenses.find(lens => lens.symbol.range.startLineNumber === lineNumber && lens.symbol.command?.title === command.title);
if (!newLens || !newLens.symbol.command) {
return;
}
command = newLens.symbol.command;
}
try {
await commandService.executeCommand(item.command.id, ...(item.command.arguments || []));
await commandService.executeCommand(command.id, ...(command.arguments || []));
} catch (err) {
notificationService.error(err);
}
@@ -35,6 +35,7 @@
.monaco-editor .sticky-line-number .codicon {
float: right;
transition: var(--vscode-editorStickyScroll-foldingOpacityTransition);
}
.monaco-editor .sticky-line-content {

Some files were not shown because too many files have changed in this diff Show More