diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000000000..6b833803b2e34 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,191 @@ +# Coding Guidelines + +## Introduction + +These are VS Code coding guidelines. Please also review our [Source Code Organisation](https://github.com/microsoft/vscode/wiki/Source-Code-Organization) page. + +## Indentation + +We use tabs, not spaces. + +## Naming Conventions + +* Use PascalCase for `type` names +* Use PascalCase for `enum` values +* Use camelCase for `function` and `method` names +* Use camelCase for `property` names and `local variables` +* Use whole words in names when possible + +## Types + +* Do not export `types` or `functions` unless you need to share it across multiple components +* Do not introduce new `types` or `values` to the global namespace + +## Comments + +* When there are comments for `functions`, `interfaces`, `enums`, and `classes` use JSDoc style comments + +## Strings + +* Use "double quotes" for strings shown to the user that need to be externalized (localized) +* Use 'single quotes' otherwise +* All strings visible to the user need to be externalized + +## Style + +* Use arrow functions `=>` over anonymous function expressions +* Only surround arrow function parameters when necessary. For example, `(x) => x + x` is wrong but the following are correct: + +```javascript +x => x + x +(x, y) => x + y +(x: T, y: T) => x === y +``` + +* Always surround loop and conditional bodies with curly braces +* Open curly braces always go on the same line as whatever necessitates them +* Parenthesized constructs should have no surrounding whitespace. A single space follows commas, colons, and semicolons in those constructs. For example: + +```javascript +for (let i = 0, n = str.length; i < 10; i++) { + if (x < 10) { + foo(); + } +} + +function f(x: number, y: string): void { } +``` + +# Extension API Guidelines + +## Overview + +The following guidelines only apply to files in the `src/vscode-dts` folder. + +This is a loose collection of guidelines that you should be following when proposing API. The process for adding API is described here: [Extension API Process](https://github.com/Microsoft/vscode/wiki/Extension-API-process). + +## Core Principles + +### Avoid Breakage + +We DO NOT want to break API. Therefore be careful and conservative when proposing new API. It needs to hold up in the long term. Expose only the minimum but still try to anticipate potential future requests. + +### Namespaces + +The API is structured into different namespaces, like `commands`, `window`, `workspace` etc. Namespaces contain functions, constants, and events. All types (classes, enum, interfaces) are defined in the global, `vscode`, namespace. + +### JavaScript Feel + +The API should have a JavaScript’ish feel. While that is harder to put in rules, it means we use namespaces, properties, functions, and globals instead of object-factories and services. Also take inspiration from popular existing JS API, for instance `window.createStatusBarItem` is like `document.createElement`, the members of `DiagnosticsCollection` are similar to ES6 maps etc. + +### Global Events + +Events aren’t defined on the types they occur on but in the best matching namespace. For instance, document changes aren't sent by a document but via the `workspace.onDidChangeTextDocument` event. The event will contain the document in question. This **global event** pattern makes it easier to manage event subscriptions because changes happen less frequently. + +### Private Events + +Private or instance events aren't accessible via globals but exist on objects, e.g., `FileSystemWatcher#onDidCreate`. *Don't* use private events unless the sender of the event is private. The rule of thumb is: 'Objects that can be accessed globally (editors, tasks, terminals, documents, etc)' should not have private events, objects that are private (only known by its creators, like tree views, web views) can send private events' + +### Event Naming + +Events follow the `on[Did|Will]VerbSubject` patterns, like `onDidChangeActiveEditor` or `onWillSaveTextDocument`. It doesn’t hurt to use explicit names. + +### Creating Objects + +Objects that live in the main thread but can be controlled/instantiated by extensions are declared as interfaces, e.g. `TextDocument` or `StatusBarItem`. When you allow creating such objects your API must follow the `createXYZ(args): XYZ` pattern. Because this is a constructor-replacement, the call must return synchronously. + +### Shy Objects + +Objects the API hands out to extensions should not contain more than what the API defines. Don’t expect everyone to read `vscode.d.ts` but also expect folks to use debugging-aided-intellisense, meaning whatever the debugger shows developers will program against. We don’t want to appear as making false promises. Prefix your private members with `_` as that is a common rule or, even better, use function-scopes to hide information. + +### Sync vs. Async + +Reading data, like an editor selection, a configuration value, etc. is synchronous. Setting a state that reflects on the main side is asynchronous. Despite updates being async your ‘extension host object’ should reflect the new state synchronously. This happens when setting an editor selection + +``` + editor.selection = newSelection + + | + | + V + + 1. On the API object set the value as given + 2. Make an async-call to the main side ala `trySetSelection` + 3. The async-call returns with the actual selection (it might have changed in the meantime) + 4. On the API object set the value again +``` + +We usually don’t expose the fact that setting state is asynchronous. We try to have API that feels sync -`editor.selection` is a getter/setter and not a method. + +### Data Driven + +Whenever possible, you should define a data model and define provider-interfaces. This puts VS Code into control as we can decide when to ask those providers, how to deal with multiple providers etc. The `ReferenceProvider` interface is a good sample for this. + +### Enrich Data Incrementally + +Sometimes it is expensive for a provider to compute parts of its data. For instance, creating a full `CompletionItem` (with all the documentation and symbols resolved) conflicts with being able to compute a large list of them quickly. In those cases, providers should return a lightweight version and offer a `resolve` method that allows extensions to enrich data. The `CodeLensProvider` and `CompletionItemProvider` interfaces are good samples for this. + +### Cancellation + +Calls into a provider should always include a `CancellationToken` as the last parameter. With that, the main thread can signal to the provider that its result won’t be needed anymore. When adding new parameters to provider-functions, it is OK to have the token not at the end anymore. + +### Objects vs. Interfaces + +Objects that should be returned by a provider are usually represented by a class that extensions can instantiate, e.g. `CodeLens`. We do that to provide convenience constructors and to be able to populate default values. + +Data that we accept in methods calls, i.e., parameter types, like in `registerRenameProvider` or `showQuickPick`, are declared as interfaces. That makes it easy to fulfill the API contract using class-instances or plain object literals. + +### Strict and Relaxed Data + +Data the API returns is strict, e.g. `activeTextEditor` is an editor or `undefined`, but not `null`. On the other side, providers can return relaxed data. We usually accept 4 types: The actual type, like `Hover`, a `Thenable` of that type, `undefined` or `null`. With that we want to make it easy to implement a provider, e.g., if you can compute results synchronous you don’t need to wrap things into a promise or if a certain condition isn’t met simple return, etc. + +### Validate Data + +Although providers can return ‘relaxed’ data, you need to verify it. The same is true for arguments etc. Throw validation errors when possible, drop data object when invalid. + +### Copy Data + +Don’t send the data that a provider returned over the wire. Often it contains more information than we need and often there are cyclic dependencies. Use the provider data to create objects that your protocol speaks. + +### Enums + +When API-work started only numeric-enums were supported, today TypeScript supports string-or-types and string-enums. Because fewer concepts are better, we stick to numeric-enums. + +### Strict Null + +We define the API with strictNull-checks in mind. That means we use the optional annotation `foo?: number` and `null` or `undefined` in type annotations. For instance, its `activeTextEditor: TextEditor | undefined`. Again, be strict for types we define and relaxed when accepting data. + +### Undefined is False + +The default value of an optional, boolean property is `false`. This is for consistency with JS where undefined never evaluates to `true`. + +### JSDoc + +We add JSDoc for all parts of the API. The doc is supported by markdown syntax. When document string-datatypes that end up in the UI, use the phrase ‘Human-readable string…’ + +## Optional Parameters (`?` vs `| undefined`) + +* For implementation, treat omitting a parameter with `?` the same as explicitly passing in `undefined` +* Use `| undefined` when you want to callers to always have to consider the parameter. +* Use `?` when you want to allow callers to omit the parameter. +* Never use `?` and `| undefined` on a parameter. Instead follow the two rules above to decide which version to use. +* If adding a new parameter to an existing function, use `?` as this allows the new signature to be backwards compatible with the old version. +* Do not add an overload to add an optional parameter to the end of the function. Instead use `?`. + +## Optional Properties (`?` vs `| undefined`) + +* Do not write code that treats the absence of a property differently than a property being present but set to `undefined` + * This can sometimes hit you on spreads or iterating through objects, so just something to be aware of + +* For readonly properties on interfaces that VS Code exposes to extensions (this include managed objects, as well as the objects passed to events): + * Use `| undefined` as this makes it clear the property exists but has the value `undefined`. + +* For readonly properties on options bag type objects passed from extensions to VS Code: + * Use `?` when it is ok to omit the property + * Use `| undefined` when you want the user to have to pass in the property but `undefined` signals that you will fall back to some default + * Try to avoid `?` + `| undefined` in most cases. Instead use `?`. Using both `?` + `| undefined` isn't wrong, but it's often more clear to treat omitting the property as falling back to the default rather than passing in `undefined` + +* For unmanaged, writable objects: + * If using `?`, always also add `| undefined` unless want to allow the property to be omitted during initialization, but never allow users to explicitly set it to `undefined` afterwards. I don't think we have many cases where this will be needed + * In these cases, you may want to try changing the api to avoid this potential confusion + * If adding a new property to an unmanaged object, use `?` as this ensures the type is backwards compatible with the old version diff --git a/.npmrc b/.npmrc index eff6e8cdba917..22256e5d8e7ba 100644 --- a/.npmrc +++ b/.npmrc @@ -1,6 +1,6 @@ disturl="https://electronjs.org/headers" -target="32.2.5" -ms_build_id="10579404" +target="32.2.6" +ms_build_id="10629634" runtime="electron" build_from_source="true" legacy-peer-deps="true" diff --git a/build/checksums/electron.txt b/build/checksums/electron.txt index 92c742d3b5002..17ec96faa2a02 100644 --- a/build/checksums/electron.txt +++ b/build/checksums/electron.txt @@ -1,75 +1,75 @@ -fed2c175e3b63682e7b939b704b524e5af7e664f6b020cfec4895b6258190f7c *chromedriver-v32.2.5-darwin-arm64.zip -fa40996a7d0c5b830d101a0b6511300ff4477995b5af86b1e8be5e21341caa8e *chromedriver-v32.2.5-darwin-x64.zip -9881960752aa2dee6577ab4c312d0a5e69f596c209cab32e2c5bd3b32222c79a *chromedriver-v32.2.5-linux-arm64.zip -864754d188b9e7a15abd97a3b41d7d53db300ef3401b76fa81633c298e3b09f0 *chromedriver-v32.2.5-linux-armv7l.zip -75e0d1f19e61caaa2b0f50966623f2948fffc864138f6ee8fe38791b733fd182 *chromedriver-v32.2.5-linux-x64.zip -360695b3ac1f1faa9caf0c670d81ed065e230822d77343d7dd6aa2988b2ecf99 *chromedriver-v32.2.5-mas-arm64.zip -03778e3fda6d50a9f122a3e5e4a5723953918f7b67ef5a41578ae1c41a3c2579 *chromedriver-v32.2.5-mas-x64.zip -807a45c2c40a3da025a7fd394d2ef34ed78b0719f2af924694200818cca1c0ca *chromedriver-v32.2.5-win32-arm64.zip -37da8dd36a36dbafa3b20101c5a3066ca03a36db45e478872b1c88231007f35e *chromedriver-v32.2.5-win32-ia32.zip -8f624e3969185ea47840c3f65d6ff2e12a2d7d8b6251b15c8b51ff690bd0a517 *chromedriver-v32.2.5-win32-x64.zip -2424f6f47c8c2e59546fad9d93324772ea1b6d290ce4672b6689ffc45c96a950 *electron-api.json -e4b455bf2339bf3945c7eb3c9faa52f1122eb9d4b97cedeced5887c01125c33d *electron-v32.2.5-darwin-arm64-dsym-snapshot.zip -016c1ec183649162c436c599bdc6f9a02a635fec4b30b99f97cc25829d70f07c *electron-v32.2.5-darwin-arm64-dsym.zip -0cc937ba248fde2098e9affdd6aa0ea2f0091ab700d8ac9b46cba4a11a0adaff *electron-v32.2.5-darwin-arm64-symbols.zip -add26413ae4b6055a37335be8a551007b8f47759ee3bed19d3ab0463c6b3422a *electron-v32.2.5-darwin-arm64.zip -3f8802fba7a8274308b98d4ac50a730f3e75ed447cca70ae63395d6ebd1d2bc9 *electron-v32.2.5-darwin-x64-dsym-snapshot.zip -f7a427b0b884be02f89b7a5b9a8dc9a6d573cf0c3a342e18483b4719a1c9a5b0 *electron-v32.2.5-darwin-x64-dsym.zip -85b68c3869332a33d5ad3d90639b5d8e1777e67df9ae23ac85d1fa412d1ae98c *electron-v32.2.5-darwin-x64-symbols.zip -67bb4e9e02f244516f10b78b380aa19a7026e025d568878d15035debe758eef4 *electron-v32.2.5-darwin-x64.zip -8a3f519c6a31d40c9849e6641668a152e73ec210e3477d1bf2ed957ac9955b2d *electron-v32.2.5-linux-arm64-debug.zip -9c64b56211d4013643cec784b030456b6b06f01cbdb96d4acc90dd5c91b74242 *electron-v32.2.5-linux-arm64-symbols.zip -0215737ef1e8bb7ca2def455ec4abcfd5743a9fa7af0b7cfa608295a54f5aae3 *electron-v32.2.5-linux-arm64.zip -8a3f519c6a31d40c9849e6641668a152e73ec210e3477d1bf2ed957ac9955b2d *electron-v32.2.5-linux-armv7l-debug.zip -0f84c7b3be36ab416a14353ec92f439d1acd9f30be7308ad3b3b514425d7ee9c *electron-v32.2.5-linux-armv7l-symbols.zip -e692c6d20cdea3f0e26519ac660b762e8119962f6b6e0032fe2a7fb73f4d205c *electron-v32.2.5-linux-armv7l.zip -1e39d6c04ab451072539aba551df6900dd6f423678f491c3437643d3f18cf657 *electron-v32.2.5-linux-x64-debug.zip -ab3c4a7beb1e5f18259142a70eecaa5c06eb72a23a692aecee87598dc413ea58 *electron-v32.2.5-linux-x64-symbols.zip -6d92ff595786c3a8926684c6983fdcb09b20dc34b37a1affb4c4dbfb659fee1e *electron-v32.2.5-linux-x64.zip -0fac69cb73abbd8a3fefdc80008053d68f0cefa3d5a79f1a849ae6dc374d2778 *electron-v32.2.5-mas-arm64-dsym-snapshot.zip -cbced9a83753637506b3c0f1c57b42b19dffb4494746e0a2b73c8bce45f4b5ae *electron-v32.2.5-mas-arm64-dsym.zip -d5b2f03a476a96d8e87670c2e07a84b872881bc49f327145a80b3f063490e0e2 *electron-v32.2.5-mas-arm64-symbols.zip -b95e7232b208568e8d7f278eb341cdf88b8c5106403f5abedc495305e3b6744f *electron-v32.2.5-mas-arm64.zip -5031bafcb557ad61a75f925147917b575428671a252ebbf6b77f53410ae3e434 *electron-v32.2.5-mas-x64-dsym-snapshot.zip -206e023d61e299289869f96ad218863a14a5e71f05b48f16de1cc48e53ba028f *electron-v32.2.5-mas-x64-dsym.zip -7bdb96b90ffa22ef1156c508f957c66ad1033b3be1cb1a3b9dd7bb98c9088696 *electron-v32.2.5-mas-x64-symbols.zip -2f46aa2c8a9a7f28a1bd148a41d170389396c457634a896bef38e472b5e66d9c *electron-v32.2.5-mas-x64.zip -f614582a35d4e4d68ea6861d35d49062908a202e208cf09354ef66982c540f7f *electron-v32.2.5-win32-arm64-pdb.zip -c8f8375ab562970ca02ba83755c69fa104a2621ad481d25f93cec797b64bf6bc *electron-v32.2.5-win32-arm64-symbols.zip -48b81d28fdceb4ab3ca27650d79bab910a1a19dbda72271882bfdc877c71975f *electron-v32.2.5-win32-arm64-toolchain-profile.zip -b3d6ed4c2ccc567bcd4f405ed20b33e4ba9dd0bcfb54cb99017a0ed2eb8ec1ef *electron-v32.2.5-win32-arm64.zip -2d5ca8fc59b5cbb8799dd1ee2916725ed7f12d2b6264062e19b1378aca7b326a *electron-v32.2.5-win32-ia32-pdb.zip -fd8de6c8ccf7094bf83d5ce86866d9e73b082dc4f28250bc939431d79a46a2d9 *electron-v32.2.5-win32-ia32-symbols.zip -48b81d28fdceb4ab3ca27650d79bab910a1a19dbda72271882bfdc877c71975f *electron-v32.2.5-win32-ia32-toolchain-profile.zip -b426125e315e2819c60b39b2e443d8a76e5b1fc320595b5b560b00e931c6a0d1 *electron-v32.2.5-win32-ia32.zip -8bb5edd099cc5ef155179928fba6bc3d78b7111eed8e6b9727bc068c787ec235 *electron-v32.2.5-win32-x64-pdb.zip -329eb0d32cb6c03c617dc5b5378c97a6f359b63492c00207a73ec0dd427d70a4 *electron-v32.2.5-win32-x64-symbols.zip -48b81d28fdceb4ab3ca27650d79bab910a1a19dbda72271882bfdc877c71975f *electron-v32.2.5-win32-x64-toolchain-profile.zip -0ae7add4862e34675384e7119902e6d2384d2712a5ebe98d8994b45dfa6ead12 *electron-v32.2.5-win32-x64.zip -146a192ac5e05bbd8172e3107cd4a1cae2b4882c98272ec735a2628889803104 *electron.d.ts -3f1f2db3beade0ef71ba4e8c1549368133f9aad1f377db91aba3dbac773dc770 *ffmpeg-v32.2.5-darwin-arm64.zip -441b3459f3e684f1444a7a88b56d88efc7ed0f466efc71b4daa32b467442231a *ffmpeg-v32.2.5-darwin-x64.zip -3f1eafaf4cd90ab43ba0267429189be182435849a166a2cbe1faefc0d07217c4 *ffmpeg-v32.2.5-linux-arm64.zip -3db919bc57e1a5bf7c1bae1d7aeacf4a331990ea82750391c0b24a046d9a2812 *ffmpeg-v32.2.5-linux-armv7l.zip -fe7d779dddbfb5da5999a7607fc5e3c7a6ab7c65e8da9fee1384918865231612 *ffmpeg-v32.2.5-linux-x64.zip -20f83028f1e263287bc83ec817d548a3e9c160aeadeb97bea0b40b6c256e6b2f *ffmpeg-v32.2.5-mas-arm64.zip -921551e865c81047259b77325c5d1bfc1cd29463c2eab7d9b37bb2bb507e9e25 *ffmpeg-v32.2.5-mas-x64.zip -713563936304f814324874686f19bcdc6b7d6472e8d4f4ab459970a059123d7a *ffmpeg-v32.2.5-win32-arm64.zip -616b736527e7a2b07fd62d8cff7c62d3a2f41725c4d45a6075c9354b5d758085 *ffmpeg-v32.2.5-win32-ia32.zip -517786aabef79bb55fd932676ad3ccacd776fac47b230067f3b939207ad7f204 *ffmpeg-v32.2.5-win32-x64.zip -d66731d99d7a4f586a86f3eea4b5807e7601da8d7b697a6ae0edff296b6a2206 *hunspell_dictionaries.zip -f5a90b865c32194e2e593c790ad05fb11f2011208796a0ad5438ac03792a3da0 *libcxx-objects-v32.2.5-linux-arm64.zip -dfcbae6c5b65397ec7ecf56fe9675ac2ca8a6507cdfe3abee10acd36c55536ad *libcxx-objects-v32.2.5-linux-armv7l.zip -a358503519eb66da7ae35d5ac0cf47482c045e2c03a6a0dd70e77e94f44d95c9 *libcxx-objects-v32.2.5-linux-x64.zip -7c1d5dff2dc9e9a450ec29da808ef1720bf129b71e7418b8815e8525da65f899 *libcxx_headers.zip -875d1697b3cde375ed63cb56104b1c53157bdd611fb3938f086be9579177bce2 *libcxxabi_headers.zip -1639adba066f123dbbf9d632a3ea786e7bc8e9027ff103972207e818e08946fb *mksnapshot-v32.2.5-darwin-arm64.zip -de90ae0b520d8ff3a175e632f627ccc413260d4e19e40c09cd9b1b75b4482611 *mksnapshot-v32.2.5-darwin-x64.zip -62029765e6b48ceee36a6b6c9e3252b386271c22839bafd21dabd2f3f1f19901 *mksnapshot-v32.2.5-linux-arm64-x64.zip -be21fd7442a9d599d70de8fb8776fe778b979fe85a47bfb92e57ac3158d2abcc *mksnapshot-v32.2.5-linux-armv7l-x64.zip -9a4f258c13b69846f405344e400a9dd149c943c39c04cf1799b6dc19cc223449 *mksnapshot-v32.2.5-linux-x64.zip -b53b42662802239c6f49e5c9805ed05463197ddbd8ca35436389adb4420e4ebb *mksnapshot-v32.2.5-mas-arm64.zip -f32544d647db6cdea6e538d29f05e65b01b7d8d98b8904ed7961e5ed7204cc4b *mksnapshot-v32.2.5-mas-x64.zip -8fc8daed10eea093d185a4bda35dc95789e8f99932193b6b9ff1ff5411f39c38 *mksnapshot-v32.2.5-win32-arm64-x64.zip -ce5d40a5e795be00faefa0383e32a96b8d41d3c1c050d2b86944084cb03de9db *mksnapshot-v32.2.5-win32-ia32.zip -7e9451ad4308f9d7a3dcd8e3ce55d029f82128a6b1370adb086e8f854d58d4e9 *mksnapshot-v32.2.5-win32-x64.zip +bb4164f7b554606b2c4daaf43e81bf2e2b5cf0d4441cfdd74f04653237fcf655 *chromedriver-v32.2.6-darwin-arm64.zip +a0fc3df1c6cd17bfe62ffbb1eba3655ca625dea5046e5d2b3dbb0e9e349cd10e *chromedriver-v32.2.6-darwin-x64.zip +671d6dab890747ea73ba5589327eef7612670950a20e5f88c7d8a301b5491e26 *chromedriver-v32.2.6-linux-arm64.zip +55bfd4e33fef1506261d4cb3074988e1970c2a762ca76a8f1197512a1766723c *chromedriver-v32.2.6-linux-armv7l.zip +d3c7a45c8c75152db927b3596f506995e72631df870b302b7dbcbd3399e54a3a *chromedriver-v32.2.6-linux-x64.zip +567f77d09708942901c6cdce6708b995f6ac779faceebb4ed383ca5003e2de4e *chromedriver-v32.2.6-mas-arm64.zip +b3a28181b1d077742f1be632a802e15b5a36a260b1cfe0e429735de9f52d074a *chromedriver-v32.2.6-mas-x64.zip +a113f5bd747b6eeb033f4d6ea2f53cf332d9b45d6340af514dd938bac7f99419 *chromedriver-v32.2.6-win32-arm64.zip +3b3237a788fad0a6be63a69b93c28b6052db23aeaa1a75d2589be15b4c2c0f2f *chromedriver-v32.2.6-win32-ia32.zip +1096c131cf8e3f98a01525e93d573eaf4fd23492d8dd78a211e39c448e69e463 *chromedriver-v32.2.6-win32-x64.zip +8e6fcf3171c3fcdcb117f641ec968bb53be3d38696e388636bf34f04c10b987d *electron-api.json +b1b20784a97e64992c92480e69af828a110d834372479b26759f1559b3da80fc *electron-v32.2.6-darwin-arm64-dsym-snapshot.zip +f11dd5a84229430ec59b4335415a4b308dc4330ff7b9febae20165fbdd862e92 *electron-v32.2.6-darwin-arm64-dsym.zip +cc96cf91f6b108dc927d8f7daee2fe27ae8a492c932993051508aa779e816445 *electron-v32.2.6-darwin-arm64-symbols.zip +fcb6bbb6aa3c1020b4045dbe9f2a5286173d5025248550f55631e70568e91775 *electron-v32.2.6-darwin-arm64.zip +d2bfeea27fc91936b4f71d0f5c577e5ad0ea094edba541dfa348948fd65c3331 *electron-v32.2.6-darwin-x64-dsym-snapshot.zip +5e7684cc12c0dee11fb933b68301d0fe68d3198d1daeadd5e1b4cf52743f79bf *electron-v32.2.6-darwin-x64-dsym.zip +6d2a7d41ab14fc7d3c5e4b35d5d425edb2d13978dcc332e781ec8b7bcfe6a794 *electron-v32.2.6-darwin-x64-symbols.zip +c0964ee5fdcefb1003ffd7ef574b07e5147856f3a94bb4335f78c409f8cf2eca *electron-v32.2.6-darwin-x64.zip +604d88b9d434ea66ddf234dd129dcef3d468b95b0da47e2f1555a682c8d0de28 *electron-v32.2.6-linux-arm64-debug.zip +f448e91df42fc84177bcd46378e49ee648f6114984fc57af4a84690a5197c23e *electron-v32.2.6-linux-arm64-symbols.zip +9e4f9345cae06e8e5679b228e7b7ac21b8733e3fcda8903e3dcbc8171c53f8be *electron-v32.2.6-linux-arm64.zip +604d88b9d434ea66ddf234dd129dcef3d468b95b0da47e2f1555a682c8d0de28 *electron-v32.2.6-linux-armv7l-debug.zip +c85d5ca3f38dc4140040bcde6a37ac9c7510bb542f12e1ffce695a35f68e3c13 *electron-v32.2.6-linux-armv7l-symbols.zip +df4b490a9c501d83c5305f20b2a9d1aa100d2e878e59ebafde477f21d35e3300 *electron-v32.2.6-linux-armv7l.zip +a5aa67da85ee318ff0770d55a506f62e6e5a10e967dfab272a94bcd91922e075 *electron-v32.2.6-linux-x64-debug.zip +671eb342a58e056f0dee5a6e9c69a6a96ee2141f81d306fa1a0e2635e22aa7c0 *electron-v32.2.6-linux-x64-symbols.zip +a3231409db7f8ac2cc446708f17e2abac0f8549c166eaab2f427e8d0f864208d *electron-v32.2.6-linux-x64.zip +8b8d0aeadcf21633216a9cce87d323ad6aa21e38ec82092cd5f65bf171be025f *electron-v32.2.6-mas-arm64-dsym-snapshot.zip +298931236955b83d174738d3325931e9672a8333bf854fc5f471168b0f7e70be *electron-v32.2.6-mas-arm64-dsym.zip +53e4c666a6f5f87aa150b1c2f34532e3711e00b0237fb103dcbef64d65979429 *electron-v32.2.6-mas-arm64-symbols.zip +bedbc78acc3bc6cb30e5fe1f133562104152022273ec21a83cd32a0eece9003f *electron-v32.2.6-mas-arm64.zip +9ba3def756c90460867d968af5417996991bf3b4b306dba4c9fbde43de2f771d *electron-v32.2.6-mas-x64-dsym-snapshot.zip +e4a3f9392934bb4ef82a214fec2ce1f319ea409b89bf03b2a2a4ab7a55688d0c *electron-v32.2.6-mas-x64-dsym.zip +55c54fd01faf5767493183001a440b837b63f8b8d64c36f7b42fa7217af36dcd *electron-v32.2.6-mas-x64-symbols.zip +1efe974cd426a288d617750c864e6edbf28495c3b851a5bc806af19cda7a274d *electron-v32.2.6-mas-x64.zip +88c50d34dc48a55a11014349d2d278f895f1615405614dbfcf27dff5f5030cf1 *electron-v32.2.6-win32-arm64-pdb.zip +b0b2211bf0f11924bcd693b6783627c7f6c9a066117bcf05c10766064c79794c *electron-v32.2.6-win32-arm64-symbols.zip +48b81d28fdceb4ab3ca27650d79bab910a1a19dbda72271882bfdc877c71975f *electron-v32.2.6-win32-arm64-toolchain-profile.zip +2b7962348f23410863cb6562d79654ce534666bab9f75965b5c8ebee61f49657 *electron-v32.2.6-win32-arm64.zip +d248ab4ec8b4a5aec414c7a404e0efd9b9a73083f7c5cb6c657c2ed58c4cbe94 *electron-v32.2.6-win32-ia32-pdb.zip +2ef98197d66d94aee4978047f22ba07538d259b25a8f5f301d9564a13649e72c *electron-v32.2.6-win32-ia32-symbols.zip +48b81d28fdceb4ab3ca27650d79bab910a1a19dbda72271882bfdc877c71975f *electron-v32.2.6-win32-ia32-toolchain-profile.zip +e85dbf85d58cab5b06cdb8e76fde3a25306e7c1808f5bb30925ba7e29ff14d13 *electron-v32.2.6-win32-ia32.zip +9d76b0c0d475cc062b2a951fbfb3b17837880102fb6cc042e2736dfebbfa0e5d *electron-v32.2.6-win32-x64-pdb.zip +3d7b93bafc633429f5c9f820bcb4843d504b12e454b3ecebb1b69c15b5f4080f *electron-v32.2.6-win32-x64-symbols.zip +48b81d28fdceb4ab3ca27650d79bab910a1a19dbda72271882bfdc877c71975f *electron-v32.2.6-win32-x64-toolchain-profile.zip +77d5e5b76b49767e6a3ad292dc315fbc7cdccd557ac38da9093b8ac6da9262d5 *electron-v32.2.6-win32-x64.zip +a52935712eb4fc2c12ac4ae611a57e121da3b6165c2de1abd7392ed4261287e2 *electron.d.ts +6345ea55fda07544434c90c276cdceb2662044b9e0355894db67ca95869af22a *ffmpeg-v32.2.6-darwin-arm64.zip +4c1347e8653727513a22be013008c2760d19200977295b98506b3b9947e74090 *ffmpeg-v32.2.6-darwin-x64.zip +3f1eafaf4cd90ab43ba0267429189be182435849a166a2cbe1faefc0d07217c4 *ffmpeg-v32.2.6-linux-arm64.zip +3db919bc57e1a5bf7c1bae1d7aeacf4a331990ea82750391c0b24a046d9a2812 *ffmpeg-v32.2.6-linux-armv7l.zip +fe7d779dddbfb5da5999a7607fc5e3c7a6ab7c65e8da9fee1384918865231612 *ffmpeg-v32.2.6-linux-x64.zip +e09ae881113d1b3103aec918e7c95c36f82b2db63657320c380c94386f689138 *ffmpeg-v32.2.6-mas-arm64.zip +ee316e435662201a81fcededc62582dc87a0bd5c9fd0f6a8a55235eca806652f *ffmpeg-v32.2.6-mas-x64.zip +415395968d31e13056cefcb589ed550a0e80d7c3d0851ee3ba29e4dcdf174210 *ffmpeg-v32.2.6-win32-arm64.zip +17f61a5293b707c984cee52b57a7e505cde994d22828e31c016434521638e419 *ffmpeg-v32.2.6-win32-ia32.zip +f9b47951a553eec21636b3cc15eccf0a2ba272567146ec8a6e2eeb91a985fd62 *ffmpeg-v32.2.6-win32-x64.zip +7d2b596bd94e4d5c7befba11662dc563a02f18c183da12ebd56f38bb6f4382e9 *hunspell_dictionaries.zip +06bca9a33142b5834fbca6d10d7f3303b0b5c52e7222fe783db109cd4c5260ed *libcxx-objects-v32.2.6-linux-arm64.zip +7ab8ff5a4e1d3a6639978ed718d2732df9c1a4dd4dcd3e18f6746a2168d353a9 *libcxx-objects-v32.2.6-linux-armv7l.zip +ba96792896751e11fdba63e5e336e323979986176aa1848122ca3757c854352e *libcxx-objects-v32.2.6-linux-x64.zip +1f858d484f4ce27f9f3c4a120b2881f88c17c81129ca10e495b50398fb2eed64 *libcxx_headers.zip +4566afb06a6dd8bd895dba5350a5705868203321116a1ae0a216d5a4a6bfb289 *libcxxabi_headers.zip +350f5419c14aede5802c4f0ef5204ddbbe0eb7d5263524da38d19f43620d8530 *mksnapshot-v32.2.6-darwin-arm64.zip +9f4e4943df4502943994ffa17525b7b5b9a1d889dbc5aeb28bfc40f9146323ec *mksnapshot-v32.2.6-darwin-x64.zip +6295ad1a4ab3b24ac99ec85d35ebfce3861e58185b94d20077e364e81ad935f8 *mksnapshot-v32.2.6-linux-arm64-x64.zip +ed9e1931165a2ff85c1af9f10b3bf8ba05d2dae31331d1d4f5ff1512078e4411 *mksnapshot-v32.2.6-linux-armv7l-x64.zip +6680c63b11e4638708d88c130474ceb2ee92fc58c62cfcd3bf33dda9fee771c2 *mksnapshot-v32.2.6-linux-x64.zip +5a4c45b755b7bbdcad51345f5eb2935ba988987650f9b8540c7ef04015207a2f *mksnapshot-v32.2.6-mas-arm64.zip +1e6243d6a1b68f327457b9dae244ffaeadc265b07a99d9c36f1abcff31e36856 *mksnapshot-v32.2.6-mas-x64.zip +407099537b17860ce7dcea6ba582a854314c29dc152a6df0abcc77ebb0187b4c *mksnapshot-v32.2.6-win32-arm64-x64.zip +f9107536378e19ae9305386dacf6fae924c7ddaad0cf0a6f49694e1e8af6ded5 *mksnapshot-v32.2.6-win32-ia32.zip +82a142db76a2cc5dfb9a89e4cd721cfebc0f3077d2415d8f3d86bb7411f0fe27 *mksnapshot-v32.2.6-win32-x64.zip diff --git a/build/checksums/nodejs.txt b/build/checksums/nodejs.txt index 632cc7155e054..9e53ad9083232 100644 --- a/build/checksums/nodejs.txt +++ b/build/checksums/nodejs.txt @@ -1,7 +1,7 @@ -92e180624259d082562592bb12548037c6a417069be29e452ec5d158d657b4be node-v20.18.0-darwin-arm64.tar.gz -c02aa7560612a4e2cc359fd89fae7aedde370c06db621f2040a4a9f830a125dc node-v20.18.0-darwin-x64.tar.gz -38bccb35c06ee4edbcd00c77976e3fad1d69d2e57c3c0c363d1700a2a2493278 node-v20.18.0-linux-arm64.tar.gz -9a522daa837d4d32dc700bf9b18dea9e21a229b113a22cfcf38f1f2240bbbc47 node-v20.18.0-linux-armv7l.tar.gz -24a5d58a1d4c2903478f4b7c3cfd2eeb5cea2cae3baee11a4dc6a1fed25fec6c node-v20.18.0-linux-x64.tar.gz -e66327f3d1de938059bedda660de2eff1a508b61d777ff247615a019eb153d46 win-arm64/node.exe -35b7c95a379beb606f5798ed83081690df13190077630b234163c6607aa4cc94 win-x64/node.exe +9e92ce1032455a9cc419fe71e908b27ae477799371b45a0844eedb02279922a4 node-v20.18.1-darwin-arm64.tar.gz +c5497dd17c8875b53712edaf99052f961013cedc203964583fc0cfc0aaf93581 node-v20.18.1-darwin-x64.tar.gz +73cd297378572e0bc9dfc187c5ec8cca8d43aee6a596c10ebea1ed5f9ec682b6 node-v20.18.1-linux-arm64.tar.gz +7b7c3315818e9fe57512737c2380fada14d8717ce88945fb6f7b8baadd3cfb92 node-v20.18.1-linux-armv7l.tar.gz +259e5a8bf2e15ecece65bd2a47153262eda71c0b2c9700d5e703ce4951572784 node-v20.18.1-linux-x64.tar.gz +9a52905b5d22b08b5b34e86b8d5358cd22c03fbd0fcb9dbb37c9bd82a8f18c17 win-arm64/node.exe +06c1dec1b428927d6ff01c8f5882f119ec13b61ac77483760aa7fba215c72cf5 win-x64/node.exe diff --git a/cgmanifest.json b/cgmanifest.json index 63e0e74d1f814..832a3f604b782 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -516,11 +516,11 @@ "git": { "name": "nodejs", "repositoryUrl": "https://github.com/nodejs/node", - "commitHash": "7eebd17fa2c1e48e4534f3a69560388fab2f2c07" + "commitHash": "70178110a8e52d28dc957b6b20da94e455922025" } }, "isOnlyProductionDependency": true, - "version": "20.18.0" + "version": "20.18.1" }, { "component": { @@ -528,12 +528,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "a6a0c4cb6d815bbc9503620c7641d57e14b03868" + "commitHash": "10e0ce069260b2cc984c301d5a7ecb3492f0c2f0" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "32.2.5" + "version": "32.2.6" }, { "component": { diff --git a/extensions/git/package.json b/extensions/git/package.json index 1851ef8703886..103caae96f7bf 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -453,6 +453,12 @@ "category": "Git", "enablement": "!operationInProgress" }, + { + "command": "git.checkoutRef", + "title": "%command.checkoutRef%", + "category": "Git", + "enablement": "!operationInProgress" + }, { "command": "git.checkoutRefDetached", "title": "%command.checkoutRefDetached%", @@ -1470,6 +1476,10 @@ "command": "git.copyCommitMessage", "when": "false" }, + { + "command": "git.checkoutRef", + "when": "false" + }, { "command": "git.checkoutRefDetached", "when": "false" @@ -2028,6 +2038,7 @@ "group": "9_copy@2" } ], + "scm/historyItemRef/context": [], "editor/title": [ { "command": "git.openFile", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 1f6775a2da58a..d706b650c8a0e 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -62,6 +62,7 @@ "command.undoCommit": "Undo Last Commit", "command.checkout": "Checkout to...", "command.checkoutDetached": "Checkout to (Detached)...", + "command.checkoutRef": "Checkout", "command.checkoutRefDetached": "Checkout (Detached)", "command.branch": "Create Branch...", "command.branchFrom": "Create Branch From...", diff --git a/extensions/git/src/blame.ts b/extensions/git/src/blame.ts index 9c6bc5ae76193..fbc5aaa417bc7 100644 --- a/extensions/git/src/blame.ts +++ b/extensions/git/src/blame.ts @@ -160,6 +160,7 @@ export class GitBlameController { this._model.onDidOpenRepository(this._onDidOpenRepository, this, this._disposables); this._model.onDidCloseRepository(this._onDidCloseRepository, this, this._disposables); + window.onDidChangeActiveTextEditor(e => this._updateTextEditorBlameInformation(e), this, this._disposables); window.onDidChangeTextEditorSelection(e => this._updateTextEditorBlameInformation(e.textEditor), this, this._disposables); window.onDidChangeTextEditorDiffInformation(e => this._updateTextEditorBlameInformation(e.textEditor), this, this._disposables); diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index cc85c83728aa1..5266955198fe2 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -5,7 +5,7 @@ import * as os from 'os'; import * as path from 'path'; -import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge, QuickPickItemKind, TextDocument, LogOutputChannel, l10n, Memento, UIKind, QuickInputButton, ThemeIcon, SourceControlHistoryItem, SourceControl, InputBoxValidationMessage, Tab, TabInputNotebook, QuickInputButtonLocation, SourceControlHistoryItemRef } from 'vscode'; +import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge, QuickPickItemKind, TextDocument, LogOutputChannel, l10n, Memento, UIKind, QuickInputButton, ThemeIcon, SourceControlHistoryItem, SourceControl, InputBoxValidationMessage, Tab, TabInputNotebook, QuickInputButtonLocation } from 'vscode'; import TelemetryReporter from '@vscode/extension-telemetry'; import { uniqueNamesGenerator, adjectives, animals, colors, NumberDictionary } from '@joaomoreno/unique-names-generator'; import { ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourcePublisher, Remote } from './api/git'; @@ -2505,8 +2505,18 @@ export class CommandCenter { return this._checkout(repository, { detached: true, treeish }); } + @command('git.checkoutRef', { repository: true }) + async checkoutRef(repository: Repository, historyItem?: SourceControlHistoryItem, historyItemRefId?: string): Promise { + const historyItemRef = historyItem?.references?.find(r => r.id === historyItemRefId); + if (!historyItemRef) { + return false; + } + + return this._checkout(repository, { treeish: historyItemRefId }); + } + @command('git.checkoutRefDetached', { repository: true }) - async checkoutRefDetached(repository: Repository, historyItem?: SourceControlHistoryItemRef): Promise { + async checkoutRefDetached(repository: Repository, historyItem?: SourceControlHistoryItem): Promise { if (!historyItem) { return false; } diff --git a/extensions/terminal-suggest/src/completions/cd.ts b/extensions/terminal-suggest/src/completions/cd.ts index 89fc633911b27..0eb7aaba25b19 100644 --- a/extensions/terminal-suggest/src/completions/cd.ts +++ b/extensions/terminal-suggest/src/completions/cd.ts @@ -9,7 +9,6 @@ const cdSpec: Fig.Spec = { args: { name: 'folder', template: 'folders', - isVariadic: true, suggestions: [ { diff --git a/extensions/terminal-suggest/src/terminalSuggestMain.ts b/extensions/terminal-suggest/src/terminalSuggestMain.ts index d9483f728cd06..89ffde7496a70 100644 --- a/extensions/terminal-suggest/src/terminalSuggestMain.ts +++ b/extensions/terminal-suggest/src/terminalSuggestMain.ts @@ -288,7 +288,7 @@ export function getCompletionItemsFromSpecs(specs: Fig.Spec[], terminalContext: } } - if (!specificSuggestionsProvided) { + if (!specificSuggestionsProvided && (filesRequested === foldersRequested)) { // Include builitin/available commands in the results for (const command of availableCommands) { if ((!terminalContext.commandLine.trim() || !!prefix) && command.startsWith(prefix) && !items.find(item => item.label === command)) { diff --git a/package-lock.json b/package-lock.json index f1ee69e00fa77..67d913bcb2815 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "cssnano": "^6.0.3", "debounce": "^1.0.0", "deemon": "^1.8.0", - "electron": "32.2.5", + "electron": "32.2.6", "eslint": "^9.11.1", "eslint-formatter-compact": "^8.40.0", "eslint-plugin-header": "3.1.1", @@ -5815,9 +5815,9 @@ "dev": true }, "node_modules/electron": { - "version": "32.2.5", - "resolved": "https://registry.npmjs.org/electron/-/electron-32.2.5.tgz", - "integrity": "sha512-8t5IGOvms/JTcLNnlOH7rFCAJIZJAazwYrF7kQsKQSLzDHh4z8mGFrU11NN3W4bIT6Yg5DJNniSWz3O5wJLmCw==", + "version": "32.2.6", + "resolved": "https://registry.npmjs.org/electron/-/electron-32.2.6.tgz", + "integrity": "sha512-aGG1MLvWCf+ECUFBCmaCF52F8312OPAJfph2D0FSsFmlbfnJuNevZCbty2lFzsiIMtU7/QRo6d0ksbgR4s7y3w==", "dev": true, "hasInstallScript": true, "license": "MIT", diff --git a/package.json b/package.json index 64f0e91044e4a..841d2a58c1c1e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.96.0", - "distro": "9f7044d3679195e9328d2e34fb2d8e833127239b", + "distro": "40103071553e7c3bf5cecea4ec8a0ad14509c451", "author": { "name": "Microsoft Corporation" }, @@ -154,7 +154,7 @@ "cssnano": "^6.0.3", "debounce": "^1.0.0", "deemon": "^1.8.0", - "electron": "32.2.5", + "electron": "32.2.6", "eslint": "^9.11.1", "eslint-formatter-compact": "^8.40.0", "eslint-plugin-header": "3.1.1", diff --git a/remote/.npmrc b/remote/.npmrc index 929e26e4c4b73..b74c59d2b8f3d 100644 --- a/remote/.npmrc +++ b/remote/.npmrc @@ -1,6 +1,6 @@ disturl="https://nodejs.org/dist" -target="20.18.0" -ms_build_id="300025" +target="20.18.1" +ms_build_id="307485" runtime="node" build_from_source="true" legacy-peer-deps="true" diff --git a/scripts/test-integration.bat b/scripts/test-integration.bat index 5c832677ca6e9..b59cceada070d 100644 --- a/scripts/test-integration.bat +++ b/scripts/test-integration.bat @@ -52,6 +52,11 @@ echo ### Colorize tests call npm run test-extension -- -l vscode-colorize-tests if %errorlevel% neq 0 exit /b %errorlevel% +echo. +echo ### Terminal Suggest tests +call npm run test-extension -- -l terminal-suggest --enable-proposed-api=vscode.vscode-api-tests +if %errorlevel% neq 0 exit /b %errorlevel% + echo. echo ### TypeScript tests call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\typescript-language-features\test-workspace --extensionDevelopmentPath=%~dp0\..\extensions\typescript-language-features --extensionTestsPath=%~dp0\..\extensions\typescript-language-features\out\test\unit %API_TESTS_EXTRA_ARGS% diff --git a/src/vs/base/browser/fastDomNode.ts b/src/vs/base/browser/fastDomNode.ts index 1ef17e48cd5d4..9d58aaba9c3df 100644 --- a/src/vs/base/browser/fastDomNode.ts +++ b/src/vs/base/browser/fastDomNode.ts @@ -39,6 +39,10 @@ export class FastDomNode { public readonly domNode: T ) { } + public focus(): void { + this.domNode.focus(); + } + public setMaxWidth(_maxWidth: number | string): void { const maxWidth = numberAsPixels(_maxWidth); if (this._maxWidth === maxWidth) { diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index be65784fd80b4..64efdcaabea15 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -1177,7 +1177,7 @@ export class FindController extends AbstractFindController !FuzzyScore.isDefault(node.filterData as any as FuzzyScore)); + this.tree.focusNext(0, true, undefined, (node) => this.shouldAllowFocus(node)); } const focus = this.tree.getFocus(); diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 418c47a4754d6..9d0d2cbf4b25f 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -227,8 +227,10 @@ export interface IAsyncFindToggles { findMode: TreeFindMode; } -export interface IAsyncFindResultMetadata { +export interface IAsyncFindResult { warningMessage?: string; + matchCount: number; + isMatch(element: T): boolean; } export interface IAsyncFindProvider { @@ -241,7 +243,7 @@ export interface IAsyncFindProvider { /** * `find` is called when the user types one or more character into the find input. */ - find(pattern: string, toggles: IAsyncFindToggles, token: CancellationToken): Promise; + find(pattern: string, toggles: IAsyncFindToggles, token: CancellationToken): Promise | undefined>; /** * `isVisible` is called to check if an element should be visible. @@ -285,8 +287,10 @@ class AsyncFindFilter extends FindFilter { } +// TODO Fix types class AsyncFindController extends FindController { private activeTokenSource: CancellationTokenSource | undefined; + private activeFindMetadata: IAsyncFindResult | undefined; private activeSession = false; private asyncWorkInProgress = false; private taskQueue = new ThrottledDelayer(250); @@ -342,13 +346,15 @@ class AsyncFindController extends FindController extends FindController 0; + this.renderMessage(showNotFound); + + if (this.pattern.length) { + this.alertResults(this.activeFindMetadata.matchCount); } } @@ -385,6 +398,23 @@ class AsyncFindController extends FindController): boolean { + return this.shouldFocusWhenNavigating(node as ITreeNode | null, TFilterData>); + } + + shouldFocusWhenNavigating(node: ITreeNode | null, TFilterData>): boolean { + if (!this.activeSession || !this.activeFindMetadata) { + return true; + } + + const element = node.element?.element as T | undefined; + if (element && this.activeFindMetadata.isMatch(element)) { + return true; + } + + return !FuzzyScore.isDefault(node.filterData as any as FuzzyScore); + } } function asObjectTreeOptions(options?: IAsyncDataTreeOptions): IObjectTreeOptions, TFilterData> | undefined { @@ -534,6 +564,8 @@ export class AsyncDataTree implements IDisposable get onDidUpdateOptions(): Event { return this.tree.onDidUpdateOptions; } + private focusNavigationFilter: ((node: ITreeNode | null, TFilterData>) => boolean) | undefined; + readonly onDidChangeFindOpenState: Event; get onDidChangeStickyScrollFocused(): Event { return this.tree.onDidChangeStickyScrollFocused; } @@ -600,6 +632,7 @@ export class AsyncDataTree implements IDisposable const findOptions = { styles: options.findWidgetStyles, showNotFoundMessage: options.showNotFoundMessage }; this.findController = this.disposables.add(new AsyncFindController(this.tree, options.findProvider!, findFilter!, this.tree.options.contextViewProvider!, findOptions)); + this.focusNavigationFilter = node => this.findController!.shouldFocusWhenNavigating(node); this.onDidChangeFindOpenState = this.findController!.onDidChangeOpenState; this.onDidChangeFindMode = this.findController!.onDidChangeMode; this.onDidChangeFindMatchType = this.findController!.onDidChangeMatchType; @@ -935,27 +968,27 @@ export class AsyncDataTree implements IDisposable } focusNext(n = 1, loop = false, browserEvent?: UIEvent): void { - this.tree.focusNext(n, loop, browserEvent); + this.tree.focusNext(n, loop, browserEvent, this.focusNavigationFilter); } focusPrevious(n = 1, loop = false, browserEvent?: UIEvent): void { - this.tree.focusPrevious(n, loop, browserEvent); + this.tree.focusPrevious(n, loop, browserEvent, this.focusNavigationFilter); } focusNextPage(browserEvent?: UIEvent): Promise { - return this.tree.focusNextPage(browserEvent); + return this.tree.focusNextPage(browserEvent, this.focusNavigationFilter); } focusPreviousPage(browserEvent?: UIEvent): Promise { - return this.tree.focusPreviousPage(browserEvent); + return this.tree.focusPreviousPage(browserEvent, this.focusNavigationFilter); } focusLast(browserEvent?: UIEvent): void { - this.tree.focusLast(browserEvent); + this.tree.focusLast(browserEvent, this.focusNavigationFilter); } focusFirst(browserEvent?: UIEvent): void { - this.tree.focusFirst(browserEvent); + this.tree.focusFirst(browserEvent, this.focusNavigationFilter); } getFocus(): T[] { diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index 01eaed143e9ec..cc1452c9c5e0d 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -313,6 +313,8 @@ export interface IDefaultChatAgent { readonly documentationUrl: string; readonly privacyStatementUrl: string; readonly skusDocumentationUrl: string; + readonly publicCodeMatchesUrl: string; + readonly managePlanUrl: string; readonly providerId: string; readonly providerName: string; readonly providerScopes: string[][]; diff --git a/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts b/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts index cab5f079c99b0..896794fc929b4 100644 --- a/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts +++ b/src/vs/editor/browser/controller/editContext/native/nativeEditContext.ts @@ -75,8 +75,6 @@ export class NativeEditContext extends AbstractEditContext { this.textArea = new FastDomNode(document.createElement('textarea')); this.textArea.setClassName('native-edit-context-textarea'); - this._register(NativeEditContextRegistry.registerTextArea(ownerID, this.textArea.domNode)); - this._updateDomAttributes(); overflowGuardContainer.appendChild(this.domNode); @@ -160,6 +158,7 @@ export class NativeEditContext extends AbstractEditContext { } viewController.paste(text, pasteOnNewLine, multicursorText, mode); })); + this._register(NativeEditContextRegistry.register(ownerID, this)); } // --- Public methods --- @@ -204,6 +203,10 @@ export class NativeEditContext extends AbstractEditContext { return true; } + public onWillPaste(): void { + this._screenReaderSupport.setIgnoreSelectionChangeTime(); + } + public writeScreenReaderContent(): void { this._screenReaderSupport.writeScreenReaderContent(); } @@ -455,6 +458,9 @@ export class NativeEditContext extends AbstractEditContext { // When using a Braille display or NVDA for example, it is possible for users to reposition the // system caret. This is reflected in Chrome as a `selectionchange` event and needs to be reflected within the editor. + // `selectionchange` events often come multiple times for a single logical change + // so throttle multiple `selectionchange` events that burst in a short period of time. + let previousSelectionChangeEventTime = 0; return addDisposableListener(this.domNode.domNode.ownerDocument, 'selectionchange', () => { const isScreenReaderOptimized = this._accessibilityService.isScreenReaderOptimized(); if (!this.isFocused() || !isScreenReaderOptimized) { @@ -464,6 +470,21 @@ export class NativeEditContext extends AbstractEditContext { if (!screenReaderContentState) { return; } + const now = Date.now(); + const delta1 = now - previousSelectionChangeEventTime; + previousSelectionChangeEventTime = now; + if (delta1 < 5) { + // received another `selectionchange` event within 5ms of the previous `selectionchange` event + // => ignore it + return; + } + const delta2 = now - this._screenReaderSupport.getIgnoreSelectionChangeTime(); + this._screenReaderSupport.resetSelectionChangeTime(); + if (delta2 < 100) { + // received a `selectionchange` event within 100ms since we touched the textarea + // => ignore it, since we caused it + return; + } const activeDocument = getActiveWindow().document; const activeDocumentSelection = activeDocument.getSelection(); if (!activeDocumentSelection) { @@ -474,11 +495,14 @@ export class NativeEditContext extends AbstractEditContext { return; } const range = activeDocumentSelection.getRangeAt(0); - const model = this._context.viewModel.model; - const offsetOfStartOfScreenReaderContent = model.getOffsetAt(screenReaderContentState.startPositionWithinEditor); + const viewModel = this._context.viewModel; + const model = viewModel.model; + const coordinatesConverter = viewModel.coordinatesConverter; + const modelScreenReaderContentStartPositionWithinEditor = coordinatesConverter.convertViewPositionToModelPosition(screenReaderContentState.startPositionWithinEditor); + const offsetOfStartOfScreenReaderContent = model.getOffsetAt(modelScreenReaderContentStartPositionWithinEditor); let offsetOfSelectionStart = range.startOffset + offsetOfStartOfScreenReaderContent; let offsetOfSelectionEnd = range.endOffset + offsetOfStartOfScreenReaderContent; - const modelUsesCRLF = this._context.viewModel.model.getEndOfLineSequence() === EndOfLineSequence.CRLF; + const modelUsesCRLF = model.getEndOfLineSequence() === EndOfLineSequence.CRLF; if (modelUsesCRLF) { const screenReaderContentText = screenReaderContentState.value; const offsetTransformer = new PositionOffsetTransformer(screenReaderContentText); diff --git a/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts b/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts index 763c2099fc13c..eda3528812505 100644 --- a/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts +++ b/src/vs/editor/browser/controller/editContext/native/nativeEditContextRegistry.ts @@ -4,22 +4,23 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable } from '../../../../../base/common/lifecycle.js'; +import { NativeEditContext } from './nativeEditContext.js'; class NativeEditContextRegistryImpl { - private _textAreaMapping: Map = new Map(); + private _nativeEditContextMapping: Map = new Map(); - registerTextArea(ownerID: string, textArea: HTMLTextAreaElement): IDisposable { - this._textAreaMapping.set(ownerID, textArea); + register(ownerID: string, nativeEditContext: NativeEditContext): IDisposable { + this._nativeEditContextMapping.set(ownerID, nativeEditContext); return { dispose: () => { - this._textAreaMapping.delete(ownerID); + this._nativeEditContextMapping.delete(ownerID); } }; } - getTextArea(ownerID: string): HTMLTextAreaElement | undefined { - return this._textAreaMapping.get(ownerID); + get(ownerID: string): NativeEditContext | undefined { + return this._nativeEditContextMapping.get(ownerID); } } diff --git a/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts b/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts index a668f4e91c6ae..1bec4ec372b85 100644 --- a/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts +++ b/src/vs/editor/browser/controller/editContext/native/screenReaderSupport.ts @@ -29,6 +29,7 @@ export class ScreenReaderSupport { private _lineHeight: number = 1; private _fontInfo: FontInfo | undefined; private _accessibilityPageSize: number = 1; + private _ignoreSelectionChangeTime: number = 0; private _primarySelection: Selection = new Selection(1, 1, 1, 1); private _screenReaderContentState: ScreenReaderContentState | undefined; @@ -43,6 +44,18 @@ export class ScreenReaderSupport { this._updateDomAttributes(); } + public setIgnoreSelectionChangeTime(): void { + this._ignoreSelectionChangeTime = Date.now(); + } + + public getIgnoreSelectionChangeTime(): number { + return this._ignoreSelectionChangeTime; + } + + public resetSelectionChangeTime(): void { + this._ignoreSelectionChangeTime = 0; + } + public onConfigurationChanged(e: ViewConfigurationChangedEvent): void { this._updateConfigurationSettings(); this._updateDomAttributes(); @@ -129,6 +142,7 @@ export class ScreenReaderSupport { return; } if (this._domNode.domNode.textContent !== this._screenReaderContentState.value) { + this.setIgnoreSelectionChangeTime(); this._domNode.domNode.textContent = this._screenReaderContentState.value; } this._setSelectionOfScreenReaderContent(this._screenReaderContentState.selectionStart, this._screenReaderContentState.selectionEnd); @@ -175,6 +189,7 @@ export class ScreenReaderSupport { const range = new globalThis.Range(); range.setStart(textContent, selectionOffsetStart); range.setEnd(textContent, selectionOffsetEnd); + this.setIgnoreSelectionChangeTime(); activeDocumentSelection.removeAllRanges(); activeDocumentSelection.addRange(range); } diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 17e0805cbdb5f..51fee410a6baa 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -4170,6 +4170,7 @@ export interface IInlineSuggestOptions { enabled?: boolean; useMixedLinesDiff?: 'never' | 'whenPossible' | 'afterJumpWhenPossible'; useInterleavedLinesDiff?: 'never' | 'always' | 'afterJump'; + onlyShowWhenCloseToCursor?: boolean; }; }; } @@ -4201,6 +4202,7 @@ class InlineEditorSuggest extends BaseEditorOption