From 18f1aea54c10efcc6ae7ab65bb6b7b74da10142b Mon Sep 17 00:00:00 2001 From: jeanp413 Date: Mon, 4 Nov 2019 20:58:19 -0500 Subject: [PATCH 01/60] Fixes #83264 --- src/vs/workbench/contrib/debug/browser/linkDetector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/linkDetector.ts b/src/vs/workbench/contrib/debug/browser/linkDetector.ts index baca730b769b..0d1152234200 100644 --- a/src/vs/workbench/contrib/debug/browser/linkDetector.ts +++ b/src/vs/workbench/contrib/debug/browser/linkDetector.ts @@ -142,7 +142,7 @@ export class LinkDetector { private decorateLink(link: HTMLElement, onclick: () => void) { link.classList.add('link'); link.title = platform.isMacintosh ? nls.localize('fileLinkMac', "Cmd + click to follow link") : nls.localize('fileLink', "Ctrl + click to follow link"); - link.onmousemove = (event) => link.classList.toggle('pointer', platform.isMacintosh ? event.metaKey : event.ctrlKey); + link.onmousemove = (event) => { link.classList.toggle('pointer', platform.isMacintosh ? event.metaKey : event.ctrlKey); }; link.onmouseleave = () => link.classList.remove('pointer'); link.onclick = (event) => { const selection = window.getSelection(); From 0d728c31ebdf03869d2687d9be0b017667c9ff37 Mon Sep 17 00:00:00 2001 From: Jackson Kearl Date: Mon, 11 Nov 2019 17:04:44 -0800 Subject: [PATCH 02/60] Remove backreferences warning (#84092) * Fallback to PCRE2 when backreferences are detected And remove warning that we don't support them. * Remove explicit fallback... ripgrep will do it implicitly * Remove unused --- src/vs/workbench/contrib/search/browser/searchWidget.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/searchWidget.ts b/src/vs/workbench/contrib/search/browser/searchWidget.ts index 0652167a7a48..d3c846bd0dd7 100644 --- a/src/vs/workbench/contrib/search/browser/searchWidget.ts +++ b/src/vs/workbench/contrib/search/browser/searchWidget.ts @@ -15,7 +15,6 @@ import { Action } from 'vs/base/common/actions'; import { Delayer } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; -import * as strings from 'vs/base/common/strings'; import { CONTEXT_FIND_WIDGET_NOT_VISIBLE } from 'vs/editor/contrib/find/findModel'; import * as nls from 'vs/nls'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -443,12 +442,6 @@ export class SearchWidget extends Widget { return { content: e.message }; } - if (strings.regExpContainsBackreference(value)) { - if (!this.searchConfiguration.usePCRE2) { - return { content: nls.localize('regexp.backreferenceValidationFailure', "Backreferences are not supported") }; - } - } - return null; } From 68fbaf42c873435a1246fb408dce0d02c1f37f96 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 08:00:16 +0100 Subject: [PATCH 03/60] debt - adopt windows-foreground-love types --- package.json | 1 + src/typings/windows-foreground-love.d.ts | 10 ---------- yarn.lock | 5 +++++ 3 files changed, 6 insertions(+), 10 deletions(-) delete mode 100644 src/typings/windows-foreground-love.d.ts diff --git a/package.json b/package.json index d4bf37ca9ae2..51c1dc12a7a1 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@types/semver": "^5.5.0", "@types/sinon": "^1.16.36", "@types/webpack": "^4.4.10", + "@types/windows-foreground-love": "^0.3.0", "@types/winreg": "^1.2.30", "@types/yauzl": "^2.9.1", "@types/yazl": "^2.4.2", diff --git a/src/typings/windows-foreground-love.d.ts b/src/typings/windows-foreground-love.d.ts deleted file mode 100644 index f7d20f13aef8..000000000000 --- a/src/typings/windows-foreground-love.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'windows-foreground-love' { - - export function allowSetForegroundWindow(pid?: number): boolean; - -} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 5e44523b3f78..3f00734e764d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -204,6 +204,11 @@ "@types/uglify-js" "*" source-map "^0.6.0" +"@types/windows-foreground-love@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/windows-foreground-love/-/windows-foreground-love-0.3.0.tgz#26bc230b2568aa7ab7c56d35bb5653c0a6965a42" + integrity sha512-tFUVA/fiofNqOh6lZlymvQiQYPY+cZXZPR9mn9wN6/KS8uwx0zgH4Ij/jmFyRYr+x+DGZWEIeknS2BMi7FZJAQ== + "@types/winreg@^1.2.30": version "1.2.30" resolved "https://registry.yarnpkg.com/@types/winreg/-/winreg-1.2.30.tgz#91d6710e536d345b9c9b017c574cf6a8da64c518" From 382c7f5e9b6db1409212651b897668452bf7e6dd Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 12 Nov 2019 08:04:33 +0100 Subject: [PATCH 04/60] :lipstick: --- src/vs/base/browser/ui/list/listWidget.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 48a5214a0d23..65ff0de7f6e4 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -1198,7 +1198,11 @@ export class List implements ISpliceable, IDisposable { this.view = new ListView(container, virtualDelegate, renderers, viewOptions); - this.updateAriaRole(); + if (typeof _options.ariaRole !== 'string') { + this.view.domNode.setAttribute('role', ListAriaRootRole.TREE); + } else { + this.view.domNode.setAttribute('role', _options.ariaRole); + } this.styleElement = DOM.createStyleSheet(this.view.domNode); @@ -1610,19 +1614,9 @@ export class List implements ISpliceable, IDisposable { this.view.domNode.removeAttribute('aria-activedescendant'); } - this.updateAriaRole(); - DOM.toggleClass(this.view.domNode, 'element-focused', focus.length > 0); } - private updateAriaRole(): void { - if (typeof this.options.ariaRole !== 'string') { - this.view.domNode.setAttribute('role', ListAriaRootRole.TREE); - } else { - this.view.domNode.setAttribute('role', this.options.ariaRole); - } - } - private _onSelectionChange(): void { const selection = this.selection.get(); From 9b620f43def06692d006f63af991c59fb40bb459 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 08:08:32 +0100 Subject: [PATCH 05/60] Enable `strictPropertyInitialization` (fix #78168) --- src/tsconfig.base.json | 1 + src/vs/base/browser/ui/tree/asyncDataTree.ts | 2 +- src/vs/workbench/api/common/extHostTypes.ts | 4 ++-- src/vs/workbench/browser/parts/views/viewsViewlet.ts | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/tsconfig.base.json b/src/tsconfig.base.json index 907c210b5303..44595cf5246d 100644 --- a/src/tsconfig.base.json +++ b/src/tsconfig.base.json @@ -10,6 +10,7 @@ "alwaysStrict": true, "strictBindCallApply": true, "strictNullChecks": true, + "strictPropertyInitialization": true, "forceConsistentCasingInFileNames": true, "baseUrl": ".", "paths": { diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 50ab5ce9be3c..49cf32517511 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -1031,7 +1031,7 @@ export interface ICompressibleAsyncDataTreeOptionsUpdate extends IAsyncDataTreeO export class CompressibleAsyncDataTree extends AsyncDataTree { - protected readonly tree: CompressibleObjectTree, TFilterData>; + protected readonly tree!: CompressibleObjectTree, TFilterData>; protected readonly compressibleNodeMapper: CompressibleAsyncDataTreeNodeMapper = new WeakMapper(node => new CompressibleAsyncDataTreeNodeWrapper(node)); constructor( diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 158fe11fda7e..71bbf302eebd 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -1143,8 +1143,8 @@ export class SelectionRange { export class CallHierarchyItem { - _sessionId: string; - _itemId: string; + _sessionId?: string; + _itemId?: string; kind: SymbolKind; name: string; diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index aa4e7f432ed5..cf9681d52e0a 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -328,7 +328,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView export abstract class FilterViewContainerViewlet extends ViewContainerViewlet { private constantViewDescriptors: Map = new Map(); private allViews: Map> = new Map(); - private filterValue: string; + private filterValue: string | undefined; protected onDidChangeFilterValue: Emitter = new Emitter(); From 90cc118a14370f21a1102eead7c35e410632051d Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 12 Nov 2019 09:24:38 +0100 Subject: [PATCH 06/60] Update visibilities before computing layout (fixes #84125) --- src/vs/workbench/browser/parts/quickinput/quickInput.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index fec32d605bf3..3a81e8c7c3b3 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -699,6 +699,7 @@ class QuickPick extends QuickInput implements IQuickPi } protected update() { + this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true, message: !!this.validationMessage } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true, message: !!this.validationMessage, customButton: this.customButton, ok: this.ok }); super.update(); if (!this.visible) { return; @@ -763,7 +764,6 @@ class QuickPick extends QuickInput implements IQuickPi this.ui.list.matchOnLabel = this.matchOnLabel; this.ui.setComboboxAccessibility(true); this.ui.inputBox.setAttribute('aria-label', QuickPick.INPUT_BOX_ARIA_LABEL); - this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true, message: !!this.validationMessage } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true, message: !!this.validationMessage, customButton: this.customButton, ok: this.ok }); } } @@ -857,6 +857,7 @@ class InputBox extends QuickInput implements IInputBox { } protected update() { + this.ui.setVisibilities({ title: !!this.title || !!this.step, inputBox: true, message: true }); super.update(); if (!this.visible) { return; @@ -882,7 +883,6 @@ class InputBox extends QuickInput implements IInputBox { this.ui.message.textContent = this.validationMessage; this.showMessageDecoration(Severity.Error); } - this.ui.setVisibilities({ title: !!this.title || !!this.step, inputBox: true, message: true }); } } From 623bae89051768933b9a14e93a2e9b496526adfb Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Nov 2019 09:43:38 +0100 Subject: [PATCH 07/60] fix #84516 --- src/vs/vscode.d.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 7bc4e66bfef4..b1f5ccc6280c 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -5986,6 +5986,9 @@ declare module 'vscode' { /** * Create a new directory (Note, that new files are created via `write`-calls). * + * *Note* that missing directories are created automatically, e.g this call has + * `mkdirp` semantics. + * * @param uri The uri of the new folder. */ createDirectory(uri: Uri): Thenable; From 039899cde9faf0ac7c1d9663c5d672b5ad389381 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=85=B7=E9=85=B7=E7=9A=84=E5=93=80=E6=AE=BF?= Date: Tue, 12 Nov 2019 16:56:31 +0800 Subject: [PATCH 08/60] Support utf-8 encoding guessing (#84504) * Update encoding.ts * fix warnings --- src/vs/base/node/encoding.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/vs/base/node/encoding.ts b/src/vs/base/node/encoding.ts index d0501c2fd6d5..c45032131704 100644 --- a/src/vs/base/node/encoding.ts +++ b/src/vs/base/node/encoding.ts @@ -199,8 +199,6 @@ export function detectEncodingByBOMFromBuffer(buffer: Buffer | VSBuffer | null, return null; } -const IGNORE_ENCODINGS = ['ascii', 'utf-8', 'utf-16', 'utf-32']; - /** * Guesses the encoding from buffer. */ @@ -212,14 +210,6 @@ async function guessEncodingByBuffer(buffer: Buffer): Promise { return null; } - const enc = guessed.encoding.toLowerCase(); - - // Ignore encodings that cannot guess correctly - // (http://chardet.readthedocs.io/en/latest/supported-encodings.html) - if (0 <= IGNORE_ENCODINGS.indexOf(enc)) { - return null; - } - return toIconvLiteEncoding(guessed.encoding); } From 2977cfea261ee53face1c6c5f9cf0279d14c5d9c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 09:57:53 +0100 Subject: [PATCH 09/60] encoding - more tests --- build/lib/compilation.ts | 2 +- .../base/test/node/encoding/encoding.test.ts | 14 ++++++ .../test/node/encoding/fixtures/some_file.css | 42 ++++++++++++++++++ .../node/encoding/fixtures/some_utf16be.css | Bin 1408 -> 1424 bytes .../node/encoding/fixtures/some_utf16le.css | Bin 1408 -> 1424 bytes .../test/node/encoding/fixtures/some_utf8.css | 6 ++- 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 src/vs/base/test/node/encoding/fixtures/some_file.css diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index 6f37821c7750..578fae31a19c 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -54,7 +54,7 @@ function createCompile(src: string, build: boolean, emitError?: boolean) { const input = es.through(); const output = input .pipe(utf8Filter) - .pipe(bom()) + .pipe(bom()) // this is required to preserve BOM in test files that loose it otherwise .pipe(utf8Filter.restore) .pipe(tsFilter) .pipe(util.loadSourcemaps()) diff --git a/src/vs/base/test/node/encoding/encoding.test.ts b/src/vs/base/test/node/encoding/encoding.test.ts index 77ad22264cf6..d8730a52b366 100644 --- a/src/vs/base/test/node/encoding/encoding.test.ts +++ b/src/vs/base/test/node/encoding/encoding.test.ts @@ -189,6 +189,20 @@ suite('Encoding', () => { assert.equal(mimes.seemsBinary, false); }); + test('autoGuessEncoding (UTF8)', async function () { + const file = getPathFromAmdModule(require, './fixtures/some_file.css'); + const buffer = await readExactlyByFile(file, 512 * 8); + const mimes = await encoding.detectEncodingFromBuffer(buffer, true); + assert.equal(mimes.encoding, 'utf8'); + }); + + test('autoGuessEncoding (ASCII)', async function () { + const file = getPathFromAmdModule(require, './fixtures/some_ansi.css'); + const buffer = await readExactlyByFile(file, 512 * 8); + const mimes = await encoding.detectEncodingFromBuffer(buffer, true); + assert.equal(mimes.encoding, 'ascii'); + }); + test('autoGuessEncoding (ShiftJIS)', async function () { const file = getPathFromAmdModule(require, './fixtures/some.shiftjis.txt'); const buffer = await readExactlyByFile(file, 512 * 8); diff --git a/src/vs/base/test/node/encoding/fixtures/some_file.css b/src/vs/base/test/node/encoding/fixtures/some_file.css new file mode 100644 index 000000000000..e4e1350019f0 --- /dev/null +++ b/src/vs/base/test/node/encoding/fixtures/some_file.css @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/*---------------------------------------------------------- +The base color for this template is #5c87b2. If you'd like +to use a different color start by replacing all instances of +#5c87b2 with your new color. + +öäüßßß +----------------------------------------------------------*/ +body +{ + background-color: #5c87b2; + font-size: .75em; + font-family: Segoe UI, Verdana, Helvetica, Sans-Serif; + margin: 8px; + padding: 0; + color: #696969; +} + +h1, h2, h3, h4, h5, h6 +{ + color: #000; + font-size: 40px; + margin: 0px; +} + +textarea +{ + font-family: Consolas +} + +#results +{ + margin-top: 2em; + margin-left: 2em; + color: black; + font-size: medium; +} + diff --git a/src/vs/base/test/node/encoding/fixtures/some_utf16be.css b/src/vs/base/test/node/encoding/fixtures/some_utf16be.css index 30c3b9d38ba3e73ef884db9b587be76fe28d751f..894438140007df4e2ed5e3e3fbce4f54e5bf5f02 100644 GIT binary patch delta 44 wcmZqRp1{3fJ)%xXjGLIa6&QFKxEQKI Date: Tue, 12 Nov 2019 10:04:35 +0100 Subject: [PATCH 10/60] Use outline (fixes #84062) --- src/vs/workbench/browser/parts/quickinput/quickInputList.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index f49a302fa420..cb9791317b06 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -598,10 +598,7 @@ registerThemingParticipant((theme, collector) => { } const activeContrast = theme.getColor(activeContrastBorder); if (activeContrast) { - collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { border: 1px dotted ${activeContrast}; }`); - collector.addRule(`.quick-input-list .monaco-list .monaco-list-row { border: 1px solid transparent; }`); - collector.addRule(`.quick-input-list .monaco-list .quick-input-list-entry { padding: 0 5px; height: 18px; align-items: center; }`); - collector.addRule(`.quick-input-list .monaco-list .quick-input-list-entry-action-bar { margin-top: 0; }`); + collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { outline: 1px dotted ${activeContrast}; outline-offset: -1px; }`); } const pickerGroupBorderColor = theme.getColor(pickerGroupBorder); if (pickerGroupBorderColor) { From 33a084fa4490cdef6c98a6eab1e1ccc89eb46ac5 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 12 Nov 2019 10:08:32 +0100 Subject: [PATCH 11/60] Update c++ grammar Fixes #84410 --- extensions/cpp/cgmanifest.json | 4 +- extensions/cpp/syntaxes/c.tmLanguage.json | 4 +- .../cpp.embedded.macro.tmLanguage.json | 88 +++++++++---------- extensions/cpp/syntaxes/cpp.tmLanguage.json | 10 +-- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/extensions/cpp/cgmanifest.json b/extensions/cpp/cgmanifest.json index 3dc984e58c2f..4fba38d93adf 100644 --- a/extensions/cpp/cgmanifest.json +++ b/extensions/cpp/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "jeff-hykin/cpp-textmate-grammar", "repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar", - "commitHash": "d937b80a19706d518e5fe52357d7c50d34a26e60" + "commitHash": "fedd206d1b2803f31a278e9b5f098ce4bc76e532" } }, "license": "MIT", - "version": "1.14.11", + "version": "1.14.13", "description": "The files syntaxes/c.json and syntaxes/c++.json were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle." }, { diff --git a/extensions/cpp/syntaxes/c.tmLanguage.json b/extensions/cpp/syntaxes/c.tmLanguage.json index d8c4dca256ba..916371903fbe 100644 --- a/extensions/cpp/syntaxes/c.tmLanguage.json +++ b/extensions/cpp/syntaxes/c.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/d937b80a19706d518e5fe52357d7c50d34a26e60", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/fedd206d1b2803f31a278e9b5f098ce4bc76e532", "name": "C", "scopeName": "source.c", "patterns": [ @@ -1177,7 +1177,7 @@ ] }, "member_access": { - "match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!(?:atomic_uint_least64_t|atomic_uint_least16_t|atomic_uint_least32_t|atomic_uint_least8_t|atomic_int_least16_t|atomic_uint_fast64_t|atomic_uint_fast32_t|atomic_int_least64_t|atomic_int_least32_t|pthread_rwlockattr_t|atomic_uint_fast16_t|pthread_mutexattr_t|atomic_int_fast16_t|atomic_uint_fast8_t|atomic_int_fast64_t|atomic_int_least8_t|atomic_int_fast32_t|atomic_int_fast8_t|pthread_condattr_t|atomic_uintptr_t|atomic_ptrdiff_t|pthread_rwlock_t|atomic_uintmax_t|pthread_mutex_t|atomic_intmax_t|atomic_intptr_t|atomic_char32_t|atomic_char16_t|pthread_attr_t|atomic_wchar_t|uint_least64_t|uint_least32_t|uint_least16_t|pthread_cond_t|pthread_once_t|uint_fast64_t|uint_fast16_t|atomic_size_t|uint_least8_t|int_least64_t|int_least32_t|int_least16_t|pthread_key_t|atomic_ullong|atomic_ushort|uint_fast32_t|atomic_schar|atomic_short|uint_fast8_t|int_fast64_t|int_fast32_t|int_fast16_t|atomic_ulong|atomic_llong|int_least8_t|atomic_uchar|memory_order|suseconds_t|int_fast8_t|atomic_bool|atomic_char|atomic_uint|atomic_long|atomic_int|useconds_t|_Imaginary|uintptr_t|pthread_t|in_addr_t|blksize_t|in_port_t|uintmax_t|uintmax_t|blkcnt_t|uint16_t|unsigned|_Complex|uint32_t|intptr_t|intmax_t|intmax_t|uint64_t|u_quad_t|int64_t|int32_t|ssize_t|caddr_t|clock_t|uint8_t|u_short|swblk_t|segsz_t|int16_t|fixpt_t|daddr_t|nlink_t|qaddr_t|size_t|time_t|mode_t|signed|quad_t|ushort|u_long|u_char|double|int8_t|ino_t|uid_t|pid_t|_Bool|float|dev_t|div_t|short|gid_t|off_t|u_int|key_t|id_t|uint|long|void|char|bool|id_t|int)\\b)[a-zA-Z_]\\w*\\b(?!\\())", + "match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!(?:atomic_uint_least64_t|atomic_uint_least16_t|atomic_uint_least32_t|atomic_uint_least8_t|atomic_int_least16_t|atomic_uint_fast64_t|atomic_uint_fast32_t|atomic_int_least64_t|atomic_int_least32_t|pthread_rwlockattr_t|atomic_uint_fast16_t|pthread_mutexattr_t|atomic_int_fast16_t|atomic_uint_fast8_t|atomic_int_fast64_t|atomic_int_least8_t|atomic_int_fast32_t|atomic_int_fast8_t|pthread_condattr_t|atomic_uintptr_t|atomic_ptrdiff_t|pthread_rwlock_t|atomic_uintmax_t|pthread_mutex_t|atomic_intmax_t|atomic_intptr_t|atomic_char32_t|atomic_char16_t|pthread_attr_t|atomic_wchar_t|uint_least64_t|uint_least32_t|uint_least16_t|pthread_cond_t|pthread_once_t|uint_fast64_t|uint_fast16_t|atomic_size_t|uint_least8_t|int_least64_t|int_least32_t|int_least16_t|pthread_key_t|atomic_ullong|atomic_ushort|uint_fast32_t|atomic_schar|atomic_short|uint_fast8_t|int_fast64_t|int_fast32_t|int_fast16_t|atomic_ulong|atomic_llong|int_least8_t|atomic_uchar|memory_order|suseconds_t|int_fast8_t|atomic_bool|atomic_char|atomic_uint|atomic_long|atomic_int|useconds_t|_Imaginary|blksize_t|pthread_t|in_addr_t|uintptr_t|in_port_t|uintmax_t|uintmax_t|blkcnt_t|uint16_t|unsigned|_Complex|uint32_t|intptr_t|intmax_t|intmax_t|uint64_t|u_quad_t|int64_t|int32_t|ssize_t|caddr_t|clock_t|uint8_t|u_short|swblk_t|segsz_t|int16_t|fixpt_t|daddr_t|nlink_t|qaddr_t|size_t|time_t|mode_t|signed|quad_t|ushort|u_long|u_char|double|int8_t|ino_t|uid_t|pid_t|_Bool|float|dev_t|div_t|short|gid_t|off_t|u_int|key_t|id_t|uint|long|void|char|bool|id_t|int)\\b)[a-zA-Z_]\\w*\\b(?!\\())", "captures": { "1": { "name": "variable.other.object.access.c" diff --git a/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json b/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json index cd2400f2c256..3f19e1339cd1 100644 --- a/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json +++ b/extensions/cpp/syntaxes/cpp.embedded.macro.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/d937b80a19706d518e5fe52357d7c50d34a26e60", + "version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/fedd206d1b2803f31a278e9b5f098ce4bc76e532", "name": "C++", "scopeName": "source.cpp.embedded.macro", "patterns": [ @@ -966,7 +966,7 @@ ] }, "class_declare": { - "match": "(class)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.class.declare.cpp" @@ -1733,7 +1733,7 @@ }, "constructor_root": { "name": "meta.function.definition.special.constructor.cpp", - "begin": "(\\s*+((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "begin": "(\\s*+((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.constructor.cpp" @@ -2094,7 +2094,7 @@ ] }, "control_flow_keywords": { - "match": "((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\{)", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\{)", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", @@ -2773,7 +2773,7 @@ }, "destructor_root": { "name": "meta.function.definition.special.member.destructor.cpp", - "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", + "begin": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<14>?)+)>)\\s*)?::)*)(((?>(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))::((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))~\\16((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\()))", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.member.destructor.cpp" @@ -3179,7 +3179,7 @@ }, "enum_block": { "name": "meta.block.enum.cpp", - "begin": "(((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?(::))?\\s*((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<15>?)+)>)\\s*)?(::))?\\s*((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.enum.declare.cpp" @@ -3859,7 +3859,7 @@ ] }, "function_call": { - "begin": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<12>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(((?(?:(?>[^<>]*)\\g<12>?)+)>)\\s*)?(\\()", + "begin": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<12>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(((?(?:(?>[^<>]*)\\g<12>?)+)>)\\s*)?(\\()", "beginCaptures": { "1": { "patterns": [ @@ -3933,7 +3933,7 @@ }, "function_definition": { "name": "meta.function.definition.cpp", - "begin": "((?:(?:^|\\G|(?<=;|\\}))|(?<=>))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*)(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", + "begin": "((?:(?:^|\\G|(?<=;|\\}))|(?<=>))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*)(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<70>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\())", "beginCaptures": { "1": { "name": "meta.head.function.definition.cpp" @@ -4529,7 +4529,7 @@ ] }, "function_pointer": { - "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", @@ -4881,7 +4881,7 @@ ] }, "function_pointer_parameter": { - "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", @@ -5535,7 +5535,7 @@ "name": "storage.type.modifier.virtual.cpp" }, { - "match": "(?<=protected|virtual|private|public|,|:)\\s*(?!(?:(?:protected|private|public)|virtual))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))", + "match": "(?<=protected|virtual|private|public|,|:)\\s*(?!(?:(?:protected|private|public)|virtual))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))", "captures": { "1": { "name": "meta.qualified_type.cpp", @@ -6668,7 +6668,7 @@ ] }, "namespace_alias": { - "match": "(?(?:(?>[^<>]*)\\g<9>?)+)>)\\s*)?::)*\\s*+)\\s*((?(?:(?>[^<>]*)\\g<9>?)+)>)\\s*)?::)*\\s*+)\\s*((?(?:(?>[^<>]*)\\g<5>?)+)>)\\s*)?::)*\\s*+)\\s*((?(?:(?>[^<>]*)\\g<5>?)+)>)\\s*)?::)*\\s*+)\\s*((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(?:(?:((?:delete\\[\\]|delete|new\\[\\]|<=>|<<=|new|>>=|\\->\\*|\\/=|%=|&=|>=|\\|=|\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|<<|>>|\\-\\-|<=|\\^=|==|!=|&&|\\|\\||\\+=|\\-=|\\*=|,|\\+|\\-|!|~|\\*|&|\\*|\\/|%|\\+|\\-|<|>|&|\\^|\\||=))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", + "begin": "((?:(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:__cdecl|__clrcall|__stdcall|__fastcall|__thiscall|__vectorcall)?)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(operator)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<67>?)+)>)\\s*)?::)*)(?:(?:((?:delete\\[\\]|delete|new\\[\\]|<=>|<<=|new|>>=|\\->\\*|\\/=|%=|&=|>=|\\|=|\\+\\+|\\-\\-|\\(\\)|\\[\\]|\\->|\\+\\+|<<|>>|\\-\\-|<=|\\^=|==|!=|&&|\\|\\||\\+=|\\-=|\\*=|,|\\+|\\-|!|~|\\*|&|\\*|\\/|%|\\+|\\-|<|>|&|\\^|\\||=))|((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?:\\[\\])?)))|(\"\")((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\<|\\())", "beginCaptures": { "1": { "name": "meta.head.function.definition.special.operator-overload.cpp" @@ -10607,7 +10607,7 @@ } }, "qualified_type": { - "match": "\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?(?![\\w<:.])", + "match": "\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<26>?)+)>)\\s*)?(?![\\w<:.])", "captures": { "0": { "name": "meta.qualified_type.cpp", @@ -10810,7 +10810,7 @@ } }, "scope_resolution": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -10833,7 +10833,7 @@ } }, "scope_resolution_function_call": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -10856,7 +10856,7 @@ } }, "scope_resolution_function_call_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -10893,7 +10893,7 @@ } }, "scope_resolution_function_definition": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -10916,7 +10916,7 @@ } }, "scope_resolution_function_definition_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -10953,7 +10953,7 @@ } }, "scope_resolution_function_definition_operator_overload": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -10976,7 +10976,7 @@ } }, "scope_resolution_function_definition_operator_overload_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11013,7 +11013,7 @@ } }, "scope_resolution_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11050,7 +11050,7 @@ } }, "scope_resolution_namespace_alias": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11073,7 +11073,7 @@ } }, "scope_resolution_namespace_alias_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11110,7 +11110,7 @@ } }, "scope_resolution_namespace_block": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11133,7 +11133,7 @@ } }, "scope_resolution_namespace_block_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11170,7 +11170,7 @@ } }, "scope_resolution_namespace_using": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11193,7 +11193,7 @@ } }, "scope_resolution_namespace_using_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11230,7 +11230,7 @@ } }, "scope_resolution_parameter": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11253,7 +11253,7 @@ } }, "scope_resolution_parameter_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11290,7 +11290,7 @@ } }, "scope_resolution_template_call": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11313,7 +11313,7 @@ } }, "scope_resolution_template_call_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11350,7 +11350,7 @@ } }, "scope_resolution_template_definition": { - "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", + "match": "(::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<4>?)+)>)\\s*)?::)*\\s*+", "captures": { "0": { "patterns": [ @@ -11373,7 +11373,7 @@ } }, "scope_resolution_template_definition_inner_generated": { - "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", + "match": "((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<8>?)+)>)\\s*)?(::)", "captures": { "1": { "patterns": [ @@ -11414,7 +11414,7 @@ "name": "punctuation.terminator.statement.cpp" }, "simple_type": { - "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?", + "match": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?", "captures": { "1": { "name": "meta.qualified_type.cpp", @@ -12450,7 +12450,7 @@ ] }, "struct_declare": { - "match": "(struct)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.struct.declare.cpp" @@ -13126,7 +13126,7 @@ } }, "type_alias": { - "match": "(using)\\s*(?!namespace)(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(?![\\w<:.]))\\s*(\\=)\\s*((?:typename)?)\\s*((?:(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(?![\\w<:.]))|(.*(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:(\\[)(\\w*)(\\])\\s*)?\\s*(?:(;)|\\n)", + "match": "(using)\\s*(?!namespace)(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(?![\\w<:.]))\\s*(\\=)\\s*((?:typename)?)\\s*((?:(?:(?:(?:(?>\\s+)|(?:\\/\\*)(?:(?>(?:[^\\*]|(?>\\*+)[^\\/])*)(?:(?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<58>?)+)>)\\s*)?(?![\\w<:.]))|(.*(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))?(?:(\\[)(\\w*)(\\])\\s*)?\\s*(?:(;)|\\n)", "captures": { "1": { "name": "keyword.other.using.directive.cpp" @@ -14094,7 +14094,7 @@ "end": "(?<=;)|(?=(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", + "begin": "(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<27>?)+)>)\\s*)?(?![\\w<:.]))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\()(\\*)\\s*((?:(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)?)\\s*(?:(\\[)(\\w*)(\\])\\s*)*(\\))\\s*(\\()", "beginCaptures": { "1": { "name": "meta.qualified_type.cpp", @@ -15393,7 +15393,7 @@ ] }, "typename": { - "match": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|new|try|for|asm|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?(?![\\w<:.]))", + "match": "(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(\\s*+((?:(?:(?:\\[\\[.*?\\]\\]|__attribute(?:__)?\\(\\(.*?\\)\\))|__declspec\\(.*?\\))|alignas\\(.*?\\))(?!\\)))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?:(?:(?:unsigned|signed|short|long)|(?:struct|class|union|enum))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(((::)?(?:((?-mix:(?!\\b(?:__has_cpp_attribute|reinterpret_cast|atomic_noexcept|atomic_cancel|atomic_commit|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|consteval|constexpr|protected|namespace|co_return|constexpr|constexpr|continue|explicit|volatile|noexcept|co_yield|noexcept|noexcept|requires|typename|decltype|operator|co_await|template|volatile|register|restrict|reflexpr|alignof|private|default|mutable|include|concept|__asm__|defined|_Pragma|alignas|typedef|warning|virtual|mutable|struct|sizeof|delete|not_eq|bitand|and_eq|xor_eq|typeid|switch|return|static|extern|inline|friend|public|ifndef|define|pragma|export|import|module|catch|throw|const|or_eq|while|compl|bitor|const|union|ifdef|class|undef|error|break|using|endif|goto|line|enum|this|case|else|elif|else|asm|try|for|new|and|xor|not|do|or|if|if)\\b)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*))\\s*+(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?::)*\\s*+)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\s*+(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?(::))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?!(?:transaction_safe_dynamic|__has_cpp_attribute|transaction_safe|reinterpret_cast|atomic_noexcept|atomic_commit|atomic_cancel|__has_include|dynamic_cast|thread_local|synchronized|static_cast|const_cast|constexpr|consteval|protected|constexpr|co_return|namespace|constexpr|noexcept|typename|decltype|template|operator|noexcept|co_yield|co_await|continue|volatile|register|restrict|explicit|override|volatile|reflexpr|noexcept|requires|default|typedef|nullptr|alignof|mutable|concept|virtual|defined|__asm__|include|_Pragma|mutable|warning|private|alignas|module|switch|not_eq|bitand|and_eq|ifndef|return|sizeof|xor_eq|export|static|delete|public|define|extern|inline|import|pragma|friend|typeid|const|compl|bitor|throw|or_eq|while|catch|break|false|final|const|endif|ifdef|undef|error|using|audit|axiom|line|else|elif|true|NULL|case|goto|else|this|new|asm|not|and|xor|try|for|if|do|or|if)\\b)((?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*)\\b(((?(?:(?>[^<>]*)\\g<36>?)+)>)\\s*)?(?![\\w<:.]))", "captures": { "1": { "name": "storage.modifier.cpp" @@ -15976,7 +15976,7 @@ ] }, "union_declare": { - "match": "(union)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.union.declare.cpp" @@ -16167,7 +16167,7 @@ }, "using_namespace": { "name": "meta.using-namespace.cpp", - "begin": "(?(?:(?>[^<>]*)\\g<7>?)+)>)\\s*)?::)*\\s*+)?((?(?:(?>[^<>]*)\\g<7>?)+)>)\\s*)?::)*\\s*+)?((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.class.declare.cpp" @@ -3307,7 +3307,7 @@ ] }, "enum_declare": { - "match": "(enum)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.enum.declare.cpp" @@ -12450,7 +12450,7 @@ ] }, "struct_declare": { - "match": "(struct)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.struct.declare.cpp" @@ -15976,7 +15976,7 @@ ] }, "union_declare": { - "match": "(union)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", + "match": "((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])", "captures": { "1": { "name": "storage.type.union.declare.cpp" From 4312a6feb64f7963ebbe267c0ea38da76ad8d58a Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 10:25:13 +0100 Subject: [PATCH 12/60] fixes #83465 --- .../contrib/debug/browser/debugConfigurationManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index c4f71f9db263..0c4a83d2cb42 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -416,7 +416,7 @@ export class ConfigurationManager implements IConfigurationManager { return candidates.then(debuggers => { debuggers.sort((first, second) => first.label.localeCompare(second.label)); const picks = debuggers.map(c => ({ label: c.label, debugger: c })); - return this.quickInputService.pick<{ label: string, debugger: Debugger | undefined }>([...picks, { type: 'separator' }, { label: 'More...', debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) + return this.quickInputService.pick<{ label: string, debugger: Debugger | undefined }>([...picks, { type: 'separator' }, { label: nls.localize('more', "More..."), debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") }) .then(picked => { if (picked && picked.debugger) { return picked.debugger; From 1aa537bf59f30de70b02ec3a22aa17b6da96f08e Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 12 Nov 2019 10:33:11 +0100 Subject: [PATCH 13/60] Use log service in exthosttask and exthosttreeviews Part of #84283 --- src/vs/workbench/api/common/extHostTask.ts | 17 +++++++++++------ src/vs/workbench/api/common/extHostTreeViews.ts | 10 ++++++++-- src/vs/workbench/api/node/extHostTask.ts | 8 +++++--- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/api/common/extHostTask.ts b/src/vs/workbench/api/common/extHostTask.ts index 944f6a196190..fc9f83e5d2ce 100644 --- a/src/vs/workbench/api/common/extHostTask.ts +++ b/src/vs/workbench/api/common/extHostTask.ts @@ -24,6 +24,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { Schemas } from 'vs/base/common/network'; import * as Platform from 'vs/base/common/platform'; +import { ILogService } from 'vs/platform/log/common/log'; export interface IExtHostTask extends ExtHostTaskShape { @@ -374,6 +375,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape { protected readonly _editorService: IExtHostDocumentsAndEditors; protected readonly _configurationService: IExtHostConfiguration; protected readonly _terminalService: IExtHostTerminalService; + protected readonly _logService: ILogService; protected _handleCounter: number; protected _handlers: Map; protected _taskExecutions: Map; @@ -393,7 +395,8 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape { @IExtHostWorkspace workspaceService: IExtHostWorkspace, @IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors, @IExtHostConfiguration configurationService: IExtHostConfiguration, - @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService + @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService, + @ILogService logService: ILogService ) { this._proxy = extHostRpc.getProxy(MainContext.MainThreadTask); this._workspaceProvider = workspaceService; @@ -406,6 +409,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape { this._providedCustomExecutions2 = new Map(); this._notProvidedCustomExecutions = new Set(); this._activeCustomExecutions2 = new Map(); + this._logService = logService; } public registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable { @@ -661,9 +665,10 @@ export class WorkerExtHostTask extends ExtHostTaskBase { @IExtHostWorkspace workspaceService: IExtHostWorkspace, @IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors, @IExtHostConfiguration configurationService: IExtHostConfiguration, - @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService + @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService, + @ILogService logService: ILogService ) { - super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService); + super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService); if (initData.remote.isRemote && initData.remote.authority) { this.registerTaskSystem(Schemas.vscodeRemote, { scheme: Schemas.vscodeRemote, @@ -696,7 +701,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase { if (value) { for (let task of value) { if (!task.definition || !validTypes[task.definition.type]) { - console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`); + this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`); } const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension); @@ -707,7 +712,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase { // is invoked, we have to be able to map it back to our data. taskIdPromises.push(this.addCustomExecution(taskDTO, task, true)); } else { - console.warn('Only custom execution tasks supported.'); + this._logService.warn('Only custom execution tasks supported.'); } } } @@ -721,7 +726,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase { if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) { return resolvedTaskDTO; } else { - console.warn('Only custom execution tasks supported.'); + this._logService.warn('Only custom execution tasks supported.'); } return undefined; } diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index 24b55f765df2..15e808589302 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -198,7 +198,13 @@ class ExtHostTreeView extends Disposable { private refreshPromise: Promise = Promise.resolve(); private refreshQueue: Promise = Promise.resolve(); - constructor(private viewId: string, options: vscode.TreeViewOptions, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService, private extension: IExtensionDescription) { + constructor( + private viewId: string, options: vscode.TreeViewOptions, + private proxy: MainThreadTreeViewsShape, + private commands: CommandsConverter, + private logService: ILogService, + private extension: IExtensionDescription + ) { super(); if (extension.contributes && extension.contributes.views) { for (const location in extension.contributes.views) { @@ -250,7 +256,7 @@ class ExtHostTreeView extends Disposable { getChildren(parentHandle: TreeItemHandle | Root): Promise { const parentElement = parentHandle ? this.getExtensionElement(parentHandle) : undefined; if (parentHandle && !parentElement) { - console.error(`No tree item with id \'${parentHandle}\' found.`); + this.logService.error(`No tree item with id \'${parentHandle}\' found.`); return Promise.resolve([]); } diff --git a/src/vs/workbench/api/node/extHostTask.ts b/src/vs/workbench/api/node/extHostTask.ts index c7a2ea29e9d0..6e1a647067a7 100644 --- a/src/vs/workbench/api/node/extHostTask.ts +++ b/src/vs/workbench/api/node/extHostTask.ts @@ -22,6 +22,7 @@ import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; import { ExtHostTaskBase, TaskHandleDTO, TaskDTO, CustomExecutionDTO, HandlerData } from 'vs/workbench/api/common/extHostTask'; import { Schemas } from 'vs/base/common/network'; +import { ILogService } from 'vs/platform/log/common/log'; export class ExtHostTask extends ExtHostTaskBase { private _variableResolver: ExtHostVariableResolverService | undefined; @@ -32,9 +33,10 @@ export class ExtHostTask extends ExtHostTaskBase { @IExtHostWorkspace workspaceService: IExtHostWorkspace, @IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors, @IExtHostConfiguration configurationService: IExtHostConfiguration, - @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService + @IExtHostTerminalService extHostTerminalService: IExtHostTerminalService, + @ILogService logService: ILogService ) { - super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService); + super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService); if (initData.remote.isRemote && initData.remote.authority) { this.registerTaskSystem(Schemas.vscodeRemote, { scheme: Schemas.vscodeRemote, @@ -71,7 +73,7 @@ export class ExtHostTask extends ExtHostTaskBase { if (value) { for (let task of value) { if (!task.definition || !validTypes[task.definition.type]) { - console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`); + this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`); } const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension); From 1dae4ffdc665d8dd814055657499040e88d53d6a Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 12 Nov 2019 10:12:01 +0100 Subject: [PATCH 14/60] catch tree rerender errors fixes #82629 --- src/vs/workbench/browser/parts/views/customView.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/views/customView.ts b/src/vs/workbench/browser/parts/views/customView.ts index 2d6dc484f22b..c48f38e71189 100644 --- a/src/vs/workbench/browser/parts/views/customView.ts +++ b/src/vs/workbench/browser/parts/views/customView.ts @@ -611,7 +611,15 @@ export class CustomTreeView extends Disposable implements ITreeView { if (tree && this.visible) { this.refreshing = true; await Promise.all(elements.map(element => tree.updateChildren(element, true))); - elements.map(element => tree.rerender(element)); + + elements.map(element => { + try { + tree.rerender(element); + } catch { + // noop + } + }); + this.refreshing = false; this.updateContentAreas(); if (this.focused) { From a8f5f3e0a7128ba36d48f4cd5d63e88dc48156f3 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 12 Nov 2019 10:12:10 +0100 Subject: [PATCH 15/60] add log tracing to main thread tree views --- .../workbench/api/browser/mainThreadTreeViews.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/api/browser/mainThreadTreeViews.ts b/src/vs/workbench/api/browser/mainThreadTreeViews.ts index 031dae4a7f7e..58796f182f6f 100644 --- a/src/vs/workbench/api/browser/mainThreadTreeViews.ts +++ b/src/vs/workbench/api/browser/mainThreadTreeViews.ts @@ -12,6 +12,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { isUndefinedOrNull, isNumber } from 'vs/base/common/types'; import { Registry } from 'vs/platform/registry/common/platform'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; +import { ILogService } from 'vs/platform/log/common/log'; @extHostNamedCustomer(MainContext.MainThreadTreeViews) export class MainThreadTreeViews extends Disposable implements MainThreadTreeViewsShape { @@ -23,13 +24,16 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie extHostContext: IExtHostContext, @IViewsService private readonly viewsService: IViewsService, @INotificationService private readonly notificationService: INotificationService, - @IExtensionService private readonly extensionService: IExtensionService + @IExtensionService private readonly extensionService: IExtensionService, + @ILogService private readonly logService: ILogService ) { super(); this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews); } $registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void { + this.logService.trace('MainThreadTreeViews#$registerTreeViewDataProvider', treeViewId, options); + this.extensionService.whenInstalledExtensionsRegistered().then(() => { const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService); this._dataProviders.set(treeViewId, dataProvider); @@ -49,6 +53,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie } $reveal(treeViewId: string, item: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise { + this.logService.trace('MainThreadTreeViews#$reveal', treeViewId, item, parentChain, options); + return this.viewsService.openView(treeViewId, options.focus) .then(() => { const viewer = this.getTreeView(treeViewId); @@ -60,6 +66,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie } $refresh(treeViewId: string, itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeItem }): Promise { + this.logService.trace('MainThreadTreeViews#$refresh', treeViewId, itemsToRefreshByHandle); + const viewer = this.getTreeView(treeViewId); const dataProvider = this._dataProviders.get(treeViewId); if (viewer && dataProvider) { @@ -70,6 +78,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie } $setMessage(treeViewId: string, message: string): void { + this.logService.trace('MainThreadTreeViews#$setMessage', treeViewId, message); + const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.message = message; @@ -77,6 +87,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie } $setTitle(treeViewId: string, title: string): void { + this.logService.trace('MainThreadTreeViews#$setTitle', treeViewId, title); + const viewer = this.getTreeView(treeViewId); if (viewer) { viewer.title = title; From 337ab02cd128ed65abdcd429a30cc57b517883e8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 12 Nov 2019 10:39:40 +0100 Subject: [PATCH 16/60] fix extension viewlet shift --- .../workbench/contrib/extensions/browser/extensionsViewlet.ts | 2 +- .../contrib/extensions/browser/media/extensionsViewlet.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 2bee5aa811ee..250084615b91 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -442,7 +442,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio if (this.searchBox) { this.searchBox.layout({ height: 20, width: dimension.width - 34 }); } - super.layout(new Dimension(dimension.width, dimension.height - 38)); + super.layout(new Dimension(dimension.width, dimension.height - 41)); } getOptimalWidth(): number { diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css index 025c3b826ccc..8c115cdd9122 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css @@ -25,7 +25,7 @@ } .extensions-viewlet > .extensions { - height: calc(100% - 38px); + height: calc(100% - 41px); } .extensions-viewlet > .extensions .extension-view-header .monaco-action-bar { From d5ff86c8ec3eb2e6bed120fcbb17a1f7ba18472f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 10:05:00 +0100 Subject: [PATCH 17/60] debt - move tests --- .../test => test/node/zip}/fixtures/extract.zip | Bin .../base/{node/test => test/node/zip}/zip.test.ts | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/vs/base/{node/test => test/node/zip}/fixtures/extract.zip (100%) rename src/vs/base/{node/test => test/node/zip}/zip.test.ts (100%) diff --git a/src/vs/base/node/test/fixtures/extract.zip b/src/vs/base/test/node/zip/fixtures/extract.zip similarity index 100% rename from src/vs/base/node/test/fixtures/extract.zip rename to src/vs/base/test/node/zip/fixtures/extract.zip diff --git a/src/vs/base/node/test/zip.test.ts b/src/vs/base/test/node/zip/zip.test.ts similarity index 100% rename from src/vs/base/node/test/zip.test.ts rename to src/vs/base/test/node/zip/zip.test.ts From 5ae52b61cbdc1bc545b562fe265ec1e545385e0b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 10:41:54 +0100 Subject: [PATCH 18/60] files - implement ctime properly as btime (fix #84525) --- .../singlefolder-tests/workspace.fs.test.ts | 2 + src/vs/platform/files/common/fileService.ts | 3 ++ src/vs/platform/files/common/files.ts | 24 ++++++++-- .../files/node/diskFileSystemProvider.ts | 2 +- .../files/test/node/diskFileService.test.ts | 44 ++++++++++++++++--- .../api/browser/mainThreadFileSystem.ts | 2 +- .../textfile/common/textFileEditorModel.ts | 4 ++ .../workbench/test/workbenchTestServices.ts | 4 ++ 8 files changed, 74 insertions(+), 11 deletions(-) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts index 06728e206d94..7d552df04a81 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.fs.test.ts @@ -23,6 +23,8 @@ suite('workspace-fs', () => { assert.equal(typeof stat.mtime, 'number'); assert.equal(typeof stat.ctime, 'number'); + assert.ok(stat.mtime > 0); + assert.ok(stat.ctime > 0); const entries = await vscode.workspace.fs.readDirectory(root); assert.ok(entries.length > 0); diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index b789748febe1..c3fd729d148f 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -209,6 +209,8 @@ export class FileService extends Disposable implements IFileService { }); } + private async toFileStat(provider: IFileSystemProvider, resource: URI, stat: IStat | { type: FileType } & Partial, siblings: number | undefined, resolveMetadata: boolean, recurse: (stat: IFileStat, siblings?: number) => boolean): Promise; + private async toFileStat(provider: IFileSystemProvider, resource: URI, stat: IStat, siblings: number | undefined, resolveMetadata: true, recurse: (stat: IFileStat, siblings?: number) => boolean): Promise; private async toFileStat(provider: IFileSystemProvider, resource: URI, stat: IStat | { type: FileType } & Partial, siblings: number | undefined, resolveMetadata: boolean, recurse: (stat: IFileStat, siblings?: number) => boolean): Promise { // convert to file stat @@ -219,6 +221,7 @@ export class FileService extends Disposable implements IFileService { isSymbolicLink: (stat.type & FileType.SymbolicLink) !== 0, isReadonly: !!(provider.capabilities & FileSystemProviderCapabilities.Readonly), mtime: stat.mtime, + ctime: stat.ctime, size: stat.size, etag: etag({ mtime: stat.mtime, size: stat.size }) }; diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index 0356e8dfdd3c..85e140f5b104 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -207,8 +207,17 @@ export enum FileType { export interface IStat { type: FileType; + + /** + * The last modification date represented as millis from unix epoch. + */ mtime: number; + + /** + * The creation date represented as millis from unix epoch. + */ ctime: number; + size: number; } @@ -583,14 +592,21 @@ interface IBaseStat { size?: number; /** - * The last modification date represented - * as millis from unix epoch. + * The last modification date represented as millis from unix epoch. * * The value may or may not be resolved as * it is optional. */ mtime?: number; + /** + * The creation date represented as millis from unix epoch. + * + * The value may or may not be resolved as + * it is optional. + */ + ctime?: number; + /** * A unique identifier thet represents the * current state of the file or directory. @@ -608,6 +624,7 @@ interface IBaseStat { export interface IBaseStatWithMetadata extends IBaseStat { mtime: number; + ctime: number; etag: string; size: number; } @@ -635,6 +652,7 @@ export interface IFileStat extends IBaseStat { export interface IFileStatWithMetadata extends IFileStat, IBaseStatWithMetadata { mtime: number; + ctime: number; etag: string; size: number; children?: IFileStatWithMetadata[]; @@ -703,7 +721,7 @@ export interface IResolveFileOptions { readonly resolveSingleChildDescendants?: boolean; /** - * Will resolve mtime, size and etag of files if enabled. This can have a negative impact + * Will resolve mtime, ctime, size and etag of files if enabled. This can have a negative impact * on performance and thus should only be used when these values are required. */ readonly resolveMetadata?: boolean; diff --git a/src/vs/platform/files/node/diskFileSystemProvider.ts b/src/vs/platform/files/node/diskFileSystemProvider.ts index 7c7e255d80e2..0187b5d9bccf 100644 --- a/src/vs/platform/files/node/diskFileSystemProvider.ts +++ b/src/vs/platform/files/node/diskFileSystemProvider.ts @@ -80,7 +80,7 @@ export class DiskFileSystemProvider extends Disposable implements return { type: this.toType(stat, isSymbolicLink), - ctime: stat.ctime.getTime(), + ctime: stat.birthtime.getTime(), // intentionally not using ctime here, we want the creation time mtime: stat.mtime.getTime(), size: stat.size }; diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index 32cbb18e5458..f1a81f3e20e4 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -213,23 +213,32 @@ suite('Disk File Service', function () { assert.equal(exists, false); }); - test('resolve', async () => { - const resolved = await service.resolve(URI.file(testDir), { resolveTo: [URI.file(join(testDir, 'deep'))] }); - assert.equal(resolved.children!.length, 8); + test('resolve - file', async () => { + const resource = URI.file(getPathFromAmdModule(require, './fixtures/resolver/index.html')); + const resolved = await service.resolve(resource); - const deep = (getByName(resolved, 'deep')!); - assert.equal(deep.children!.length, 4); + assert.equal(resolved.name, 'index.html'); + assert.equal(resolved.resource.toString(), resource.toString()); + assert.equal(resolved.children, undefined); + assert.ok(resolved.mtime! > 0); + assert.ok(resolved.ctime! > 0); + assert.ok(resolved.size! > 0); }); test('resolve - directory', async () => { const testsElements = ['examples', 'other', 'index.html', 'site.css']; - const result = await service.resolve(URI.file(getPathFromAmdModule(require, './fixtures/resolver'))); + const resource = URI.file(getPathFromAmdModule(require, './fixtures/resolver')); + const result = await service.resolve(resource); assert.ok(result); + assert.equal(result.resource.toString(), resource.toString()); + assert.equal(result.name, 'resolver'); assert.ok(result.children); assert.ok(result.children!.length > 0); assert.ok(result!.isDirectory); + assert.ok(result.mtime! > 0); + assert.ok(result.ctime! > 0); assert.equal(result.children!.length, testsElements.length); assert.ok(result.children!.every(entry => { @@ -242,12 +251,18 @@ suite('Disk File Service', function () { assert.ok(basename(value.resource.fsPath)); if (['examples', 'other'].indexOf(basename(value.resource.fsPath)) >= 0) { assert.ok(value.isDirectory); + assert.equal(value.mtime, undefined); + assert.equal(value.ctime, undefined); } else if (basename(value.resource.fsPath) === 'index.html') { assert.ok(!value.isDirectory); assert.ok(!value.children); + assert.equal(value.mtime, undefined); + assert.equal(value.ctime, undefined); } else if (basename(value.resource.fsPath) === 'site.css') { assert.ok(!value.isDirectory); assert.ok(!value.children); + assert.equal(value.mtime, undefined); + assert.equal(value.ctime, undefined); } else { assert.ok(!'Unexpected value ' + basename(value.resource.fsPath)); } @@ -260,9 +275,12 @@ suite('Disk File Service', function () { const result = await service.resolve(URI.file(getPathFromAmdModule(require, './fixtures/resolver')), { resolveMetadata: true }); assert.ok(result); + assert.equal(result.name, 'resolver'); assert.ok(result.children); assert.ok(result.children!.length > 0); assert.ok(result!.isDirectory); + assert.ok(result.mtime! > 0); + assert.ok(result.ctime! > 0); assert.equal(result.children!.length, testsElements.length); assert.ok(result.children!.every(entry => { @@ -277,18 +295,32 @@ suite('Disk File Service', function () { assert.ok(basename(value.resource.fsPath)); if (['examples', 'other'].indexOf(basename(value.resource.fsPath)) >= 0) { assert.ok(value.isDirectory); + assert.ok(value.mtime! > 0); + assert.ok(value.ctime! > 0); } else if (basename(value.resource.fsPath) === 'index.html') { assert.ok(!value.isDirectory); assert.ok(!value.children); + assert.ok(value.mtime! > 0); + assert.ok(value.ctime! > 0); } else if (basename(value.resource.fsPath) === 'site.css') { assert.ok(!value.isDirectory); assert.ok(!value.children); + assert.ok(value.mtime! > 0); + assert.ok(value.ctime! > 0); } else { assert.ok(!'Unexpected value ' + basename(value.resource.fsPath)); } }); }); + test('resolve - directory with resolveTo', async () => { + const resolved = await service.resolve(URI.file(testDir), { resolveTo: [URI.file(join(testDir, 'deep'))] }); + assert.equal(resolved.children!.length, 8); + + const deep = (getByName(resolved, 'deep')!); + assert.equal(deep.children!.length, 4); + }); + test('resolve - directory - resolveTo single directory', async () => { const resolverFixturesPath = getPathFromAmdModule(require, './fixtures/resolver'); const result = await service.resolve(URI.file(resolverFixturesPath), { resolveTo: [URI.file(join(resolverFixturesPath, 'other/deep'))] }); diff --git a/src/vs/workbench/api/browser/mainThreadFileSystem.ts b/src/vs/workbench/api/browser/mainThreadFileSystem.ts index 3407a420ca74..fa8c5bdaf7ed 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystem.ts @@ -52,7 +52,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { $stat(uri: UriComponents): Promise { return this._fileService.resolve(URI.revive(uri), { resolveMetadata: true }).then(stat => { return { - ctime: 0, + ctime: stat.ctime, mtime: stat.mtime, size: stat.size, type: MainThreadFileSystem._getFileType(stat) diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 5cfaec6676bb..5e6a21d69872 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -32,6 +32,7 @@ import { Schemas } from 'vs/base/common/network'; export interface IBackupMetaData { mtime: number; + ctime: number; size: number; etag: string; orphaned: boolean; @@ -224,6 +225,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil if (isEqual(target, this.resource) && this.lastResolvedFileStat) { meta = { mtime: this.lastResolvedFileStat.mtime, + ctime: this.lastResolvedFileStat.ctime, size: this.lastResolvedFileStat.size, etag: this.lastResolvedFileStat.etag, orphaned: this.inOrphanMode @@ -313,6 +315,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil resource: this.resource, name: basename(this.resource), mtime: resolvedBackup.meta ? resolvedBackup.meta.mtime : Date.now(), + ctime: resolvedBackup.meta ? resolvedBackup.meta.ctime : Date.now(), size: resolvedBackup.meta ? resolvedBackup.meta.size : 0, etag: resolvedBackup.meta ? resolvedBackup.meta.etag : ETAG_DISABLED, // etag disabled if unknown! value: resolvedBackup.value, @@ -397,6 +400,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil resource: this.resource, name: content.name, mtime: content.mtime, + ctime: content.ctime, size: content.size, etag: content.etag, isDirectory: false, diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 9b4fbf6b47c0..e536d21ee319 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -262,6 +262,7 @@ export class TestTextFileService extends NativeTextFileService { resource: content.resource, name: content.name, mtime: content.mtime, + ctime: content.ctime, etag: content.etag, encoding: 'utf8', value: await createTextBufferFactoryFromStream(content.value), @@ -996,6 +997,7 @@ export class TestFileService implements IFileService { etag: 'index.txt', encoding: 'utf8', mtime: Date.now(), + ctime: Date.now(), name: resources.basename(resource), size: 1 }); @@ -1022,6 +1024,7 @@ export class TestFileService implements IFileService { etag: 'index.txt', encoding: 'utf8', mtime: Date.now(), + ctime: Date.now(), size: 1, name: resources.basename(resource) }); @@ -1033,6 +1036,7 @@ export class TestFileService implements IFileService { etag: 'index.txt', encoding: 'utf8', mtime: Date.now(), + ctime: Date.now(), size: 42, isDirectory: false, name: resources.basename(resource) From 77d57689ccc16dfeacc328868b1567136ab1adee Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 11:11:34 +0100 Subject: [PATCH 19/60] files - introduce IFileStat.isFile() for #84524 --- src/vs/platform/files/common/fileService.ts | 1 + src/vs/platform/files/common/files.ts | 9 +++++++-- src/vs/platform/files/test/node/diskFileService.test.ts | 3 +++ .../services/textfile/common/textFileEditorModel.ts | 1 + src/vs/workbench/test/workbenchTestServices.ts | 4 ++++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/files/common/fileService.ts b/src/vs/platform/files/common/fileService.ts index c3fd729d148f..d3a70db859d2 100644 --- a/src/vs/platform/files/common/fileService.ts +++ b/src/vs/platform/files/common/fileService.ts @@ -217,6 +217,7 @@ export class FileService extends Disposable implements IFileService { const fileStat: IFileStat = { resource, name: getBaseLabel(resource), + isFile: (stat.type & FileType.File) !== 0, isDirectory: (stat.type & FileType.Directory) !== 0, isSymbolicLink: (stat.type & FileType.SymbolicLink) !== 0, isReadonly: !!(provider.capabilities & FileSystemProviderCapabilities.Readonly), diff --git a/src/vs/platform/files/common/files.ts b/src/vs/platform/files/common/files.ts index 85e140f5b104..15f2e20910b8 100644 --- a/src/vs/platform/files/common/files.ts +++ b/src/vs/platform/files/common/files.ts @@ -635,14 +635,19 @@ export interface IBaseStatWithMetadata extends IBaseStat { export interface IFileStat extends IBaseStat { /** - * The resource is a directory + * The resource is a file. + */ + isFile: boolean; + + /** + * The resource is a directory. */ isDirectory: boolean; /** * The resource is a symbolic link. */ - isSymbolicLink?: boolean; + isSymbolicLink: boolean; /** * The children of the file stat or undefined if none. diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index f1a81f3e20e4..79ecd34d5f08 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -218,6 +218,9 @@ suite('Disk File Service', function () { const resolved = await service.resolve(resource); assert.equal(resolved.name, 'index.html'); + assert.equal(resolved.isFile, true); + assert.equal(resolved.isDirectory, false); + assert.equal(resolved.isSymbolicLink, false); assert.equal(resolved.resource.toString(), resource.toString()); assert.equal(resolved.children, undefined); assert.ok(resolved.mtime! > 0); diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 5e6a21d69872..8618b539f5a3 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -403,6 +403,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil ctime: content.ctime, size: content.size, etag: content.etag, + isFile: true, isDirectory: false, isSymbolicLink: false, isReadonly: content.isReadonly diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index e536d21ee319..c4acaed37e87 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -975,7 +975,9 @@ export class TestFileService implements IFileService { encoding: 'utf8', mtime: Date.now(), size: 42, + isFile: true, isDirectory: false, + isSymbolicLink: false, name: resources.basename(resource) }); } @@ -1038,7 +1040,9 @@ export class TestFileService implements IFileService { mtime: Date.now(), ctime: Date.now(), size: 42, + isFile: true, isDirectory: false, + isSymbolicLink: false, name: resources.basename(resource) })); } From 5fbd6bbc56d77c090f729c0d22fb1cf84163a7a1 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 11:13:02 +0100 Subject: [PATCH 20/60] fixes #83478 --- src/vs/workbench/contrib/files/browser/views/explorerViewer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index 054a39beafe5..2a1d6e7a9d67 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -702,7 +702,7 @@ export class FileDragAndDrop implements ITreeDragAndDrop { if (targetStat.children) { const ignoreCase = hasToIgnoreCase(target.resource); targetStat.children.forEach(child => { - targetNames.add(ignoreCase ? child.name : child.name.toLowerCase()); + targetNames.add(ignoreCase ? child.name.toLowerCase() : child.name); }); } From 8faa1d52f1a17bbce681a6d7d00a739a73c27e75 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 12 Nov 2019 11:27:34 +0100 Subject: [PATCH 21/60] Only QuickNav if there was a keyDown since shown (fixes #83013) --- src/vs/base/parts/quickopen/browser/quickOpenWidget.ts | 7 ++++++- src/vs/workbench/browser/parts/quickinput/quickInput.ts | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 7a3a473d9700..dc7df956ff2c 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -134,6 +134,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { private styles: IQuickOpenStyles; // @ts-ignore (legacy widget - to be replaced with quick input) private renderer: Renderer; + private keyDownSeenSinceShown = false; constructor(container: HTMLElement, callbacks: IQuickOpenCallbacks, options: IQuickOpenOptions) { super(); @@ -170,6 +171,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { this._register(DOM.addDisposableListener(this.element, DOM.EventType.FOCUS, e => this.gainingFocus(), true)); this._register(DOM.addDisposableListener(this.element, DOM.EventType.BLUR, e => this.loosingFocus(e), true)); this._register(DOM.addDisposableListener(this.element, DOM.EventType.KEY_DOWN, e => { + this.keyDownSeenSinceShown = true; const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e); if (keyboardEvent.keyCode === KeyCode.Escape) { DOM.EventHelper.stop(e, true); @@ -220,6 +222,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { this._register(DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.INPUT, (e: Event) => this.onType())); this._register(DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => { + this.keyDownSeenSinceShown = true; const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e); const shouldOpenInBackground = this.shouldOpenInBackground(keyboardEvent); @@ -300,6 +303,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { })); this._register(DOM.addDisposableListener(this.treeContainer, DOM.EventType.KEY_DOWN, e => { + this.keyDownSeenSinceShown = true; const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e); // Only handle when in quick navigation mode @@ -320,7 +324,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { const keyCode = keyboardEvent.keyCode; // Only handle when in quick navigation mode - if (!this.quickNavigateConfiguration) { + if (!this.quickNavigateConfiguration || !this.keyDownSeenSinceShown) { return; } @@ -595,6 +599,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider { this.visible = true; this.isLoosingFocus = false; this.quickNavigateConfiguration = options ? options.quickNavigateConfiguration : undefined; + this.keyDownSeenSinceShown = false; // Adjust UI for quick navigate mode if (this.quickNavigateConfiguration) { diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 3a81e8c7c3b3..529f2a9c95f2 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -84,6 +84,7 @@ interface QuickInputUI { onDidTriggerButton: Event; ignoreFocusOut: boolean; keyMods: Writeable; + keyDownSeenSinceShown: boolean; isScreenReaderOptimized(): boolean; show(controller: QuickInput): void; setVisibilities(visibilities: Visibilities): void; @@ -216,6 +217,7 @@ class QuickInput extends Disposable implements IQuickInput { } }), ); + this.ui.keyDownSeenSinceShown = false; this.ui.show(this); this.visible = true; this.update(); @@ -554,6 +556,7 @@ class QuickPick extends QuickInput implements IQuickPi } })); this.visibleDisposables.add(this.ui.inputBox.onKeyDown(event => { + this.ui.keyDownSeenSinceShown = true; switch (event.keyCode) { case KeyCode.DownArrow: this.ui.list.focus('Next'); @@ -652,7 +655,7 @@ class QuickPick extends QuickInput implements IQuickPi private registerQuickNavigation() { return dom.addDisposableListener(this.ui.container, dom.EventType.KEY_UP, e => { - if (this.canSelectMany || !this.quickNavigate) { + if (this.canSelectMany || !this.quickNavigate || !this.ui.keyDownSeenSinceShown) { return; } @@ -1111,6 +1114,7 @@ export class QuickInputService extends Component implements IQuickInputService { inputBox.setFocus(); })); this._register(dom.addDisposableListener(container, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => { + this.getUI().keyDownSeenSinceShown = true; const event = new StandardKeyboardEvent(e); switch (event.keyCode) { case KeyCode.Enter: @@ -1172,6 +1176,7 @@ export class QuickInputService extends Component implements IQuickInputService { onDidTriggerButton: this.onDidTriggerButtonEmitter.event, ignoreFocusOut: false, keyMods: this.keyMods, + keyDownSeenSinceShown: false, isScreenReaderOptimized: () => this.isScreenReaderOptimized(), show: controller => this.show(controller), hide: () => this.hide(), From a7d466093bc6eea36a07ff6e312f7c652dca50e6 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 11:37:37 +0100 Subject: [PATCH 22/60] Zen mode react on silentNotifcations setting change fixes #83535 --- src/vs/workbench/browser/layout.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 24ebadeba87e..81fd79a40a4f 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -747,6 +747,13 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi if (config.silentNotifications) { this.notificationService.setFilter(NotificationsFilter.ERROR); } + this.state.zenMode.transitionDisposables.add(this.configurationService.onDidChangeConfiguration(c => { + const silentNotificationsKey = 'zenMode.silentNotifications'; + if (c.affectsConfiguration(silentNotificationsKey)) { + const filter = this.configurationService.getValue(silentNotificationsKey) ? NotificationsFilter.ERROR : NotificationsFilter.OFF; + this.notificationService.setFilter(filter); + } + })); if (config.centerLayout) { this.centerEditorLayout(true, true); From a2e9c12994620f6a55dd5df34d49044c6ee84488 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Nov 2019 11:42:34 +0100 Subject: [PATCH 23/60] use isFile-info instead of defaulting to FileType.File, fixes #84524 --- .../api/browser/mainThreadFileSystem.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadFileSystem.ts b/src/vs/workbench/api/browser/mainThreadFileSystem.ts index fa8c5bdaf7ed..4a26a90cd76d 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystem.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystem.ts @@ -55,7 +55,7 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { ctime: stat.ctime, mtime: stat.mtime, size: stat.size, - type: MainThreadFileSystem._getFileType(stat) + type: MainThreadFileSystem._asFileType(stat) }; }).catch(MainThreadFileSystem._handleError); } @@ -67,12 +67,22 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape { err.name = FileSystemProviderErrorCode.FileNotADirectory; throw err; } - return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._getFileType(child)] as [string, FileType]); + return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._asFileType(child)] as [string, FileType]); }).catch(MainThreadFileSystem._handleError); } - private static _getFileType(stat: IFileStat): FileType { - return (stat.isDirectory ? FileType.Directory : FileType.File) + (stat.isSymbolicLink ? FileType.SymbolicLink : 0); + private static _asFileType(stat: IFileStat): FileType { + let res = 0; + if (stat.isFile) { + res += FileType.File; + + } else if (stat.isDirectory) { + res += FileType.Directory; + } + if (stat.isSymbolicLink) { + res += FileType.SymbolicLink; + } + return res; } $readFile(uri: UriComponents): Promise { From 6f1d6c5c565d8f55dcd63fde245a37d6888f1eeb Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 12 Nov 2019 11:46:06 +0100 Subject: [PATCH 24/60] one more fix for #84201 --- extensions/git/src/git.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 6d54fb4db21b..7066ae2a9ffb 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1819,8 +1819,11 @@ export class Repository { } // Else, remove all lines starting with whitespace followed by `#`. - //TODO: Support core.commentChar - return message.replace(/^\s*#.*$\n?/gm, '').trim(); + // TODO: Support core.commentChar + return message.replace(/^(\s*#)(.*)$(\n?)/gm, (_, prefix, content, suffix) => { + // https://github.com/microsoft/vscode/issues/84201#issuecomment-552834814 + return /^\d+(\s|$)/.test(content) ? `${prefix}${content}${suffix}` : ''; + }).trim(); } async getMergeMessage(): Promise { From 4583277fbdafb01b1ccb537855fc130fb2d73847 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 12 Nov 2019 12:11:15 +0100 Subject: [PATCH 25/60] continuation of #84201 --- extensions/git/src/git.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 7066ae2a9ffb..a710a539c291 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1822,7 +1822,7 @@ export class Repository { // TODO: Support core.commentChar return message.replace(/^(\s*#)(.*)$(\n?)/gm, (_, prefix, content, suffix) => { // https://github.com/microsoft/vscode/issues/84201#issuecomment-552834814 - return /^\d+(\s|$)/.test(content) ? `${prefix}${content}${suffix}` : ''; + return /^\d/.test(content) ? `${prefix}${content}${suffix}` : ''; }).trim(); } From a1913036404fae80ba2eae76069499eb54f09476 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 12:12:27 +0100 Subject: [PATCH 26/60] fixes #84573 --- src/vs/workbench/contrib/debug/browser/callStackView.ts | 2 +- .../workbench/contrib/debug/browser/media/debugViewlet.css | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/callStackView.ts b/src/vs/workbench/contrib/debug/browser/callStackView.ts index 1706204f2eb7..df3cc5348631 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackView.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackView.ts @@ -800,7 +800,7 @@ class DisconnectAction extends Action { private readonly session: IDebugSession, @ICommandService private readonly commandService: ICommandService ) { - super(`action.${DISCONNECT_ID}`, DISCONNECT_LABEL, 'debug-action disconnect'); + super(`action.${DISCONNECT_ID}`, DISCONNECT_LABEL, 'debug-action codicon-debug-disconnect'); } public run(): Promise { diff --git a/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css b/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css index 8ce5999aea8d..9847a8b1d06a 100644 --- a/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css +++ b/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css @@ -140,9 +140,7 @@ text-transform: uppercase; } -.debug-viewlet .debug-call-stack .thread:hover > .state, -.debug-viewlet .debug-call-stack .session:hover > .state, -.debug-viewlet .debug-call-stack .monaco-list-row.focused .state { +.debug-viewlet .debug-call-stack .monaco-list-row:hover .state { display: none; } @@ -159,6 +157,7 @@ width: 16px; height: 100%; margin-right: 8px; + vertical-align: text-top; } .debug-viewlet .debug-call-stack .thread > .state > .label, @@ -240,7 +239,7 @@ overflow: hidden; } -.debug-viewlet .debug-call-stack .monaco-list:focus .monaco-list-row.selected.focused .codicon { +.debug-viewlet .debug-call-stack .monaco-list:focus .monaco-list-row.selected .codicon { color: inherit !important; } From 8013616a328d760a68a6cf84df7813e614beb418 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 12:20:59 +0100 Subject: [PATCH 27/60] debug: remove debugMisconfiuration --- .../contrib/debug/browser/debugService.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index 1eb19f2c61dd..031da0c11ab8 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -488,8 +488,6 @@ export class DebugService implements IDebugService { } const errorMessage = error instanceof Error ? error.message : error; - this.telemetryDebugMisconfiguration(session.configuration ? session.configuration.type : undefined, errorMessage); - await this.showError(errorMessage, isErrorWithActions(error) ? error.actions : []); return false; } @@ -1201,19 +1199,6 @@ export class DebugService implements IDebugService { }); } - private telemetryDebugMisconfiguration(debugType: string | undefined, message: string): Promise { - /* __GDPR__ - "debugMisconfiguration" : { - "type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, - "error": { "classification": "CallstackOrException", "purpose": "FeatureInsight" } - } - */ - return this.telemetryService.publicLog('debugMisconfiguration', { - type: debugType, - error: message - }); - } - private telemetryDebugAddBreakpoint(breakpoint: IBreakpoint, context: string): Promise { /* __GDPR__ "debugAddBreakpoint" : { From 7ade4e64605959633a22bd65c5acf7fdd3ff1e6e Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Tue, 12 Nov 2019 12:49:11 +0100 Subject: [PATCH 28/60] Fix #84584: Remove transform from codicons that causes them and the text in the same layer with them to be rendered using grayscale rendering --- src/vs/base/browser/ui/codiconLabel/codicon/codicon.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css b/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css index b01ce8e6e12a..b5327ffa4835 100644 --- a/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css +++ b/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css @@ -19,11 +19,6 @@ user-select: none; -webkit-user-select: none; -ms-user-select: none; - - /* Hack to get web rendering to align to pixel grid */ - transform: rotate(0); - -webkit-transform: rotate(0.1deg); - -moz-transform: rotate(0); } From 655e3b3e997cbe46f0da2b1e0a246809b50f42c4 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 12:53:51 +0100 Subject: [PATCH 29/60] fixes 83483 --- src/vs/workbench/contrib/files/browser/views/emptyView.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/files/browser/views/emptyView.ts b/src/vs/workbench/contrib/files/browser/views/emptyView.ts index f24f0128c6fc..7d9fbe1c0347 100644 --- a/src/vs/workbench/contrib/files/browser/views/emptyView.ts +++ b/src/vs/workbench/contrib/files/browser/views/emptyView.ts @@ -134,6 +134,10 @@ export class EmptyView extends ViewletPanel { // no-op } + focus(): void { + this.focusBody(); + } + focusBody(): void { if (this.button) { this.button.element.focus(); From 5f32c01db24732e852998d58c963cdbb3911d77a Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 13:01:29 +0100 Subject: [PATCH 30/60] fixes #83521 --- .../contrib/files/browser/fileActions.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 3460f9fb6bcd..cec21f34551a 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -471,7 +471,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, ({ id: DOWNLOAD_COMMAND_ID, title: DOWNLOAD_LABEL, }, - when: ContextKeyExpr.or(ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), IsWebContext.toNegated()), ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), ExplorerFolderContext.toNegated())) + when: ContextKeyExpr.or(ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), IsWebContext.toNegated()), ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated())) })); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { @@ -495,7 +495,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { id: ADD_ROOT_FOLDER_COMMAND_ID, title: ADD_ROOT_FOLDER_LABEL }, - when: ContextKeyExpr.and(ExplorerRootContext) + when: ExplorerRootContext }); MenuRegistry.appendMenuItem(MenuId.ExplorerContext, { From cd39e8e0a2e39e5c577953b3f95b1175415783f9 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Tue, 12 Nov 2019 13:55:15 +0100 Subject: [PATCH 31/60] Fixes #84565: Mark all editor layers as strictly contained (have the layers always pass the opacity check) --- src/vs/base/browser/fastDomNode.ts | 10 ++++++++++ src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts | 1 + src/vs/editor/browser/viewParts/lines/viewLines.ts | 1 + src/vs/editor/browser/viewParts/margin/margin.ts | 1 + src/vs/editor/browser/viewParts/minimap/minimap.ts | 1 + .../overviewRuler/decorationsOverviewRuler.ts | 1 + .../browser/viewParts/overviewRuler/overviewRuler.ts | 1 + 7 files changed, 16 insertions(+) diff --git a/src/vs/base/browser/fastDomNode.ts b/src/vs/base/browser/fastDomNode.ts index 6dfec19f492b..180eacdbd0ff 100644 --- a/src/vs/base/browser/fastDomNode.ts +++ b/src/vs/base/browser/fastDomNode.ts @@ -26,6 +26,7 @@ export class FastDomNode { private _position: string; private _visibility: string; private _layerHint: boolean; + private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'; constructor(domNode: T) { this.domNode = domNode; @@ -47,6 +48,7 @@ export class FastDomNode { this._position = ''; this._visibility = ''; this._layerHint = false; + this._contain = 'none'; } public setMaxWidth(maxWidth: number): void { @@ -206,6 +208,14 @@ export class FastDomNode { (this.domNode.style).willChange = this._layerHint ? 'transform' : 'auto'; } + public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void { + if (this._contain === contain) { + return; + } + this._contain = contain; + (this.domNode.style).contain = this._contain; + } + public setAttribute(name: string, value: string): void { this.domNode.setAttribute(name, value); } diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts index 4e9245ade07c..b1d48bc7cf82 100644 --- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts @@ -99,6 +99,7 @@ export abstract class AbstractScrollbar extends Widget { this.slider.setHeight(height); } this.slider.setLayerHinting(true); + this.slider.setContain('strict'); this.domNode.domNode.appendChild(this.slider.domNode); diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index 852d61259850..00b20578698f 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -544,6 +544,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, // (3) handle scrolling this._linesContent.setLayerHinting(this._canUseLayerHinting); + this._linesContent.setContain('strict'); const adjustedScrollTop = this._context.viewLayout.getCurrentScrollTop() - viewportData.bigNumbersDelta; this._linesContent.setTop(-adjustedScrollTop); this._linesContent.setLeft(-this._context.viewLayout.getCurrentScrollLeft()); diff --git a/src/vs/editor/browser/viewParts/margin/margin.ts b/src/vs/editor/browser/viewParts/margin/margin.ts index 1208e3c56c9a..8181e2f8aa80 100644 --- a/src/vs/editor/browser/viewParts/margin/margin.ts +++ b/src/vs/editor/browser/viewParts/margin/margin.ts @@ -78,6 +78,7 @@ export class Margin extends ViewPart { public render(ctx: RestrictedRenderingContext): void { this._domNode.setLayerHinting(this._canUseLayerHinting); + this._domNode.setContain('strict'); const adjustedScrollTop = ctx.scrollTop - ctx.bigNumbersDelta; this._domNode.setTop(-adjustedScrollTop); diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 5ff05c883588..8e50b1e0e2d0 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -503,6 +503,7 @@ export class Minimap extends ViewPart { this._slider.setPosition('absolute'); this._slider.setClassName('minimap-slider'); this._slider.setLayerHinting(true); + this._slider.setContain('strict'); this._domNode.appendChild(this._slider); this._sliderHorizontal = createFastDomNode(document.createElement('div')); diff --git a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts index a4e988745cbc..687b9985268b 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts @@ -215,6 +215,7 @@ export class DecorationsOverviewRuler extends ViewPart { this._domNode.setClassName('decorationsOverviewRuler'); this._domNode.setPosition('absolute'); this._domNode.setLayerHinting(true); + this._domNode.setContain('strict'); this._domNode.setAttribute('aria-hidden', 'true'); this._updateSettings(false); diff --git a/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts index 7b9ef090d2a5..b75ba0ae4223 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/overviewRuler.ts @@ -26,6 +26,7 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler { this._domNode.setClassName(cssClassName); this._domNode.setPosition('absolute'); this._domNode.setLayerHinting(true); + this._domNode.setContain('strict'); this._zoneManager = new OverviewZoneManager((lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber)); this._zoneManager.setDOMWidth(0); From 57ddcfd7923f8df0f5c6f09a0041e2dcab91142b Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 12 Nov 2019 14:40:07 +0100 Subject: [PATCH 32/60] Only update visibilities when visible (#84125) --- src/vs/workbench/browser/parts/quickinput/quickInput.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInput.ts b/src/vs/workbench/browser/parts/quickinput/quickInput.ts index 529f2a9c95f2..4b365e66ae14 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInput.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInput.ts @@ -702,11 +702,11 @@ class QuickPick extends QuickInput implements IQuickPi } protected update() { - this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true, message: !!this.validationMessage } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true, message: !!this.validationMessage, customButton: this.customButton, ok: this.ok }); - super.update(); if (!this.visible) { return; } + this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true, message: !!this.validationMessage } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true, message: !!this.validationMessage, customButton: this.customButton, ok: this.ok }); + super.update(); if (this.ui.inputBox.value !== this.value) { this.ui.inputBox.value = this.value; } @@ -860,11 +860,11 @@ class InputBox extends QuickInput implements IInputBox { } protected update() { - this.ui.setVisibilities({ title: !!this.title || !!this.step, inputBox: true, message: true }); - super.update(); if (!this.visible) { return; } + this.ui.setVisibilities({ title: !!this.title || !!this.step, inputBox: true, message: true }); + super.update(); if (this.ui.inputBox.value !== this.value) { this.ui.inputBox.value = this.value; } From 7a242cfc3eb7d9697dbfc0d171b61dd14f0676fd Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 12 Nov 2019 15:28:06 +0100 Subject: [PATCH 33/60] Simplify switch event for remote explorer --- src/vs/workbench/browser/parts/views/viewsViewlet.ts | 7 +++---- src/vs/workbench/contrib/remote/browser/remote.ts | 8 ++------ .../services/remote/common/remoteExplorerService.ts | 3 +-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/browser/parts/views/viewsViewlet.ts b/src/vs/workbench/browser/parts/views/viewsViewlet.ts index cf9681d52e0a..874677282dd2 100644 --- a/src/vs/workbench/browser/parts/views/viewsViewlet.ts +++ b/src/vs/workbench/browser/parts/views/viewsViewlet.ts @@ -23,7 +23,7 @@ import { DefaultPanelDndController } from 'vs/base/browser/ui/splitview/panelvie import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService'; import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Event } from 'vs/base/common/event'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { localize } from 'vs/nls'; @@ -330,10 +330,9 @@ export abstract class FilterViewContainerViewlet extends ViewContainerViewlet { private allViews: Map> = new Map(); private filterValue: string | undefined; - protected onDidChangeFilterValue: Emitter = new Emitter(); - constructor( viewletId: string, + onDidChangeFilterValue: Event, @IConfigurationService configurationService: IConfigurationService, @IWorkbenchLayoutService layoutService: IWorkbenchLayoutService, @ITelemetryService telemetryService: ITelemetryService, @@ -345,7 +344,7 @@ export abstract class FilterViewContainerViewlet extends ViewContainerViewlet { @IWorkspaceContextService contextService: IWorkspaceContextService ) { super(viewletId, `${viewletId}.state`, false, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); - this._register(this.onDidChangeFilterValue.event(newFilterValue => { + this._register(onDidChangeFilterValue(newFilterValue => { this.filterValue = newFilterValue; this.onFilterChanged(newFilterValue); })); diff --git a/src/vs/workbench/contrib/remote/browser/remote.ts b/src/vs/workbench/contrib/remote/browser/remote.ts index f87cdc9515a1..5a334ade8078 100644 --- a/src/vs/workbench/contrib/remote/browser/remote.ts +++ b/src/vs/workbench/contrib/remote/browser/remote.ts @@ -381,9 +381,9 @@ export class RemoteViewlet extends FilterViewContainerViewlet implements IViewMo @IThemeService themeService: IThemeService, @IContextMenuService contextMenuService: IContextMenuService, @IExtensionService extensionService: IExtensionService, - @IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService + @IRemoteExplorerService remoteExplorerService: IRemoteExplorerService ) { - super(VIEWLET_ID, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); + super(VIEWLET_ID, remoteExplorerService.onDidChangeTargetType, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService); this.addConstantViewDescriptors([this.helpPanelDescriptor]); remoteHelpExtPoint.setHandler((extensions) => { let helpInformation: HelpInformation[] = []; @@ -400,10 +400,6 @@ export class RemoteViewlet extends FilterViewContainerViewlet implements IViewMo viewsRegistry.deregisterViews([this.helpPanelDescriptor], VIEW_CONTAINER); } }); - - this._register(this.remoteExplorerService.onDidChangeTargetType(() => { - this.onDidChangeFilterValue.fire(this.remoteExplorerService.targetType); - })); } protected getFilterOn(viewDescriptor: IViewDescriptor): string | undefined { diff --git a/src/vs/workbench/services/remote/common/remoteExplorerService.ts b/src/vs/workbench/services/remote/common/remoteExplorerService.ts index 7e3d66db8f22..da27dccfb2e6 100644 --- a/src/vs/workbench/services/remote/common/remoteExplorerService.ts +++ b/src/vs/workbench/services/remote/common/remoteExplorerService.ts @@ -23,9 +23,8 @@ class RemoteExplorerService implements IRemoteExplorerService { set targetType(name: string) { if (this._targetType !== name) { - const oldTarget = this._targetType; this._targetType = name; - this._onDidChangeTargetType.fire(oldTarget); + this._onDidChangeTargetType.fire(this._targetType); } } get targetType(): string { From 72da3e4c35892369a55c187802f697c5c7a9b994 Mon Sep 17 00:00:00 2001 From: Vladislav Hadzhiyski Date: Tue, 12 Nov 2019 16:31:52 +0200 Subject: [PATCH 34/60] Fix #83940 (#84414) * Add custom "Open with" message to installer script Supported languages: de, en, es, fr, hu, it, pt-br, ru * Fix typo in build/win32/i18n/messages.en.isl Co-Authored-By: jaqra <48099350+jaqra@users.noreply.github.com> * Add tr translation for OpenWithCodeContextMenu * Update translations to be consistent with "AddContextMenuFiles" translation * Fix file encoding * Fix asian lang files * Add translations for Japanese & Chinese * Fix file endings * Remove newline at end of i18n files * Add OpenWith translations without changing the file encoding --- build/win32/code.iss | 4 ++-- build/win32/i18n/messages.de.isl | 3 ++- build/win32/i18n/messages.en.isl | 3 ++- build/win32/i18n/messages.es.isl | 3 ++- build/win32/i18n/messages.fr.isl | 3 ++- build/win32/i18n/messages.hu.isl | 3 ++- build/win32/i18n/messages.it.isl | 3 ++- build/win32/i18n/messages.ja.isl | 3 ++- build/win32/i18n/messages.ko.isl | 3 ++- build/win32/i18n/messages.pt-br.isl | 3 ++- build/win32/i18n/messages.ru.isl | 3 ++- build/win32/i18n/messages.tr.isl | 3 ++- build/win32/i18n/messages.zh-cn.isl | 3 ++- build/win32/i18n/messages.zh-tw.isl | 3 ++- 14 files changed, 28 insertions(+), 15 deletions(-) diff --git a/build/win32/code.iss b/build/win32/code.iss index ee70efb974d0..0e2ed70d64ac 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -957,10 +957,10 @@ Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBas Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico" Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1""" -Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open w&ith {#ShellNameShort}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey +Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu, {#ShellNameShort}}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufiles Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: addcontextmenufiles -Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open w&ith {#ShellNameShort}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey +Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu, {#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open w&ith {#ShellNameShort}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey diff --git a/build/win32/i18n/messages.de.isl b/build/win32/i18n/messages.de.isl index 755652bcdbe9..6a9f29aa9c27 100644 --- a/build/win32/i18n/messages.de.isl +++ b/build/win32/i18n/messages.de.isl @@ -5,4 +5,5 @@ AssociateWithFiles=%1 als Editor f AddToPath=Zu PATH hinzufügen (nach dem Neustart verfügbar) RunAfter=%1 nach der Installation ausführen Other=Andere: -SourceFile=%1-Quelldatei \ No newline at end of file +SourceFile=%1-Quelldatei +OpenWithCodeContextMenu=Mit %1 öffnen \ No newline at end of file diff --git a/build/win32/i18n/messages.en.isl b/build/win32/i18n/messages.en.isl index a6aab59b95a9..6535824eed67 100644 --- a/build/win32/i18n/messages.en.isl +++ b/build/win32/i18n/messages.en.isl @@ -5,4 +5,5 @@ AssociateWithFiles=Register %1 as an editor for supported file types AddToPath=Add to PATH (requires shell restart) RunAfter=Run %1 after installation Other=Other: -SourceFile=%1 Source File \ No newline at end of file +SourceFile=%1 Source File +OpenWithCodeContextMenu=Open with %1 \ No newline at end of file diff --git a/build/win32/i18n/messages.es.isl b/build/win32/i18n/messages.es.isl index e8d5af64b619..e51f099f9a13 100644 --- a/build/win32/i18n/messages.es.isl +++ b/build/win32/i18n/messages.es.isl @@ -5,4 +5,5 @@ AssociateWithFiles=Registrar %1 como editor para tipos de archivo admitidos AddToPath=Agregar a PATH (disponible después de reiniciar) RunAfter=Ejecutar %1 después de la instalación Other=Otros: -SourceFile=Archivo de origen %1 \ No newline at end of file +SourceFile=Archivo de origen %1 +OpenWithCodeContextMenu=Abrir con %1 \ No newline at end of file diff --git a/build/win32/i18n/messages.fr.isl b/build/win32/i18n/messages.fr.isl index 3e17036f8067..df1404186251 100644 --- a/build/win32/i18n/messages.fr.isl +++ b/build/win32/i18n/messages.fr.isl @@ -5,4 +5,5 @@ AssociateWithFiles=Inscrire %1 en tant qu' AddToPath=Ajouter à PATH (disponible après le redémarrage) RunAfter=Exécuter %1 après l'installation Other=Autre : -SourceFile=Fichier source %1 \ No newline at end of file +SourceFile=Fichier source %1 +OpenWithCodeContextMenu=Ouvrir avec %1 \ No newline at end of file diff --git a/build/win32/i18n/messages.hu.isl b/build/win32/i18n/messages.hu.isl index f141ad1b24ad..b64553da8e6d 100644 --- a/build/win32/i18n/messages.hu.isl +++ b/build/win32/i18n/messages.hu.isl @@ -5,4 +5,5 @@ AssociateWithFiles=%1 regisztr AddToPath=Hozzáadás a PATH-hoz (újraindítás után lesz elérhetõ) RunAfter=%1 indítása a telepítés után Other=Egyéb: -SourceFile=%1 forrásfájl \ No newline at end of file +SourceFile=%1 forrásfájl +OpenWithCodeContextMenu=Megnyitás a következõvel: %1 \ No newline at end of file diff --git a/build/win32/i18n/messages.it.isl b/build/win32/i18n/messages.it.isl index 7ad8a0622d45..08248c4ce1ba 100644 --- a/build/win32/i18n/messages.it.isl +++ b/build/win32/i18n/messages.it.isl @@ -5,4 +5,5 @@ AssociateWithFiles=Registra %1 come editor per i tipi di file supportati AddToPath=Aggiungi a PATH (disponibile dopo il riavvio) RunAfter=Esegui %1 dopo l'installazione Other=Altro: -SourceFile=File di origine %1 \ No newline at end of file +SourceFile=File di origine %1 +OpenWithCodeContextMenu=Apri con %1 \ No newline at end of file diff --git a/build/win32/i18n/messages.ja.isl b/build/win32/i18n/messages.ja.isl index 3a16aaa204e9..9675060e94af 100644 --- a/build/win32/i18n/messages.ja.isl +++ b/build/win32/i18n/messages.ja.isl @@ -5,4 +5,5 @@ AssociateWithFiles= AddToPath=PATH ‚ւ̒ljÁ�i�Ä‹N“®Œã‚ÉŽg—p‰Â”\�j RunAfter=ƒCƒ“ƒXƒg�[ƒ‹Œã‚É %1 ‚ðŽÀ�s‚·‚é Other=‚»‚Ì‘¼: -SourceFile=%1 ƒ\�[ƒX ƒtƒ@ƒCƒ‹ \ No newline at end of file +SourceFile=%1 ƒ\�[ƒX ƒtƒ@ƒCƒ‹ +OpenWithCodeContextMenu=%1 ‚ÅŠJ‚­ \ No newline at end of file diff --git a/build/win32/i18n/messages.ko.isl b/build/win32/i18n/messages.ko.isl index 28860c36b633..5a510558bbd2 100644 --- a/build/win32/i18n/messages.ko.isl +++ b/build/win32/i18n/messages.ko.isl @@ -5,4 +5,5 @@ AssociateWithFiles=%1 AddToPath=PATH¿¡ Ãß°¡(´Ù½Ã ½ÃÀÛÇÑ ÈÄ »ç¿ë °¡´É) RunAfter=¼³Ä¡ ÈÄ %1 ½ÇÇà Other=±âŸ: -SourceFile=%1 ¿øº» ÆÄÀÏ \ No newline at end of file +SourceFile=%1 ¿øº» ÆÄÀÏ +OpenWithCodeContextMenu=%1(À¸)·Î ¿­±â \ No newline at end of file diff --git a/build/win32/i18n/messages.pt-br.isl b/build/win32/i18n/messages.pt-br.isl index d534637f8b61..e327e8fd1a06 100644 --- a/build/win32/i18n/messages.pt-br.isl +++ b/build/win32/i18n/messages.pt-br.isl @@ -5,4 +5,5 @@ AssociateWithFiles=Registre %1 como um editor para tipos de arquivos suportados AddToPath=Adicione em PATH (disponível após reiniciar) RunAfter=Executar %1 após a instalação Other=Outros: -SourceFile=Arquivo Fonte %1 \ No newline at end of file +SourceFile=Arquivo Fonte %1 +OpenWithCodeContextMenu=Abrir com %1 \ No newline at end of file diff --git a/build/win32/i18n/messages.ru.isl b/build/win32/i18n/messages.ru.isl index 4d834663627e..bca3b864a5f9 100644 --- a/build/win32/i18n/messages.ru.isl +++ b/build/win32/i18n/messages.ru.isl @@ -5,4 +5,5 @@ AssociateWithFiles= AddToPath=Äîáàâèòü â PATH (äîñòóïíî ïîñëå ïåðåçàãðóçêè) RunAfter=Çàïóñòèòü %1 ïîñëå óñòàíîâêè Other=Äðóãîå: -SourceFile=Èñõîäíûé ôàéë %1 \ No newline at end of file +SourceFile=Èñõîäíûé ôàéë %1 +OpenWithCodeContextMenu=Îòêðûòü ñ ïîìîùüþ %1 \ No newline at end of file diff --git a/build/win32/i18n/messages.tr.isl b/build/win32/i18n/messages.tr.isl index dc241d924c7b..b13e5e27bd2a 100644 --- a/build/win32/i18n/messages.tr.isl +++ b/build/win32/i18n/messages.tr.isl @@ -5,4 +5,5 @@ AssociateWithFiles=%1 uygulamas AddToPath=PATH'e ekle (yeniden baþlattýktan sonra kullanýlabilir) RunAfter=Kurulumdan sonra %1 uygulamasýný çalýþtýr. Other=Diðer: -SourceFile=%1 Kaynak Dosyasý \ No newline at end of file +SourceFile=%1 Kaynak Dosyasý +OpenWithCodeContextMenu=%1 Ýle Aç \ No newline at end of file diff --git a/build/win32/i18n/messages.zh-cn.isl b/build/win32/i18n/messages.zh-cn.isl index 349fc2ccc29b..8fa136f6d5a9 100644 --- a/build/win32/i18n/messages.zh-cn.isl +++ b/build/win32/i18n/messages.zh-cn.isl @@ -5,4 +5,5 @@ AssociateWithFiles= AddToPath=Ìí¼Óµ½ PATH (ÖØÆôºóÉúЧ) RunAfter=°²×°ºóÔËÐÐ %1 Other=ÆäËû: -SourceFile=%1 Ô´Îļþ \ No newline at end of file +SourceFile=%1 Ô´Îļþ +OpenWithCodeContextMenu=ͨ¹ý %1 ´ò¿ª \ No newline at end of file diff --git a/build/win32/i18n/messages.zh-tw.isl b/build/win32/i18n/messages.zh-tw.isl index 7c3f84aa131f..40c5fa92d793 100644 --- a/build/win32/i18n/messages.zh-tw.isl +++ b/build/win32/i18n/messages.zh-tw.isl @@ -5,4 +5,5 @@ AssociateWithFiles= AddToPath=¥[¤J PATH ¤¤ (­«·s±Ò°Ê«á¥Í®Ä) RunAfter=¦w¸Ë«á°õ¦æ %1 Other=¨ä¥L: -SourceFile=%1 ¨Ó·½ÀÉ®× \ No newline at end of file +SourceFile=%1 ¨Ó·½ÀÉ®× +OpenWithCodeContextMenu=¥H %1 ¶}±Ò \ No newline at end of file From cf8d61ebd2f022f4ce8280171f0360d1fe0a206d Mon Sep 17 00:00:00 2001 From: Pine Wu Date: Tue, 12 Nov 2019 06:37:21 -0800 Subject: [PATCH 35/60] Fix #81943 --- extensions/scss/cgmanifest.json | 4 +- extensions/scss/syntaxes/scss.tmLanguage.json | 181 ++++++++++++++++-- 2 files changed, 167 insertions(+), 18 deletions(-) diff --git a/extensions/scss/cgmanifest.json b/extensions/scss/cgmanifest.json index 7d152d3d3f3a..12247769ce22 100644 --- a/extensions/scss/cgmanifest.json +++ b/extensions/scss/cgmanifest.json @@ -6,12 +6,12 @@ "git": { "name": "atom/language-sass", "repositoryUrl": "https://github.com/atom/language-sass", - "commitHash": "d01d29191ab323fb3cf8bde9df0429f8e07902ff" + "commitHash": "f52ab12f7f9346cc2568129d8c4419bd3d506b47" } }, "license": "MIT", "description": "The file syntaxes/scss.json was derived from the Atom package https://github.com/atom/language-sass which was originally converted from the TextMate bundle https://github.com/alexsancho/SASS.tmbundle.", - "version": "0.62.0" + "version": "0.62.1" } ], "version": 1 diff --git a/extensions/scss/syntaxes/scss.tmLanguage.json b/extensions/scss/syntaxes/scss.tmLanguage.json index 5add08181f65..21ed870a5cc3 100644 --- a/extensions/scss/syntaxes/scss.tmLanguage.json +++ b/extensions/scss/syntaxes/scss.tmLanguage.json @@ -4,13 +4,19 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/atom/language-sass/commit/d01d29191ab323fb3cf8bde9df0429f8e07902ff", + "version": "https://github.com/atom/language-sass/commit/f52ab12f7f9346cc2568129d8c4419bd3d506b47", "name": "SCSS", "scopeName": "source.css.scss", "patterns": [ { "include": "#variable_setting" }, + { + "include": "#at_rule_forward" + }, + { + "include": "#at_rule_use" + }, { "include": "#at_rule_include" }, @@ -239,6 +245,55 @@ } ] }, + "at_rule_forward": { + "begin": "\\s*((@)forward\\b)\\s*", + "captures": { + "1": { + "name": "keyword.control.at-rule.forward.scss" + }, + "2": { + "name": "punctuation.definition.keyword.scss" + } + }, + "end": "\\s*(?=;)", + "name": "meta.at-rule.forward.scss", + "patterns": [ + { + "match": "\\b(as|hide|show)\\b", + "name": "keyword.control.operator" + }, + { + "match": "\\b([\\w-]+)(\\*)", + "captures": { + "1": { + "name": "entity.other.attribute-name.module.scss" + }, + "2": { + "name": "punctuation.definition.wildcard.scss" + } + } + }, + { + "match": "\\b[\\w-]+\\b", + "name": "entity.name.function.scss" + }, + { + "include": "#variable" + }, + { + "include": "#string_single" + }, + { + "include": "#string_double" + }, + { + "include": "#comment_line" + }, + { + "include": "#comment_block" + } + ] + }, "at_rule_function": { "patterns": [ { @@ -336,12 +391,18 @@ "at_rule_include": { "patterns": [ { - "begin": "(?<=@include)\\s+([\\w-]+)\\s*(\\()", + "begin": "(?<=@include)\\s+(?:([\\w-]+)\\s*(\\.))?([\\w-]+)\\s*(\\()", "beginCaptures": { "1": { - "name": "entity.name.function.scss" + "name": "variable.scss" }, "2": { + "name": "punctuation.access.module.scss" + }, + "3": { + "name": "entity.name.function.scss" + }, + "4": { "name": "punctuation.definition.parameters.begin.bracket.round.scss" } }, @@ -359,12 +420,18 @@ ] }, { - "match": "(?<=@include)\\s+([\\w-]+)", + "match": "(?<=@include)\\s+(?:([\\w-]+)\\s*(\\.))?([\\w-]+)", "captures": { "0": { "name": "meta.at-rule.include.scss" }, "1": { + "name": "variable.scss" + }, + "2": { + "name": "punctuation.access.module.scss" + }, + "3": { "name": "entity.name.function.scss" } } @@ -794,6 +861,64 @@ } ] }, + "at_rule_use": { + "begin": "\\s*((@)use\\b)\\s*", + "captures": { + "1": { + "name": "keyword.control.at-rule.use.scss" + }, + "2": { + "name": "punctuation.definition.keyword.scss" + } + }, + "end": "\\s*(?=;)", + "name": "meta.at-rule.use.scss", + "patterns": [ + { + "match": "\\b(as|with)\\b", + "name": "keyword.control.operator" + }, + { + "match": "\\b[\\w-]+\\b", + "name": "variable.scss" + }, + { + "match": "\\*", + "name": "variable.language.expanded-namespace.scss" + }, + { + "include": "#string_single" + }, + { + "include": "#string_double" + }, + { + "include": "#comment_line" + }, + { + "include": "#comment_block" + }, + { + "begin": "\\(", + "beginCaptures": { + "0": { + "name": "punctuation.definition.parameters.begin.bracket.round.scss" + } + }, + "end": "\\)", + "endCaptures": { + "0": { + "name": "punctuation.definition.parameters.end.bracket.round.scss" + } + }, + "patterns": [ + { + "include": "#function_attributes" + } + ] + } + ] + }, "at_rule_warn": { "begin": "\\s*((@)(warn|debug|error)\\b)\\s*", "captures": { @@ -890,12 +1015,18 @@ "name": "keyword.other.default.scss" }, "constant_functions": { - "begin": "([\\w-]+)(\\()", + "begin": "(?:([\\w-]+)(\\.))?([\\w-]+)(\\()", "beginCaptures": { "1": { - "name": "support.function.misc.scss" + "name": "variable.scss" }, "2": { + "name": "punctuation.access.module.scss" + }, + "3": { + "name": "support.function.misc.scss" + }, + "4": { "name": "punctuation.section.function.scss" } }, @@ -1050,10 +1181,10 @@ "name": "variable.interpolation.scss", "patterns": [ { - "include": "#property_values" + "include": "#variable" }, { - "include": "#variable" + "include": "#property_values" } ] }, @@ -1118,10 +1249,10 @@ "include": "#map" }, { - "include": "#property_values" + "include": "#variable" }, { - "include": "#variable" + "include": "#property_values" } ] }, @@ -1326,7 +1457,7 @@ ] }, "selector_attribute": { - "match": "(?xi)\n(\\[)\n\\s*\n(\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+?\n)\n(?:\n \\s*([~|^$*]?=)\\s*\n (?:\n (\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n )\n |\n ((\")(.*?)(\"))\n |\n ((')(.*?)('))\n )\n)?\n\\s*\n(\\])", + "match": "(?xi)\n(\\[)\n\\s*\n(\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+?\n)\n(?:\n \\s*([~|^$*]?=)\\s*\n (?:\n (\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n )\n |\n ((\")(.*?)(\"))\n |\n ((')(.*?)('))\n )\n)?\n\\s*\n(\\])", "name": "meta.attribute-selector.scss", "captures": { "1": { @@ -1421,7 +1552,7 @@ } }, "selector_class": { - "match": "(?x)\n(\\.) # Valid class-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n | ; # - A semicolon\n)", + "match": "(?x)\n(\\.) # Valid class-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,\\#)\\[:{>+~|] # - Another selector\n | \\.[^$] # - Class selector, negating module variable\n | /\\* # - A block comment\n | ; # - A semicolon\n)", "name": "entity.other.attribute-name.class.css", "captures": { "1": { @@ -1449,7 +1580,7 @@ "name": "entity.name.tag.custom.scss" }, "selector_id": { - "match": "(?x)\n(\\#) # Valid id-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n)", + "match": "(?x)\n(\\#) # Valid id-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,\\#)\\[:{>+~|] # - Another selector\n | \\.[^$] # - Class selector, negating module variable\n | /\\* # - A block comment\n)", "name": "entity.other.attribute-name.id.css", "captures": { "1": { @@ -1473,7 +1604,7 @@ } }, "selector_placeholder": { - "match": "(?x)\n(%) # Valid placeholder-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= ; # - End of statement\n | $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n)", + "match": "(?x)\n(%) # Valid placeholder-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.\\$ # Possible start of interpolation module scope variable\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= ; # - End of statement\n | $ # - End of the line\n | [\\s,\\#)\\[:{>+~|] # - Another selector\n | \\.[^$] # - Class selector, negating module variable\n | /\\* # - A block comment\n)", "name": "entity.other.attribute-name.placeholder.css", "captures": { "1": { @@ -1723,8 +1854,26 @@ ] }, "variables": { - "match": "(\\$|\\-\\-)[A-Za-z0-9_-]+\\b", - "name": "variable.scss" + "patterns": [ + { + "match": "\\b([\\w-]+)(\\.)(\\$[\\w-]+)\\b", + "captures": { + "1": { + "name": "variable.scss" + }, + "2": { + "name": "punctuation.access.module.scss" + }, + "3": { + "name": "variable.scss" + } + } + }, + { + "match": "(\\$|\\-\\-)[A-Za-z0-9_-]+\\b", + "name": "variable.scss" + } + ] } } } \ No newline at end of file From dae6c27e334fa10b0c2bc88b384db5bbb9850db4 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 12 Nov 2019 15:38:04 +0100 Subject: [PATCH 36/60] always send exeExtensionRecommendations:alreadyInstalled --- .../browser/extensionTipsService.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index e7b3de3e4c10..722c6fb9e9d8 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -506,15 +506,6 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private async promptForImportantExeBasedExtension(): Promise { - const storageKey = 'extensionsAssistant/workspaceRecommendationsIgnore'; - const config = this.configurationService.getValue(ConfigurationKey); - - if (config.ignoreRecommendations - || config.showRecommendationsOnlyOnDemand - || this.storageService.getBoolean(storageKey, StorageScope.WORKSPACE, false)) { - return false; - } - let recommendationsToSuggest = Object.keys(this._importantExeBasedRecommendations); const installed = await this.extensionManagementService.getInstalled(ExtensionType.User); @@ -527,13 +518,23 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe "exeName": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ - this.telemetryService.publicLog('exeExtensionRecommendations:alreadyInstalled', { extensionId, exeName: tip.exeFriendlyName || basename(tip.windowsPath!) }); + this.telemetryService.publicLog('exeExtensionRecommendations:alreadyInstalled', { extensionId, exeName: basename(tip.windowsPath!) }); }); + if (recommendationsToSuggest.length === 0) { return false; } + const storageKey = 'extensionsAssistant/workspaceRecommendationsIgnore'; + const config = this.configurationService.getValue(ConfigurationKey); + + if (config.ignoreRecommendations + || config.showRecommendationsOnlyOnDemand + || this.storageService.getBoolean(storageKey, StorageScope.WORKSPACE, false)) { + return false; + } + recommendationsToSuggest = this.filterIgnoredOrNotAllowed(recommendationsToSuggest); if (recommendationsToSuggest.length === 0) { return false; From 12b7d0aafeaaa65e683e9289126bc75db2278c5c Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Tue, 12 Nov 2019 16:05:13 +0100 Subject: [PATCH 37/60] window.showOpenDialog throws "TypeError: Default path must be a string" with defaultUri = null. Fixes #84325 --- src/vs/workbench/api/browser/mainThreadDialogs.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDialogs.ts b/src/vs/workbench/api/browser/mainThreadDialogs.ts index b4e38d566987..94ab09b7eba1 100644 --- a/src/vs/workbench/api/browser/mainThreadDialogs.ts +++ b/src/vs/workbench/api/browser/mainThreadDialogs.ts @@ -33,11 +33,11 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape { private static _convertOpenOptions(options: MainThreadDialogOpenOptions): IOpenDialogOptions { const result: IOpenDialogOptions = { - openLabel: options.openLabel, + openLabel: options.openLabel || undefined, canSelectFiles: options.canSelectFiles || (!options.canSelectFiles && !options.canSelectFolders), canSelectFolders: options.canSelectFolders, canSelectMany: options.canSelectMany, - defaultUri: URI.revive(options.defaultUri) + defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined }; if (options.filters) { result.filters = []; @@ -48,8 +48,8 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape { private static _convertSaveOptions(options: MainThreadDialogSaveOptions): ISaveDialogOptions { const result: ISaveDialogOptions = { - defaultUri: URI.revive(options.defaultUri), - saveLabel: options.saveLabel + defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined, + saveLabel: options.saveLabel || undefined }; if (options.filters) { result.filters = []; From a660498d441806a1eb14bfd6f1fc92d1bc02d061 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 12 Nov 2019 16:13:52 +0100 Subject: [PATCH 38/60] Backup and restore last used remote for explorer --- .../remote/browser/explorerViewItems.ts | 36 +++++++++++-------- .../remote/common/remoteExplorerService.ts | 6 ++++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/explorerViewItems.ts b/src/vs/workbench/contrib/remote/browser/explorerViewItems.ts index f57014a69b5c..3cd6c869fca2 100644 --- a/src/vs/workbench/contrib/remote/browser/explorerViewItems.ts +++ b/src/vs/workbench/contrib/remote/browser/explorerViewItems.ts @@ -13,12 +13,13 @@ import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/c import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; import { selectBorder } from 'vs/platform/theme/common/colorRegistry'; -import { IRemoteExplorerService } from 'vs/workbench/services/remote/common/remoteExplorerService'; +import { IRemoteExplorerService, REMOTE_EXPLORER_TYPE_KEY } from 'vs/workbench/services/remote/common/remoteExplorerService'; import { ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox'; import { IViewDescriptor } from 'vs/workbench/common/views'; import { startsWith } from 'vs/base/common/strings'; import { isStringArray } from 'vs/base/common/types'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; export interface IRemoteSelectItem extends ISelectOptionItem { authority: string[]; @@ -34,7 +35,8 @@ export class SwitchRemoteViewItem extends SelectActionViewItem { @IThemeService private readonly themeService: IThemeService, @IContextViewService contextViewService: IContextViewService, @IRemoteExplorerService remoteExplorerService: IRemoteExplorerService, - @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @IStorageService private readonly storageService: IStorageService ) { super(null, action, optionsItems, 0, contextViewService, { ariaLabel: nls.localize('remotes', 'Switch Remote') }); this._register(attachSelectBoxStyler(this.selectBox, themeService, { @@ -45,26 +47,32 @@ export class SwitchRemoteViewItem extends SelectActionViewItem { } private setSelectionForConnection(optionsItems: IRemoteSelectItem[], environmentService: IWorkbenchEnvironmentService, remoteExplorerService: IRemoteExplorerService) { - // TODO: set from saved state if (this.optionsItems.length > 0) { - const remoteAuthority = environmentService.configuration.remoteAuthority; let index = 0; - if (remoteAuthority) { - const actualRemoteAuthority = remoteAuthority.split('+')[0]; - for (let optionIterator = 0; (optionIterator < this.optionsItems.length) && (index === 0); optionIterator++) { - for (let authorityIterator = 0; authorityIterator < optionsItems[optionIterator].authority.length; authorityIterator++) { - if (optionsItems[optionIterator].authority[authorityIterator] === actualRemoteAuthority) { - index = optionIterator; - break; - } - } - } + const remoteAuthority = environmentService.configuration.remoteAuthority; + const explorerType: string | undefined = remoteAuthority ? remoteAuthority.split('+')[0] : + this.storageService.get(REMOTE_EXPLORER_TYPE_KEY, StorageScope.WORKSPACE) ?? this.storageService.get(REMOTE_EXPLORER_TYPE_KEY, StorageScope.GLOBAL); + if (explorerType) { + index = this.getOptionIndexForExplorerType(optionsItems, explorerType); } this.select(index); remoteExplorerService.targetType = optionsItems[index].authority[0]; } } + private getOptionIndexForExplorerType(optionsItems: IRemoteSelectItem[], explorerType: string): number { + let index = 0; + for (let optionIterator = 0; (optionIterator < this.optionsItems.length) && (index === 0); optionIterator++) { + for (let authorityIterator = 0; authorityIterator < optionsItems[optionIterator].authority.length; authorityIterator++) { + if (optionsItems[optionIterator].authority[authorityIterator] === explorerType) { + index = optionIterator; + break; + } + } + } + return index; + } + render(container: HTMLElement) { super.render(container); dom.addClass(container, 'switch-remote'); diff --git a/src/vs/workbench/services/remote/common/remoteExplorerService.ts b/src/vs/workbench/services/remote/common/remoteExplorerService.ts index da27dccfb2e6..7aec6e576894 100644 --- a/src/vs/workbench/services/remote/common/remoteExplorerService.ts +++ b/src/vs/workbench/services/remote/common/remoteExplorerService.ts @@ -6,8 +6,10 @@ import { Event, Emitter } from 'vs/base/common/event'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; export const IRemoteExplorerService = createDecorator('remoteExplorerService'); +export const REMOTE_EXPLORER_TYPE_KEY: string = 'remote.explorerType'; export interface IRemoteExplorerService { _serviceBrand: undefined; @@ -21,9 +23,13 @@ class RemoteExplorerService implements IRemoteExplorerService { private _onDidChangeTargetType: Emitter = new Emitter(); public onDidChangeTargetType: Event = this._onDidChangeTargetType.event; + constructor(@IStorageService private readonly storageService: IStorageService) { } + set targetType(name: string) { if (this._targetType !== name) { this._targetType = name; + this.storageService.store(REMOTE_EXPLORER_TYPE_KEY, this._targetType, StorageScope.WORKSPACE); + this.storageService.store(REMOTE_EXPLORER_TYPE_KEY, this._targetType, StorageScope.GLOBAL); this._onDidChangeTargetType.fire(this._targetType); } } From e3114f4cbcd9aae70dac2538415c3fd1b8fdc576 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 16:51:33 +0100 Subject: [PATCH 39/60] introduce early version of working copy service Adopt it for untitled and text file models. Use it for indicating dirty count in explorer and document edited on macOS. --- .../common/editor/textEditorModel.ts | 2 + .../common/editor/untitledTextEditorModel.ts | 29 ++-- .../browser/editors/fileEditorTracker.ts | 30 +++- .../files/browser/files.contribution.ts | 6 +- .../files/browser/files.web.contribution.ts | 6 - .../files/common/dirtyFilesIndicator.ts | 70 ++++++++ .../contrib/files/common/dirtyFilesTracker.ts | 113 ------------ .../electron-browser/dirtyFilesTracker.ts | 81 --------- .../electron-browser/files.contribution.ts | 6 - .../browser/testCustomEditors.ts | 40 ++++- src/vs/workbench/electron-browser/window.ts | 30 +++- .../keybindingEditing.test.ts | 6 +- .../textfile/common/textFileEditorModel.ts | 37 +++- .../textfile/test/textFileEditorModel.test.ts | 75 +++++++- .../workingCopy/common/workingCopyService.ts | 161 ++++++++++++++++++ .../test/common/workingCopyService.test.ts | 144 ++++++++++++++++ .../common/editor/untitledTextEditor.test.ts | 29 +++- .../workbench/test/workbenchTestServices.ts | 6 + src/vs/workbench/workbench.common.main.ts | 1 + 19 files changed, 617 insertions(+), 255 deletions(-) create mode 100644 src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts delete mode 100644 src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts delete mode 100644 src/vs/workbench/contrib/files/electron-browser/dirtyFilesTracker.ts create mode 100644 src/vs/workbench/services/workingCopy/common/workingCopyService.ts create mode 100644 src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts diff --git a/src/vs/workbench/common/editor/textEditorModel.ts b/src/vs/workbench/common/editor/textEditorModel.ts index 9385d8e31e6a..e95e0d87bae9 100644 --- a/src/vs/workbench/common/editor/textEditorModel.ts +++ b/src/vs/workbench/common/editor/textEditorModel.ts @@ -17,7 +17,9 @@ import { withUndefinedAsNull } from 'vs/base/common/types'; * The base text editor model leverages the code editor model. This class is only intended to be subclassed and not instantiated. */ export abstract class BaseTextEditorModel extends EditorModel implements ITextEditorModel, IModeSupport { + protected textEditorModelHandle: URI | null = null; + private createdEditorModel: boolean | undefined; private readonly modelDisposeListener = this._register(new MutableDisposable()); diff --git a/src/vs/workbench/common/editor/untitledTextEditorModel.ts b/src/vs/workbench/common/editor/untitledTextEditorModel.ts index 917f7feeff10..7c47a00dfc9c 100644 --- a/src/vs/workbench/common/editor/untitledTextEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledTextEditorModel.ts @@ -16,8 +16,9 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res import { ITextBufferFactory } from 'vs/editor/common/model'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService'; +import { IWorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; -export class UntitledTextEditorModel extends BaseTextEditorModel implements IEncodingSupport { +export class UntitledTextEditorModel extends BaseTextEditorModel implements IEncodingSupport, IWorkingCopy { static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY; @@ -30,33 +31,33 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc private readonly _onDidChangeEncoding: Emitter = this._register(new Emitter()); readonly onDidChangeEncoding: Event = this._onDidChangeEncoding.event; - private dirty: boolean = false; - private versionId: number = 0; - private readonly contentChangeEventScheduler: RunOnceScheduler; + readonly capabilities = 0; + + private dirty = false; + private versionId = 0; + private readonly contentChangeEventScheduler = this._register(new RunOnceScheduler(() => this._onDidChangeContent.fire(), UntitledTextEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY)); private configuredEncoding?: string; constructor( private readonly preferredMode: string | undefined, - private readonly resource: URI, - private _hasAssociatedFilePath: boolean, + public readonly resource: URI, + public readonly hasAssociatedFilePath: boolean, private readonly initialValue: string | undefined, private preferredEncoding: string | undefined, @IModeService modeService: IModeService, @IModelService modelService: IModelService, @IBackupFileService private readonly backupFileService: IBackupFileService, - @ITextResourceConfigurationService private readonly configurationService: ITextResourceConfigurationService + @ITextResourceConfigurationService private readonly configurationService: ITextResourceConfigurationService, + @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService ) { super(modelService, modeService); - this.contentChangeEventScheduler = this._register(new RunOnceScheduler(() => this._onDidChangeContent.fire(), UntitledTextEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY)); + // Make known to working copy service + this._register(this.workingCopyService.registerWorkingCopy(this)); this.registerListeners(); } - get hasAssociatedFilePath(): boolean { - return this._hasAssociatedFilePath; - } - private registerListeners(): void { // Config Changes @@ -147,7 +148,7 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc } // untitled associated to file path are dirty right away as well as untitled with content - this.setDirty(this._hasAssociatedFilePath || !!backup || !!this.initialValue); + this.setDirty(this.hasAssociatedFilePath || !!backup || !!this.initialValue); let untitledContents: ITextBufferFactory; if (backup) { @@ -190,7 +191,7 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc // mark the untitled text editor as non-dirty once its content becomes empty and we do // not have an associated path set. we never want dirty indicator in that case. - if (!this._hasAssociatedFilePath && this.textEditorModel.getLineCount() === 1 && this.textEditorModel.getLineContent(1) === '') { + if (!this.hasAssociatedFilePath && this.textEditorModel.getLineCount() === 1 && this.textEditorModel.getLineContent(1) === '') { this.setDirty(false); } diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts index ddc030e106fc..271741351a97 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts @@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri'; import * as resources from 'vs/base/common/resources'; import { IEditorViewState } from 'vs/editor/common/editorCommon'; import { toResource, SideBySideEditorInput, IWorkbenchEditorConfiguration, SideBySideEditor as SideBySideEditorChoice } from 'vs/workbench/common/editor'; -import { ITextFileService, ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, ITextFileEditorModel, TextFileModelChangeEvent, ModelState } from 'vs/workbench/services/textfile/common/textfiles'; import { FileOperationEvent, FileOperation, IFileService, FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files'; import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; @@ -61,6 +61,9 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // Update editors from disk changes this._register(this.fileService.onFileChanges(e => this.onFileChanges(e))); + // Open editors from dirty text file models + this._register(this.textFileService.models.onModelsDirty(e => this.onTextFilesDirty(e))); + // Editor changing this._register(this.editorService.onDidVisibleEditorsChange(() => this.handleOutOfWorkspaceWatchers())); @@ -359,6 +362,31 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut }); } + private onTextFilesDirty(e: readonly TextFileModelChangeEvent[]): void { + + // If files become dirty but are not opened, we open it in the background unless there are pending to be saved + this.doOpenDirtyResources(distinct(e.filter(e => { + + // Only dirty models that are not PENDING_SAVE + const model = this.textFileService.models.get(e.resource); + const shouldOpen = model?.isDirty() && !model.hasState(ModelState.PENDING_SAVE); + + // Only if not open already + return shouldOpen && !this.editorService.isOpen({ resource: e.resource }); + }).map(e => e.resource), r => r.toString())); + } + + private doOpenDirtyResources(resources: URI[]): void { + + // Open + this.editorService.openEditors(resources.map(resource => { + return { + resource, + options: { inactive: true, pinned: true, preserveFocus: true } + }; + })); + } + dispose(): void { super.dispose(); diff --git a/src/vs/workbench/contrib/files/browser/files.contribution.ts b/src/vs/workbench/contrib/files/browser/files.contribution.ts index 25f5a95c4e31..226a42e22c79 100644 --- a/src/vs/workbench/contrib/files/browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.contribution.ts @@ -38,6 +38,7 @@ import { ExplorerService } from 'vs/workbench/contrib/files/common/explorerServi import { SUPPORTED_ENCODINGS } from 'vs/workbench/services/textfile/common/textfiles'; import { Schemas } from 'vs/base/common/network'; import { WorkspaceWatcher } from 'vs/workbench/contrib/files/common/workspaceWatcher'; +import { DirtyFilesIndicator } from 'vs/workbench/contrib/files/common/dirtyFilesIndicator'; // Viewlet Action export class OpenExplorerViewletAction extends ShowViewletAction { @@ -170,9 +171,12 @@ Registry.as(WorkbenchExtensions.Workbench).regi // Register uri display for file uris Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(FileUriLabelContribution, LifecyclePhase.Starting); -// Workspace Watcher +// Register Workspace Watcher Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkspaceWatcher, LifecyclePhase.Restored); +// Register Dirty Files Indicator +Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DirtyFilesIndicator, LifecyclePhase.Starting); + // Configuration const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration); diff --git a/src/vs/workbench/contrib/files/browser/files.web.contribution.ts b/src/vs/workbench/contrib/files/browser/files.web.contribution.ts index 0a28e1afb600..44d91d66b91c 100644 --- a/src/vs/workbench/contrib/files/browser/files.web.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/files.web.contribution.ts @@ -10,9 +10,6 @@ import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileE import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { TextFileEditor } from 'vs/workbench/contrib/files/browser/editors/textFileEditor'; -import { DirtyFilesTracker } from 'vs/workbench/contrib/files/common/dirtyFilesTracker'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; // Register file editor Registry.as(EditorExtensions.Editors).registerEditor( @@ -25,6 +22,3 @@ Registry.as(EditorExtensions.Editors).registerEditor( new SyncDescriptor(FileEditorInput) ] ); - -// Register Dirty Files Tracker -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(DirtyFilesTracker, LifecyclePhase.Starting); diff --git a/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts new file mode 100644 index 000000000000..515a11480ba2 --- /dev/null +++ b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as nls from 'vs/nls'; +import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; +import { VIEWLET_ID } from 'vs/workbench/contrib/files/common/files'; +import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; +import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; +import { IWorkingCopyService, IWorkingCopy, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; + +export class DirtyFilesIndicator extends Disposable implements IWorkbenchContribution { + private readonly badgeHandle = this._register(new MutableDisposable()); + + private lastKnownDirtyCount: number | undefined; + + private get hasDirtyCount(): boolean { + return typeof this.lastKnownDirtyCount === 'number' && this.lastKnownDirtyCount > 0; + } + + constructor( + @ITextFileService private readonly textFileService: ITextFileService, + @ILifecycleService private readonly lifecycleService: ILifecycleService, + @IActivityService private readonly activityService: IActivityService, + @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService + ) { + super(); + + this.registerListeners(); + } + + private registerListeners(): void { + + // Working copy dirty indicator + this._register(this.workingCopyService.onDidChangeDirty(c => this.onWorkingCopyDidChangeDirty(c))); + + // Lifecycle + this.lifecycleService.onShutdown(this.dispose, this); + } + + private onWorkingCopyDidChangeDirty(copy: IWorkingCopy): void { + if (!!(copy.capabilities & WorkingCopyCapabilities.AutoSave) && this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + return; // do not indicate changes to working copies that are auto saved after short delay + } + + const gotDirty = copy.isDirty(); + if (gotDirty || this.hasDirtyCount) { + this.updateActivityBadge(); + } + } + + private updateActivityBadge(): void { + const dirtyCount = this.workingCopyService.dirtyCount; + this.lastKnownDirtyCount = dirtyCount; + + // Indicate dirty count in badge if any + if (dirtyCount > 0) { + this.badgeHandle.value = this.activityService.showActivity( + VIEWLET_ID, + new NumberBadge(dirtyCount, num => num === 1 ? nls.localize('dirtyFile', "1 unsaved file") : nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), + 'explorer-viewlet-label' + ); + } else { + this.badgeHandle.clear(); + } + } +} diff --git a/src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts b/src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts deleted file mode 100644 index 6d070bd03e4e..000000000000 --- a/src/vs/workbench/contrib/files/common/dirtyFilesTracker.ts +++ /dev/null @@ -1,113 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as nls from 'vs/nls'; -import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { VIEWLET_ID } from 'vs/workbench/contrib/files/common/files'; -import { TextFileModelChangeEvent, ITextFileService, AutoSaveMode, ModelState } from 'vs/workbench/services/textfile/common/textfiles'; -import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; -import { URI } from 'vs/base/common/uri'; -import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; -import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; -import * as arrays from 'vs/base/common/arrays'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; - -export class DirtyFilesTracker extends Disposable implements IWorkbenchContribution { - private lastKnownDirtyCount: number | undefined; - private readonly badgeHandle = this._register(new MutableDisposable()); - - constructor( - @ITextFileService protected readonly textFileService: ITextFileService, - @ILifecycleService private readonly lifecycleService: ILifecycleService, - @IEditorService private readonly editorService: IEditorService, - @IActivityService private readonly activityService: IActivityService, - @IUntitledTextEditorService protected readonly untitledTextEditorService: IUntitledTextEditorService - ) { - super(); - - this.registerListeners(); - } - - private registerListeners(): void { - - // Local text file changes - this._register(this.untitledTextEditorService.onDidChangeDirty(e => this.onUntitledDidChangeDirty(e))); - this._register(this.textFileService.models.onModelsDirty(e => this.onTextFilesDirty(e))); - this._register(this.textFileService.models.onModelsSaved(e => this.onTextFilesSaved(e))); - this._register(this.textFileService.models.onModelsSaveError(e => this.onTextFilesSaveError(e))); - this._register(this.textFileService.models.onModelsReverted(e => this.onTextFilesReverted(e))); - - // Lifecycle - this.lifecycleService.onShutdown(this.dispose, this); - } - - private get hasDirtyCount(): boolean { - return typeof this.lastKnownDirtyCount === 'number' && this.lastKnownDirtyCount > 0; - } - - protected onUntitledDidChangeDirty(resource: URI): void { - const gotDirty = this.untitledTextEditorService.isDirty(resource); - - if (gotDirty || this.hasDirtyCount) { - this.updateActivityBadge(); - } - } - - protected onTextFilesDirty(e: readonly TextFileModelChangeEvent[]): void { - if (this.textFileService.getAutoSaveMode() !== AutoSaveMode.AFTER_SHORT_DELAY) { - this.updateActivityBadge(); // no indication needed when auto save is enabled for short delay - } - - // If files become dirty but are not opened, we open it in the background unless there are pending to be saved - this.doOpenDirtyResources(arrays.distinct(e.filter(e => { - - // Only dirty models that are not PENDING_SAVE - const model = this.textFileService.models.get(e.resource); - const shouldOpen = model?.isDirty() && !model.hasState(ModelState.PENDING_SAVE); - - // Only if not open already - return shouldOpen && !this.editorService.isOpen({ resource: e.resource }); - }).map(e => e.resource), r => r.toString())); - } - - private doOpenDirtyResources(resources: URI[]): void { - - // Open - this.editorService.openEditors(resources.map(resource => { - return { - resource, - options: { inactive: true, pinned: true, preserveFocus: true } - }; - })); - } - - protected onTextFilesSaved(e: readonly TextFileModelChangeEvent[]): void { - if (this.hasDirtyCount) { - this.updateActivityBadge(); - } - } - - protected onTextFilesSaveError(e: readonly TextFileModelChangeEvent[]): void { - this.updateActivityBadge(); - } - - protected onTextFilesReverted(e: readonly TextFileModelChangeEvent[]): void { - if (this.hasDirtyCount) { - this.updateActivityBadge(); - } - } - - private updateActivityBadge(): void { - const dirtyCount = this.textFileService.getDirty().length; - this.lastKnownDirtyCount = dirtyCount; - - this.badgeHandle.clear(); - - if (dirtyCount > 0) { - this.badgeHandle.value = this.activityService.showActivity(VIEWLET_ID, new NumberBadge(dirtyCount, num => num === 1 ? nls.localize('dirtyFile', "1 unsaved file") : nls.localize('dirtyFiles', "{0} unsaved files", dirtyCount)), 'explorer-viewlet-label'); - } - } -} diff --git a/src/vs/workbench/contrib/files/electron-browser/dirtyFilesTracker.ts b/src/vs/workbench/contrib/files/electron-browser/dirtyFilesTracker.ts deleted file mode 100644 index 6f85e8d1bdce..000000000000 --- a/src/vs/workbench/contrib/files/electron-browser/dirtyFilesTracker.ts +++ /dev/null @@ -1,81 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextFileModelChangeEvent, ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; -import { platform, Platform } from 'vs/base/common/platform'; -import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; -import { URI } from 'vs/base/common/uri'; -import { IActivityService } from 'vs/workbench/services/activity/common/activity'; -import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; -import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; -import { DirtyFilesTracker } from 'vs/workbench/contrib/files/common/dirtyFilesTracker'; -import { IElectronService } from 'vs/platform/electron/node/electron'; - -export class NativeDirtyFilesTracker extends DirtyFilesTracker { - private isDocumentedEdited: boolean; - - constructor( - @ITextFileService protected readonly textFileService: ITextFileService, - @ILifecycleService lifecycleService: ILifecycleService, - @IEditorService editorService: IEditorService, - @IActivityService activityService: IActivityService, - @IUntitledTextEditorService protected readonly untitledTextEditorService: IUntitledTextEditorService, - @IElectronService private readonly electronService: IElectronService - ) { - super(textFileService, lifecycleService, editorService, activityService, untitledTextEditorService); - - this.isDocumentedEdited = false; - } - - protected onUntitledDidChangeDirty(resource: URI): void { - const gotDirty = this.untitledTextEditorService.isDirty(resource); - if ((!this.isDocumentedEdited && gotDirty) || (this.isDocumentedEdited && !gotDirty)) { - this.updateDocumentEdited(); - } - - super.onUntitledDidChangeDirty(resource); - } - - protected onTextFilesDirty(e: readonly TextFileModelChangeEvent[]): void { - if ((this.textFileService.getAutoSaveMode() !== AutoSaveMode.AFTER_SHORT_DELAY) && !this.isDocumentedEdited) { - this.updateDocumentEdited(); // no indication needed when auto save is enabled for short delay - } - - super.onTextFilesDirty(e); - } - - protected onTextFilesSaved(e: readonly TextFileModelChangeEvent[]): void { - if (this.isDocumentedEdited) { - this.updateDocumentEdited(); - } - - super.onTextFilesSaved(e); - } - - protected onTextFilesSaveError(e: readonly TextFileModelChangeEvent[]): void { - if (!this.isDocumentedEdited) { - this.updateDocumentEdited(); - } - - super.onTextFilesSaveError(e); - } - - protected onTextFilesReverted(e: readonly TextFileModelChangeEvent[]): void { - if (this.isDocumentedEdited) { - this.updateDocumentEdited(); - } - - super.onTextFilesReverted(e); - } - - private updateDocumentEdited(): void { - if (platform === Platform.Mac) { - const hasDirtyFiles = this.textFileService.isDirty(); - this.isDocumentedEdited = hasDirtyFiles; - - this.electronService.setDocumentEdited(hasDirtyFiles); - } - } -} diff --git a/src/vs/workbench/contrib/files/electron-browser/files.contribution.ts b/src/vs/workbench/contrib/files/electron-browser/files.contribution.ts index 03a2fa2f4219..d5d18ac24ea8 100644 --- a/src/vs/workbench/contrib/files/electron-browser/files.contribution.ts +++ b/src/vs/workbench/contrib/files/electron-browser/files.contribution.ts @@ -10,9 +10,6 @@ import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileE import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { IEditorRegistry, EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/editor'; import { NativeTextFileEditor } from 'vs/workbench/contrib/files/electron-browser/textFileEditor'; -import { NativeDirtyFilesTracker } from 'vs/workbench/contrib/files/electron-browser/dirtyFilesTracker'; -import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; -import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; // Register file editor Registry.as(EditorExtensions.Editors).registerEditor( @@ -25,6 +22,3 @@ Registry.as(EditorExtensions.Editors).registerEditor( new SyncDescriptor(FileEditorInput) ] ); - -// Register Dirty Files Tracker -Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(NativeDirtyFilesTracker, LifecyclePhase.Starting); diff --git a/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts b/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts index 6f25031e1dbd..6a038352e2d6 100644 --- a/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts +++ b/src/vs/workbench/contrib/testCustomEditors/browser/testCustomEditors.ts @@ -24,7 +24,9 @@ import { isEqual } from 'vs/base/common/resources'; import { generateUuid } from 'vs/base/common/uuid'; import { CancellationToken } from 'vs/base/common/cancellation'; import { editorBackground, editorForeground } from 'vs/platform/theme/common/colorRegistry'; +import { IWorkingCopy, IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +const CUSTOM_SCHEME = 'testCustomEditor'; const ENABLE = false; class TestCustomEditorsAction extends Action { @@ -35,13 +37,15 @@ class TestCustomEditorsAction extends Action { constructor( id: string, label: string, - @IEditorService private readonly editorService: IEditorService + @IEditorService private readonly editorService: IEditorService, + @IInstantiationService private readonly instantiationService: IInstantiationService ) { super(id, label); } async run(): Promise { - await this.editorService.openEditor(new TestCustomEditorInput(URI.parse(`testCustomEditor:/${generateUuid()}`))); + const input = this.instantiationService.createInstance(TestCustomEditorInput, URI.parse(`${CUSTOM_SCHEME}:/${generateUuid()}`)); + await this.editorService.openEditor(input); return true; } @@ -111,12 +115,17 @@ class TestCustomEditor extends BaseEditor { layout(dimension: Dimension): void { } } -class TestCustomEditorInput extends EditorInput { +class TestCustomEditorInput extends EditorInput implements IWorkingCopy { private model: TestCustomEditorModel | undefined = undefined; + private dirty = false; - constructor(public readonly resource: URI) { + readonly capabilities = 0; + + constructor(public readonly resource: URI, @IWorkingCopyService workingCopyService: IWorkingCopyService) { super(); + + this._register(workingCopyService.registerWorkingCopy(this)); } getResource(): URI { @@ -128,7 +137,7 @@ class TestCustomEditorInput extends EditorInput { } getName(): string { - return `Custom Editor: ${this.resource.toString()}`; + return this.resource.toString(); } setValue(value: string) { @@ -139,9 +148,11 @@ class TestCustomEditorInput extends EditorInput { this.setDirty(value.length > 0); } - setDirty(dirty: boolean) { - this.dirty = dirty; - this._onDidChangeDirty.fire(); + private setDirty(dirty: boolean) { + if (this.dirty !== dirty) { + this.dirty = dirty; + this._onDidChangeDirty.fire(); + } } isDirty(): boolean { @@ -176,6 +187,17 @@ class TestCustomEditorInput extends EditorInput { matches(other: EditorInput) { return other instanceof TestCustomEditorInput && isEqual(other.resource, this.resource); } + + dispose(): void { + this.setDirty(false); + + if (this.model) { + this.model.dispose(); + this.model = undefined; + } + + super.dispose(); + } } class TestCustomEditorModel extends EditorModel { @@ -212,7 +234,7 @@ if (ENABLE) { } deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): TestCustomEditorInput { - return new TestCustomEditorInput(URI.parse(JSON.parse(serializedEditorInput).resource)); + return instantiationService.createInstance(TestCustomEditorInput, URI.parse(JSON.parse(serializedEditorInput).resource)); } } diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index 9f58a3e46012..d7f2c37ac7fb 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -60,6 +60,7 @@ import { ITunnelService, extractLocalHostUriMetaDataForPortMapping } from 'vs/pl import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IElectronEnvironmentService } from 'vs/workbench/services/electron/electron-browser/electronEnvironmentService'; +import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export class ElectronWindow extends Disposable { @@ -67,14 +68,16 @@ export class ElectronWindow extends Disposable { private readonly touchBarDisposables = this._register(new DisposableStore()); private lastInstalledTouchedBar: ICommandAction[][] | undefined; - private customTitleContextMenuDisposable = this._register(new DisposableStore()); + private readonly customTitleContextMenuDisposable = this._register(new DisposableStore()); private previousConfiguredZoomLevel: number | undefined; - private addFoldersScheduler: RunOnceScheduler; - private pendingFoldersToAdd: URI[]; + private readonly addFoldersScheduler = this._register(new RunOnceScheduler(() => this.doAddFolders(), 100)); + private pendingFoldersToAdd: URI[] = []; - private closeEmptyWindowScheduler: RunOnceScheduler = this._register(new RunOnceScheduler(() => this.onAllEditorsClosed(), 50)); + private readonly closeEmptyWindowScheduler: RunOnceScheduler = this._register(new RunOnceScheduler(() => this.onAllEditorsClosed(), 50)); + + private isDocumentedEdited = false; constructor( @IEditorService private readonly editorService: EditorServiceImpl, @@ -99,13 +102,11 @@ export class ElectronWindow extends Disposable { @IElectronService private readonly electronService: IElectronService, @ITunnelService private readonly tunnelService: ITunnelService, @IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService, - @IElectronEnvironmentService private readonly electronEnvironmentService: IElectronEnvironmentService + @IElectronEnvironmentService private readonly electronEnvironmentService: IElectronEnvironmentService, + @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService ) { super(); - this.pendingFoldersToAdd = []; - this.addFoldersScheduler = this._register(new RunOnceScheduler(() => this.doAddFolders(), 100)); - this.registerListeners(); this.create(); } @@ -261,6 +262,19 @@ export class ElectronWindow extends Disposable { this.electronService.handleTitleDoubleClick(); })); } + + // Document edited (macOS only): indicate for dirty working copies + if (isMacintosh) { + this._register(this.workingCopyService.onDidChangeDirty(workingCopy => { + const gotDirty = workingCopy.isDirty(); + if ((!this.isDocumentedEdited && gotDirty) || (this.isDocumentedEdited && !gotDirty)) { + const hasDirtyFiles = this.workingCopyService.hasDirty; + this.isDocumentedEdited = hasDirtyFiles; + + this.electronService.setDocumentEdited(hasDirtyFiles); + } + })); + } } private onDidVisibleEditorsChange(): void { diff --git a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts index d4be17512c0f..26baa78b0abe 100644 --- a/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts +++ b/src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts @@ -39,7 +39,7 @@ import { KeybindingsEditingService } from 'vs/workbench/services/keybinding/comm import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { TextModelResolverService } from 'vs/workbench/services/textmodelResolver/common/textModelResolverService'; import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; -import { TestBackupFileService, TestContextService, TestEditorGroupsService, TestEditorService, TestLifecycleService, TestTextFileService, TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices'; +import { TestBackupFileService, TestContextService, TestEditorGroupsService, TestEditorService, TestLifecycleService, TestTextFileService, TestTextResourcePropertiesService, TestWorkingCopyService } from 'vs/workbench/test/workbenchTestServices'; import { FileService } from 'vs/platform/files/common/fileService'; import { Schemas } from 'vs/base/common/network'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; @@ -49,6 +49,7 @@ import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv'; import { NativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService'; import { IWindowConfiguration } from 'vs/platform/windows/common/windows'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; class TestEnvironmentService extends NativeWorkbenchEnvironmentService { @@ -67,7 +68,7 @@ interface Modifiers { shiftKey?: boolean; } -suite('KeybindingsEditing', () => { +suite.skip('KeybindingsEditing', () => { let instantiationService: TestInstantiationService; let testObject: KeybindingsEditingService; @@ -93,6 +94,7 @@ suite('KeybindingsEditing', () => { instantiationService.stub(IContextKeyService, instantiationService.createInstance(MockContextKeyService)); instantiationService.stub(IEditorGroupsService, new TestEditorGroupsService()); instantiationService.stub(IEditorService, new TestEditorService()); + instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService()); instantiationService.stub(ITelemetryService, NullTelemetryService); instantiationService.stub(IModeService, ModeServiceImpl); instantiationService.stub(ILogService, new NullLogService()); diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 8618b539f5a3..ee2501f8854f 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { Event, Emitter } from 'vs/base/common/event'; +import { Emitter } from 'vs/base/common/event'; import { guessMimeTypes } from 'vs/base/common/mime'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { URI } from 'vs/base/common/uri'; @@ -29,6 +29,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { isEqual, isEqualOrParent, extname, basename, joinPath } from 'vs/base/common/resources'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Schemas } from 'vs/base/common/network'; +import { IWorkingCopyService, IWorkingCopy, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export interface IBackupMetaData { mtime: number; @@ -57,7 +58,7 @@ type TelemetryData = { /** * The text file editor model listens to changes to its underlying code editor model and saves these changes through the file service back to the disk. */ -export class TextFileEditorModel extends BaseTextEditorModel implements ITextFileEditorModel { +export class TextFileEditorModel extends BaseTextEditorModel implements ITextFileEditorModel, IWorkingCopy { static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY; static DEFAULT_ORPHANED_CHANGE_BUFFER_DELAY = 100; @@ -70,11 +71,16 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil private static saveParticipant: ISaveParticipant | null; static setSaveParticipant(handler: ISaveParticipant | null): void { TextFileEditorModel.saveParticipant = handler; } - private readonly _onDidContentChange: Emitter = this._register(new Emitter()); - readonly onDidContentChange: Event = this._onDidContentChange.event; + private readonly _onDidContentChange = this._register(new Emitter()); + readonly onDidContentChange = this._onDidContentChange.event; - private readonly _onDidStateChange: Emitter = this._register(new Emitter()); - readonly onDidStateChange: Event = this._onDidStateChange.event; + private readonly _onDidStateChange = this._register(new Emitter()); + readonly onDidStateChange = this._onDidStateChange.event; + + private readonly _onDidChangeDirty = this._register(new Emitter()); + readonly onDidChangeDirty = this._onDidChangeDirty.event; + + readonly capabilities = WorkingCopyCapabilities.AutoSave; private contentEncoding: string | undefined; // encoding as reported from disk @@ -101,7 +107,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil private disposed = false; constructor( - private readonly resource: URI, + public readonly resource: URI, private preferredEncoding: string | undefined, // encoding as chosen by the user private preferredMode: string | undefined, // mode as chosen by the user @INotificationService private readonly notificationService: INotificationService, @@ -114,12 +120,16 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil @IBackupFileService private readonly backupFileService: IBackupFileService, @IEnvironmentService private readonly environmentService: IEnvironmentService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, - @ILogService private readonly logService: ILogService + @ILogService private readonly logService: ILogService, + @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService ) { super(modelService, modeService); this.updateAutoSaveConfiguration(textFileService.getAutoSaveConfiguration()); + // Make known to working copy service + this._register(this.workingCopyService.registerWorkingCopy(this)); + this.registerListeners(); } @@ -249,6 +259,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil this.autoSaveDisposable.clear(); // Unset flags + const wasDirty = this.dirty; const undo = this.setDirty(false); // Force read from disk unless reverting soft @@ -266,6 +277,11 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Emit file change event this._onDidStateChange.fire(StateChange.REVERTED); + + // Emit dirty change event + if (wasDirty) { + this._onDidChangeDirty.fire(); + } } async load(options?: ILoadOptions): Promise { @@ -528,6 +544,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Emit event if (wasDirty) { this._onDidStateChange.fire(StateChange.REVERTED); + this._onDidChangeDirty.fire(); } return; @@ -568,6 +585,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Emit as Event if we turned dirty if (!wasDirty) { this._onDidStateChange.fire(StateChange.DIRTY); + this._onDidChangeDirty.fire(); } } @@ -739,8 +757,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil // Cancel any content change event promises as they are no longer valid this.contentChangeEventScheduler.cancel(); - // Emit File Saved Event + // Emit Events this._onDidStateChange.fire(StateChange.SAVED); + this._onDidChangeDirty.fire(); // Telemetry const settingsType = this.getTypeIfSettings(); diff --git a/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts b/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts index 07c3271fa955..dbddfc86a401 100644 --- a/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts @@ -16,9 +16,15 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { timeout } from 'vs/base/common/async'; import { ModesRegistry } from 'vs/editor/common/modes/modesRegistry'; import { assertIsDefined } from 'vs/base/common/types'; +import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; class ServiceAccessor { - constructor(@ITextFileService public textFileService: TestTextFileService, @IModelService public modelService: IModelService, @IFileService public fileService: TestFileService) { + constructor( + @ITextFileService public readonly textFileService: TestTextFileService, + @IModelService public readonly modelService: IModelService, + @IFileService public readonly fileService: TestFileService, + @IWorkingCopyService public readonly workingCopyService: IWorkingCopyService + ) { } } @@ -51,10 +57,15 @@ suite('Files - TextFileEditorModel', () => { await model.load(); + assert.equal(accessor.workingCopyService.dirtyCount, 0); + model.textEditorModel!.setValue('bar'); assert.ok(getLastModifiedTime(model) <= Date.now()); assert.ok(model.hasState(ModelState.DIRTY)); + assert.equal(accessor.workingCopyService.dirtyCount, 1); + assert.equal(accessor.workingCopyService.isDirty(model.resource), true); + let savedEvent = false; model.onDidStateChange(e => { if (e === StateChange.SAVED) { @@ -62,6 +73,13 @@ suite('Files - TextFileEditorModel', () => { } }); + let workingCopyEvent = false; + accessor.workingCopyService.onDidChangeDirty(e => { + if (e.resource.toString() === model.resource.toString()) { + workingCopyEvent = true; + } + }); + const pendingSave = model.save(); assert.ok(model.hasState(ModelState.PENDING_SAVE)); @@ -71,6 +89,10 @@ suite('Files - TextFileEditorModel', () => { assert.ok(model.hasState(ModelState.SAVED)); assert.ok(!model.isDirty()); assert.ok(savedEvent); + assert.ok(workingCopyEvent); + + assert.equal(accessor.workingCopyService.dirtyCount, 0); + assert.equal(accessor.workingCopyService.isDirty(model.resource), false); model.dispose(); assert.ok(!accessor.modelService.getModel(model.getResource())); @@ -88,9 +110,17 @@ suite('Files - TextFileEditorModel', () => { } }); + let workingCopyEvent = false; + accessor.workingCopyService.onDidChangeDirty(e => { + if (e.resource.toString() === model.resource.toString()) { + workingCopyEvent = true; + } + }); + await model.save({ force: true }); assert.ok(savedEvent); + assert.ok(!workingCopyEvent); model.dispose(); assert.ok(!accessor.modelService.getModel(model.getResource())); @@ -182,14 +212,29 @@ suite('Files - TextFileEditorModel', () => { } }); + let workingCopyEvent = false; + accessor.workingCopyService.onDidChangeDirty(e => { + if (e.resource.toString() === model.resource.toString()) { + workingCopyEvent = true; + } + }); + await model.load(); model.textEditorModel!.setValue('foo'); assert.ok(model.isDirty()); + assert.equal(accessor.workingCopyService.dirtyCount, 1); + assert.equal(accessor.workingCopyService.isDirty(model.resource), true); + await model.revert(); assert.ok(!model.isDirty()); assert.equal(model.textEditorModel!.getValue(), 'Hello Html'); assert.equal(eventCounter, 1); + + assert.ok(workingCopyEvent); + assert.equal(accessor.workingCopyService.dirtyCount, 0); + assert.equal(accessor.workingCopyService.isDirty(model.resource), false); + model.dispose(); }); @@ -204,14 +249,29 @@ suite('Files - TextFileEditorModel', () => { } }); + let workingCopyEvent = false; + accessor.workingCopyService.onDidChangeDirty(e => { + if (e.resource.toString() === model.resource.toString()) { + workingCopyEvent = true; + } + }); + await model.load(); model.textEditorModel!.setValue('foo'); assert.ok(model.isDirty()); + assert.equal(accessor.workingCopyService.dirtyCount, 1); + assert.equal(accessor.workingCopyService.isDirty(model.resource), true); + await model.revert(true /* soft revert */); assert.ok(!model.isDirty()); assert.equal(model.textEditorModel!.getValue(), 'foo'); assert.equal(eventCounter, 1); + + assert.ok(workingCopyEvent); + assert.equal(accessor.workingCopyService.dirtyCount, 0); + assert.equal(accessor.workingCopyService.isDirty(model.resource), false); + model.dispose(); }); @@ -223,6 +283,9 @@ suite('Files - TextFileEditorModel', () => { await model.load(); model.textEditorModel!.undo(); assert.ok(model.isDirty()); + + assert.equal(accessor.workingCopyService.dirtyCount, 1); + assert.equal(accessor.workingCopyService.isDirty(model.resource), true); }); test('Make Dirty', async function () { @@ -246,9 +309,18 @@ suite('Files - TextFileEditorModel', () => { } }); + let workingCopyEvent = false; + accessor.workingCopyService.onDidChangeDirty(e => { + if (e.resource.toString() === model.resource.toString()) { + workingCopyEvent = true; + } + }); + model.makeDirty(); assert.ok(model.isDirty()); assert.equal(eventCounter, 1); + assert.ok(workingCopyEvent); + model.dispose(); }); @@ -343,7 +415,6 @@ suite('Files - TextFileEditorModel', () => { }); test('Save Participant, async participant', async function () { - const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/index_async.txt'), 'utf8', undefined); TextFileEditorModel.setSaveParticipant({ diff --git a/src/vs/workbench/services/workingCopy/common/workingCopyService.ts b/src/vs/workbench/services/workingCopy/common/workingCopyService.ts new file mode 100644 index 000000000000..074a78302915 --- /dev/null +++ b/src/vs/workbench/services/workingCopy/common/workingCopyService.ts @@ -0,0 +1,161 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { Event, Emitter } from 'vs/base/common/event'; +import { URI } from 'vs/base/common/uri'; +import { Disposable, IDisposable, toDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle'; +import { TernarySearchTree } from 'vs/base/common/map'; + +export const enum WorkingCopyCapabilities { + + /** + * Signals that the working copy participates + * in auto saving as configured by the user. + */ + AutoSave = 1 << 1 +} + +export interface IWorkingCopy { + + //#region Dirty Tracking + + readonly onDidChangeDirty: Event; + + isDirty(): boolean; + + //#endregion + + readonly resource: URI; + + readonly capabilities: WorkingCopyCapabilities; +} + +export const IWorkingCopyService = createDecorator('workingCopyService'); + +export interface IWorkingCopyService { + + _serviceBrand: undefined; + + //#region Dirty Tracking + + readonly onDidChangeDirty: Event; + + readonly dirtyCount: number; + + readonly hasDirty: boolean; + + isDirty(resource: URI): boolean; + + //#endregion + + + //#region Registry + + registerWorkingCopy(workingCopy: IWorkingCopy): IDisposable; + + //#endregion +} + +export class WorkingCopyService extends Disposable implements IWorkingCopyService { + + _serviceBrand: undefined; + + //#region Dirty Tracking + + private readonly _onDidChangeDirty = this._register(new Emitter()); + readonly onDidChangeDirty = this._onDidChangeDirty.event; + + isDirty(resource: URI): boolean { + const workingCopies = this.mapResourceToWorkingCopy.get(resource.toString()); + if (workingCopies) { + for (const workingCopy of workingCopies) { + if (workingCopy.isDirty()) { + return true; + } + } + } + + return false; + } + + get hasDirty(): boolean { + for (const workingCopy of this.workingCopies) { + if (workingCopy.isDirty()) { + return true; + } + } + + return false; + } + + get dirtyCount(): number { + let totalDirtyCount = 0; + + for (const workingCopy of this.workingCopies) { + if (workingCopy.isDirty()) { + totalDirtyCount++; + } + } + + return totalDirtyCount; + } + + //#endregion + + + //#region Registry + + private mapResourceToWorkingCopy = TernarySearchTree.forPaths>(); + private workingCopies = new Set(); + + registerWorkingCopy(workingCopy: IWorkingCopy): IDisposable { + const disposables = new DisposableStore(); + + // Registry + let workingCopiesForResource = this.mapResourceToWorkingCopy.get(workingCopy.resource.toString()); + if (!workingCopiesForResource) { + workingCopiesForResource = new Set(); + this.mapResourceToWorkingCopy.set(workingCopy.resource.toString(), workingCopiesForResource); + } + + workingCopiesForResource.add(workingCopy); + + this.workingCopies.add(workingCopy); + + // Dirty Events + disposables.add(workingCopy.onDidChangeDirty(() => this._onDidChangeDirty.fire(workingCopy))); + if (workingCopy.isDirty()) { + this._onDidChangeDirty.fire(workingCopy); + } + + return toDisposable(() => { + this.unregisterWorkingCopy(workingCopy); + dispose(disposables); + }); + } + + private unregisterWorkingCopy(workingCopy: IWorkingCopy): void { + + // Remove from registry + const workingCopiesForResource = this.mapResourceToWorkingCopy.get(workingCopy.resource.toString()); + if (workingCopiesForResource && workingCopiesForResource.delete(workingCopy) && workingCopiesForResource.size === 0) { + this.mapResourceToWorkingCopy.delete(workingCopy.resource.toString()); + } + + this.workingCopies.delete(workingCopy); + + // If copy is dirty, ensure to fire an event to signal the dirty change + // (a disposed working copy cannot account for being dirty in our model) + if (workingCopy.isDirty()) { + this._onDidChangeDirty.fire(workingCopy); + } + } + + //#endregion +} + +registerSingleton(IWorkingCopyService, WorkingCopyService, true); diff --git a/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts b/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts new file mode 100644 index 000000000000..7bff97ff4082 --- /dev/null +++ b/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts @@ -0,0 +1,144 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { WorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { URI } from 'vs/base/common/uri'; +import { Emitter } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; + +suite('WorkingCopyService', () => { + + class TestWorkingCopy extends Disposable implements IWorkingCopy { + + private readonly _onDidChangeDirty = this._register(new Emitter()); + readonly onDidChangeDirty = this._onDidChangeDirty.event; + + private readonly _onDispose = this._register(new Emitter()); + readonly onDispose = this._onDispose.event; + + readonly capabilities = 0; + + private dirty = false; + + constructor(public readonly resource: URI, isDirty = false) { + super(); + + this.dirty = isDirty; + } + + setDirty(dirty: boolean): void { + if (this.dirty !== dirty) { + this.dirty = dirty; + this._onDidChangeDirty.fire(); + } + } + + isDirty(): boolean { + return this.dirty; + } + + dispose(): void { + this._onDispose.fire(); + + super.dispose(); + } + } + + test('registry - basics', () => { + const service = new WorkingCopyService(); + + const onDidChangeDirty: IWorkingCopy[] = []; + service.onDidChangeDirty(copy => onDidChangeDirty.push(copy)); + + assert.equal(service.hasDirty, false); + assert.equal(service.dirtyCount, 0); + assert.equal(service.isDirty(URI.file('/')), false); + + // resource 1 + const resource1 = URI.file('/some/folder/file.txt'); + const copy1 = new TestWorkingCopy(resource1); + const unregister1 = service.registerWorkingCopy(copy1); + + assert.equal(service.dirtyCount, 0); + assert.equal(service.isDirty(resource1), false); + assert.equal(service.hasDirty, false); + + copy1.setDirty(true); + + assert.equal(service.dirtyCount, 1); + assert.equal(service.isDirty(resource1), true); + assert.equal(service.hasDirty, true); + assert.equal(onDidChangeDirty.length, 1); + assert.equal(onDidChangeDirty[0], copy1); + + copy1.setDirty(false); + + assert.equal(service.dirtyCount, 0); + assert.equal(service.isDirty(resource1), false); + assert.equal(service.hasDirty, false); + assert.equal(onDidChangeDirty.length, 2); + assert.equal(onDidChangeDirty[1], copy1); + + unregister1.dispose(); + + // resource 2 + const resource2 = URI.file('/some/folder/file-dirty.txt'); + const copy2 = new TestWorkingCopy(resource2, true); + const unregister2 = service.registerWorkingCopy(copy2); + + assert.equal(service.dirtyCount, 1); + assert.equal(service.isDirty(resource2), true); + assert.equal(service.hasDirty, true); + + assert.equal(onDidChangeDirty.length, 3); + assert.equal(onDidChangeDirty[2], copy2); + + unregister2.dispose(); + assert.equal(service.dirtyCount, 0); + assert.equal(service.hasDirty, false); + assert.equal(onDidChangeDirty.length, 4); + assert.equal(onDidChangeDirty[3], copy2); + }); + + test('registry - multiple copies on same resource', () => { + const service = new WorkingCopyService(); + + const onDidChangeDirty: IWorkingCopy[] = []; + service.onDidChangeDirty(copy => onDidChangeDirty.push(copy)); + + const resource = URI.parse('custom://some/folder/custom.txt'); + + const copy1 = new TestWorkingCopy(resource); + const unregister1 = service.registerWorkingCopy(copy1); + + const copy2 = new TestWorkingCopy(resource); + const unregister2 = service.registerWorkingCopy(copy2); + + copy1.setDirty(true); + + assert.equal(service.dirtyCount, 1); + assert.equal(onDidChangeDirty.length, 1); + assert.equal(service.isDirty(resource), true); + + copy2.setDirty(true); + + assert.equal(service.dirtyCount, 2); + assert.equal(onDidChangeDirty.length, 2); + assert.equal(service.isDirty(resource), true); + + unregister1.dispose(); + + assert.equal(service.dirtyCount, 1); + assert.equal(onDidChangeDirty.length, 3); + assert.equal(service.isDirty(resource), true); + + unregister2.dispose(); + + assert.equal(service.dirtyCount, 0); + assert.equal(onDidChangeDirty.length, 4); + assert.equal(service.isDirty(resource), false); + }); +}); diff --git a/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts b/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts index b963b547b007..3d55bd3d1449 100644 --- a/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts +++ b/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts @@ -17,6 +17,7 @@ import { UntitledTextEditorInput } from 'vs/workbench/common/editor/untitledText import { timeout } from 'vs/base/common/async'; import { snapshotToString } from 'vs/workbench/services/textfile/common/textfiles'; import { ModesRegistry, PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; +import { IWorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export class TestUntitledTextEditorService extends UntitledTextEditorService { get(resource: URI) { return super.get(resource); } @@ -25,9 +26,10 @@ export class TestUntitledTextEditorService extends UntitledTextEditorService { class ServiceAccessor { constructor( - @IUntitledTextEditorService public untitledTextEditorService: TestUntitledTextEditorService, - @IModeService public modeService: ModeServiceImpl, - @IConfigurationService public testConfigurationService: TestConfigurationService) { + @IUntitledTextEditorService public readonly untitledTextEditorService: TestUntitledTextEditorService, + @IWorkingCopyService public readonly workingCopyService: IWorkingCopyService, + @IModeService public readonly modeService: ModeServiceImpl, + @IConfigurationService public readonly testConfigurationService: TestConfigurationService) { } } @@ -48,6 +50,8 @@ suite('Workbench untitled text editors', () => { test('Untitled Text Editor Service', async (done) => { const service = accessor.untitledTextEditorService; + const workingCopyService = accessor.workingCopyService; + assert.equal(service.getAll().length, 0); const input1 = service.createOrGet(); @@ -83,11 +87,17 @@ suite('Workbench untitled text editors', () => { assert.equal(service.getDirty([input2.getResource()])[0].toString(), input2.getResource().toString()); assert.equal(service.getDirty([input1.getResource()]).length, 0); + assert.ok(workingCopyService.isDirty(input2.getResource())); + assert.equal(workingCopyService.dirtyCount, 1); + service.revertAll(); assert.equal(service.getAll().length, 0); assert.ok(!input2.isDirty()); assert.ok(!model.isDirty()); + assert.ok(!workingCopyService.isDirty(input2.getResource())); + assert.equal(workingCopyService.dirtyCount, 0); + input2.dispose(); assert.ok(!service.exists(input2.getResource())); @@ -109,14 +119,17 @@ suite('Workbench untitled text editors', () => { test('Untitled no longer dirty when content gets empty', async () => { const service = accessor.untitledTextEditorService; + const workingCopyService = accessor.workingCopyService; const input = service.createOrGet(); // dirty const model = await input.resolve(); model.textEditorModel.setValue('foo bar'); assert.ok(model.isDirty()); + assert.ok(workingCopyService.isDirty(model.resource)); model.textEditorModel.setValue(''); assert.ok(!model.isDirty()); + assert.ok(!workingCopyService.isDirty(model.resource)); input.dispose(); }); @@ -176,11 +189,21 @@ suite('Workbench untitled text editors', () => { test('Untitled with initial content is dirty', async () => { const service = accessor.untitledTextEditorService; const input = service.createOrGet(undefined, undefined, 'Hello World'); + const workingCopyService = accessor.workingCopyService; + + let onDidChangeDirty: IWorkingCopy | undefined = undefined; + const listener = workingCopyService.onDidChangeDirty(copy => { + onDidChangeDirty = copy; + }); // dirty const model = await input.resolve(); assert.ok(model.isDirty()); + assert.equal(workingCopyService.dirtyCount, 1); + assert.equal(onDidChangeDirty, model); + input.dispose(); + listener.dispose(); }); test('Untitled created with files.defaultLanguage setting', () => { diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index c4acaed37e87..5d9d717d2bcc 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -92,6 +92,7 @@ import { IBackupMainService, IWorkspaceBackupInfo } from 'vs/platform/backup/ele import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup'; import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; import { find } from 'vs/base/common/arrays'; +import { WorkingCopyService, IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); @@ -330,6 +331,7 @@ export function workbenchInstantiationService(): IInstantiationService { instantiationService.stub(IEditorService, editorService); instantiationService.stub(ICodeEditorService, new TestCodeEditorService()); instantiationService.stub(IViewletService, new TestViewletService()); + instantiationService.stub(IWorkingCopyService, new TestWorkingCopyService()); return instantiationService; } @@ -1464,3 +1466,7 @@ export class TestDialogMainService implements IDialogMainService { throw new Error('Method not implemented.'); } } + +export class TestWorkingCopyService extends WorkingCopyService { + +} diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index ddb19940d86a..8c9f50ad424b 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -82,6 +82,7 @@ import 'vs/workbench/services/extensions/common/staticExtensions'; import 'vs/workbench/services/userDataSync/common/settingsMergeService'; import 'vs/workbench/services/path/common/remotePathService'; import 'vs/workbench/services/remote/common/remoteExplorerService'; +import 'vs/workbench/services/workingCopy/common/workingCopyService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; From f0f6c8dc4ceda13c9e935895ead2538dff352641 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Nov 2019 16:52:13 +0100 Subject: [PATCH 40/60] fixes #83757 --- .../contrib/debug/browser/media/debug.contribution.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css b/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css index 3ab961601acd..fd184092abdc 100644 --- a/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css +++ b/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css @@ -120,7 +120,8 @@ } .monaco-editor .debug-top-stack-frame.debug-breakpoint-and-top-stack-frame, -.monaco-editor .inline-breakpoint-widget.debug-breakpoint-and-top-stack-frame-at-column { +.monaco-editor .debug-breakpoint.debug-top-stack-frame, +.monaco-editor .debug-breakpoint-and-top-stack-frame-at-column { background: url('current-and-breakpoint.svg') center center no-repeat; } From cbdb21d24c8f45d1cb5c879324f980b6301b914e Mon Sep 17 00:00:00 2001 From: Andre Weinand Date: Tue, 12 Nov 2019 17:01:58 +0100 Subject: [PATCH 41/60] do a "--inspect-brk" if being asked to do so; fixes #83583 --- .../services/environment/browser/environmentService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts index 4035945e8e38..5437e4c00caa 100644 --- a/src/vs/workbench/services/environment/browser/environmentService.ts +++ b/src/vs/workbench/services/environment/browser/environmentService.ts @@ -301,7 +301,7 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment break; case 'inspect-brk-extensions': extensionHostDebugEnvironment.params.port = parseInt(value); - extensionHostDebugEnvironment.params.break = false; + extensionHostDebugEnvironment.params.break = true; break; } } From dc315fcb0feb29cc3683a5887f25890c7fc62633 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 12 Nov 2019 17:03:18 +0100 Subject: [PATCH 42/60] fixes #84598 --- src/vs/base/browser/ui/tree/asyncDataTree.ts | 75 +++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 49cf32517511..9a5dd74b4f53 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -264,7 +264,7 @@ function dfs(node: IAsyncDataTreeNode, fn: (node: IAsyncDa export class AsyncDataTree implements IDisposable { protected readonly tree: ObjectTree, TFilterData>; - private readonly root: IAsyncDataTreeNode; + protected readonly root: IAsyncDataTreeNode; private readonly nodes = new Map>(); private readonly sorter?: ITreeSorter; private readonly collapseByDefault?: { (e: T): boolean; }; @@ -859,7 +859,7 @@ export class AsyncDataTree implements IDisposable return childrenToRefresh; } - private render(node: IAsyncDataTreeNode, viewStateContext?: IAsyncDataTreeViewStateContext): void { + protected render(node: IAsyncDataTreeNode, viewStateContext?: IAsyncDataTreeViewStateContext): void { const children = node.children.map(node => this.asTreeElement(node, viewStateContext)); this.tree.setChildren(node === this.root ? null : node, children); @@ -1098,4 +1098,75 @@ export class CompressibleAsyncDataTree extends As return { focus, selection, expanded, scrollTop: this.scrollTop }; } + + protected render(node: IAsyncDataTreeNode, viewStateContext?: IAsyncDataTreeViewStateContext): void { + if (!this.identityProvider) { + return super.render(node, viewStateContext); + } + + // Preserve traits across compressions. Hacky but does the trick. + // This is hard to fix properly since it requires rewriting the traits + // across trees and lists. Let's just keep it this way for now. + const getId = (element: T) => this.identityProvider!.getId(element).toString(); + const getUncompressedIds = (nodes: IAsyncDataTreeNode[]): Set => { + const result = new Set(); + + for (const node of nodes) { + const compressedNode = this.tree.getCompressedTreeNode(node === this.root ? null : node); + + if (!compressedNode.element) { + continue; + } + + for (const node of compressedNode.element.elements) { + result.add(getId(node.element as T)); + } + } + + return result; + }; + + const oldSelection = getUncompressedIds(this.tree.getSelection() as IAsyncDataTreeNode[]); + const oldFocus = getUncompressedIds(this.tree.getFocus() as IAsyncDataTreeNode[]); + + super.render(node, viewStateContext); + + const selection = this.getSelection(); + let didChangeSelection = false; + + const focus = this.getFocus(); + let didChangeFocus = false; + + const visit = (node: ITreeNode> | null, TFilterData>) => { + const compressedNode = node.element; + + if (compressedNode) { + for (let i = 0; i < compressedNode.elements.length; i++) { + const id = getId(compressedNode.elements[i].element as T); + + if (oldSelection.has(id)) { + selection.push(compressedNode.elements[compressedNode.elements.length - 1].element as T); + didChangeSelection = true; + } + + if (oldFocus.has(id)) { + focus.push(compressedNode.elements[compressedNode.elements.length - 1].element as T); + didChangeFocus = true; + } + } + } + + node.children.forEach(visit); + }; + + visit(this.tree.getCompressedTreeNode(node === this.root ? null : node)); + + if (didChangeSelection) { + this.setSelection(selection); + } + + if (didChangeFocus) { + this.setFocus(focus); + } + } } From da5f40883482e245afb4d87ce4f94a73ecb5c13f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 17:04:49 +0100 Subject: [PATCH 43/60] workbench editor model: getResource => resource --- .../api/browser/mainThreadDocuments.ts | 2 +- .../api/browser/mainThreadSaveParticipant.ts | 10 +-- .../browser/parts/editor/binaryEditor.ts | 2 +- .../common/editor/binaryEditorModel.ts | 9 +- .../common/editor/untitledTextEditorModel.ts | 4 - .../browser/editors/fileEditorTracker.ts | 6 +- .../contrib/files/browser/saveErrorHandler.ts | 12 +-- .../textfile/browser/textFileService.ts | 28 +++---- .../textfile/common/textFileEditorModel.ts | 10 +-- .../common/textFileEditorModelManager.ts | 2 +- .../services/textfile/common/textfiles.ts | 7 +- .../textfile/test/textFileEditorModel.test.ts | 8 +- .../test/textFileEditorModelManager.test.ts | 2 +- .../textfile/test/textFileService.test.ts | 82 +++++++++---------- .../test/textModelResolverService.test.ts | 4 +- .../common/editor/untitledTextEditor.test.ts | 4 +- 16 files changed, 88 insertions(+), 104 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadDocuments.ts b/src/vs/workbench/api/browser/mainThreadDocuments.ts index 05eb4662f395..2b743a9484fb 100644 --- a/src/vs/workbench/api/browser/mainThreadDocuments.ts +++ b/src/vs/workbench/api/browser/mainThreadDocuments.ts @@ -233,7 +233,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape { initialValue, useResourcePath: Boolean(resource && resource.path) }).then(model => { - const resource = model.getResource(); + const resource = model.resource; if (!this._modelIsSynced.has(resource.toString())) { throw new Error(`expected URI ${resource.toString()} to have come to LIFE`); diff --git a/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts b/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts index 3dff068097ec..5fdd5b7c9519 100644 --- a/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts +++ b/src/vs/workbench/api/browser/mainThreadSaveParticipant.ts @@ -51,7 +51,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant { } async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { - if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { + if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) { this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO); } } @@ -113,7 +113,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant { } async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { - if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { + if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) { this.doInsertFinalNewLine(model.textEditorModel); } } @@ -147,7 +147,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant } async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise { - if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) { + if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) { this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO); } } @@ -257,7 +257,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant { const model = editorModel.textEditorModel; - const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() }; + const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.resource }; const setting = this._configurationService.getValue('editor.codeActionsOnSave', settingsOverrides); if (!setting) { return undefined; @@ -343,7 +343,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant { return new Promise((resolve, reject) => { setTimeout(() => reject(localize('timeout.onWillSave', "Aborted onWillSaveTextDocument-event after 1750ms")), 1750); - this._proxy.$participateInSave(editorModel.getResource(), env.reason).then(values => { + this._proxy.$participateInSave(editorModel.resource, env.reason).then(values => { if (!values.every(success => success)) { return Promise.reject(new Error('listener failed')); } diff --git a/src/vs/workbench/browser/parts/editor/binaryEditor.ts b/src/vs/workbench/browser/parts/editor/binaryEditor.ts index 53b00a24b331..d196daa8517e 100644 --- a/src/vs/workbench/browser/parts/editor/binaryEditor.ts +++ b/src/vs/workbench/browser/parts/editor/binaryEditor.ts @@ -93,7 +93,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor { } const [binaryContainer, scrollbar] = assertAllDefined(this.binaryContainer, this.scrollbar); - this.resourceViewerContext = ResourceViewer.show({ name: model.getName(), resource: model.getResource(), size: model.getSize(), etag: model.getETag(), mime: model.getMime() }, binaryContainer, scrollbar, { + this.resourceViewerContext = ResourceViewer.show({ name: model.getName(), resource: model.resource, size: model.getSize(), etag: model.getETag(), mime: model.getMime() }, binaryContainer, scrollbar, { openInternalClb: () => this.handleOpenInternalCallback(input, options), openExternalClb: this.environmentService.configuration.remoteAuthority ? undefined : resource => this.callbacks.openExternal(resource), metadataClb: meta => this.handleMetadataChanged(meta) diff --git a/src/vs/workbench/common/editor/binaryEditorModel.ts b/src/vs/workbench/common/editor/binaryEditorModel.ts index 5f94a8c947a7..a911af30a8c2 100644 --- a/src/vs/workbench/common/editor/binaryEditorModel.ts +++ b/src/vs/workbench/common/editor/binaryEditorModel.ts @@ -19,7 +19,7 @@ export class BinaryEditorModel extends EditorModel { private readonly mime: string; constructor( - private readonly resource: URI, + public readonly resource: URI, private readonly name: string | undefined, @IFileService private readonly fileService: IFileService ) { @@ -49,13 +49,6 @@ export class BinaryEditorModel extends EditorModel { return this.name || basename(this.resource); } - /** - * The resource of the binary resource. - */ - getResource(): URI { - return this.resource; - } - /** * The size of the binary resource if known. */ diff --git a/src/vs/workbench/common/editor/untitledTextEditorModel.ts b/src/vs/workbench/common/editor/untitledTextEditorModel.ts index 7c47a00dfc9c..b0d22deb9b3a 100644 --- a/src/vs/workbench/common/editor/untitledTextEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledTextEditorModel.ts @@ -115,10 +115,6 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc this._onDidChangeDirty.fire(); } - getResource(): URI { - return this.resource; - } - revert(): void { this.setDirty(false); diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts index 271741351a97..ca9dba559e20 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts @@ -98,7 +98,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut return resource ? this.textFileService.models.get(resource) : undefined; })) .filter(model => !model.isDirty()), - m => m.getResource().toString() + m => m.resource.toString() ).forEach(model => this.queueModelLoad(model)); } } @@ -299,7 +299,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // and updated right after. distinct(coalesce([...e.getUpdated(), ...e.getAdded()] .map(u => this.textFileService.models.get(u.resource))) - .filter(model => model && !model.isDirty()), m => m.getResource().toString()) + .filter(model => model && !model.isDirty()), m => m.resource.toString()) .forEach(model => this.queueModelLoad(model)); } @@ -308,7 +308,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut // Load model to update (use a queue to prevent accumulation of loads // when the load actually takes long. At most we only want the queue // to have a size of 2 (1 running load and 1 queued load). - const queue = this.modelLoadQueue.queueFor(model.getResource()); + const queue = this.modelLoadQueue.queueFor(model.resource); if (queue.size <= 1) { queue.queue(() => model.load().then(undefined, onUnexpectedError)); } diff --git a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts index 847d044971b8..635033681e1e 100644 --- a/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts +++ b/src/vs/workbench/contrib/files/browser/saveErrorHandler.ts @@ -103,7 +103,7 @@ export class SaveErrorHandler extends Disposable implements ISaveErrorHandler, I onSaveError(error: any, model: ITextFileEditorModel): void { const fileOperationError = error as FileOperationError; - const resource = model.getResource(); + const resource = model.resource; let message: string; const primaryActions: IAction[] = []; @@ -113,7 +113,7 @@ export class SaveErrorHandler extends Disposable implements ISaveErrorHandler, I if (fileOperationError.fileOperationResult === FileOperationResult.FILE_MODIFIED_SINCE) { // If the user tried to save from the opened conflict editor, show its message again - if (this.activeConflictResolutionResource && this.activeConflictResolutionResource.toString() === model.getResource().toString()) { + if (this.activeConflictResolutionResource && this.activeConflictResolutionResource.toString() === model.resource.toString()) { if (this.storageService.getBoolean(LEARN_MORE_DIRTY_WRITE_IGNORE_KEY, StorageScope.GLOBAL)) { return; // return if this message is ignored } @@ -178,7 +178,7 @@ export class SaveErrorHandler extends Disposable implements ISaveErrorHandler, I const actions: INotificationActions = { primary: primaryActions, secondary: secondaryActions }; const handle = this.notificationService.notify({ severity: Severity.Error, message, actions }); Event.once(handle.onDidClose)(() => { dispose(primaryActions), dispose(secondaryActions); }); - this.messages.set(model.getResource(), handle); + this.messages.set(model.resource, handle); } dispose(): void { @@ -243,7 +243,7 @@ class ResolveSaveConflictAction extends Action { async run(): Promise { if (!this.model.isDisposed()) { - const resource = this.model.getResource(); + const resource = this.model.resource; const name = basename(resource); const editorLabel = nls.localize('saveConflictDiffLabel', "{0} (in file) ↔ {1} (in {2}) - Resolve save conflict", name, name, this.productService.nameLong); @@ -332,7 +332,7 @@ export const acceptLocalChangesCommand = async (accessor: ServicesAccessor, reso await model.save(); // Reopen file input - await editorService.openEditor({ resource: model.getResource() }, group); + await editorService.openEditor({ resource: model.resource }, group); // Clean up group.closeEditor(editor); @@ -361,7 +361,7 @@ export const revertLocalChangesCommand = async (accessor: ServicesAccessor, reso await model.revert(); // Reopen file input - await editorService.openEditor({ resource: model.getResource() }, group); + await editorService.openEditor({ resource: model.resource }, group); // Clean up group.closeEditor(editor); diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index b77eb7be4c0e..7a68d53bd7a9 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -467,7 +467,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex const sourceModels: ITextFileEditorModel[] = []; const conflictingModels: ITextFileEditorModel[] = []; for (const model of this.getFileModels()) { - const resource = model.getResource(); + const resource = model.resource; if (isEqualOrParent(resource, target, false /* do not ignorecase, see https://github.com/Microsoft/vscode/issues/56384 */)) { conflictingModels.push(model); @@ -483,7 +483,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex type ModelToRestore = { resource: URI; snapshot?: ITextSnapshot }; const modelsToRestore: ModelToRestore[] = []; for (const sourceModel of sourceModels) { - const sourceModelResource = sourceModel.getResource(); + const sourceModelResource = sourceModel.resource; // If the source is the actual model, just use target as new resource let modelToRestoreResource: URI; @@ -508,7 +508,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex // in order to move, we need to soft revert all dirty models, // both from the source as well as the target if any const dirtyModels = [...sourceModels, ...conflictingModels].filter(model => model.isDirty()); - await this.revertAll(dirtyModels.map(dirtyModel => dirtyModel.getResource()), { soft: true }); + await this.revertAll(dirtyModels.map(dirtyModel => dirtyModel.resource), { soft: true }); // now we can rename the source to target via file operation let stat: IFileStatWithMetadata; @@ -735,9 +735,9 @@ export abstract class AbstractTextFileService extends Disposable implements ITex }); const mapResourceToResult = new ResourceMap(); - dirtyFileModels.forEach(m => { - mapResourceToResult.set(m.getResource(), { - source: m.getResource() + dirtyFileModels.forEach(dirtyModel => { + mapResourceToResult.set(dirtyModel.resource, { + source: dirtyModel.resource }); }); @@ -745,7 +745,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex await model.save(options); if (!model.isDirty()) { - const result = mapResourceToResult.get(model.getResource()); + const result = mapResourceToResult.get(model.resource); if (result) { result.success = true; } @@ -861,7 +861,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex // path. This can happen if the file was created after the untitled file was opened. // See https://github.com/Microsoft/vscode/issues/67946 let write: boolean; - if (sourceModel instanceof UntitledTextEditorModel && sourceModel.hasAssociatedFilePath && targetExists && isEqual(target, toLocalResource(sourceModel.getResource(), this.environmentService.configuration.remoteAuthority))) { + if (sourceModel instanceof UntitledTextEditorModel && sourceModel.hasAssociatedFilePath && targetExists && isEqual(target, toLocalResource(sourceModel.resource, this.environmentService.configuration.remoteAuthority))) { write = await this.confirmOverwrite(target); } else { write = true; @@ -944,9 +944,9 @@ export abstract class AbstractTextFileService extends Disposable implements ITex const fileModels = options?.force ? this.getFileModels(resources) : this.getDirtyFileModels(resources); const mapResourceToResult = new ResourceMap(); - fileModels.forEach(m => { - mapResourceToResult.set(m.getResource(), { - source: m.getResource() + fileModels.forEach(fileModel => { + mapResourceToResult.set(fileModel.resource, { + source: fileModel.resource }); }); @@ -955,7 +955,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex await model.revert(options?.soft); if (!model.isDirty()) { - const result = mapResourceToResult.get(model.getResource()); + const result = mapResourceToResult.get(model.resource); if (result) { result.success = true; } @@ -964,7 +964,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex // FileNotFound means the file got deleted meanwhile, so still record as successful revert if ((error).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) { - const result = mapResourceToResult.get(model.getResource()); + const result = mapResourceToResult.get(model.resource); if (result) { result.success = true; } @@ -983,7 +983,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex getDirty(resources?: URI[]): URI[] { // Collect files - const dirty = this.getDirtyFileModels(resources).map(m => m.getResource()); + const dirty = this.getDirtyFileModels(resources).map(dirtyFileModel => dirtyFileModel.resource); // Add untitled ones dirty.push(...this.untitledTextEditorService.getDirty(resources)); diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index ee2501f8854f..b86d2ed4508d 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -29,7 +29,7 @@ import { ILogService } from 'vs/platform/log/common/log'; import { isEqual, isEqualOrParent, extname, basename, joinPath } from 'vs/base/common/resources'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Schemas } from 'vs/base/common/network'; -import { IWorkingCopyService, IWorkingCopy, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export interface IBackupMetaData { mtime: number; @@ -58,7 +58,7 @@ type TelemetryData = { /** * The text file editor model listens to changes to its underlying code editor model and saves these changes through the file service back to the disk. */ -export class TextFileEditorModel extends BaseTextEditorModel implements ITextFileEditorModel, IWorkingCopy { +export class TextFileEditorModel extends BaseTextEditorModel implements ITextFileEditorModel { static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY; static DEFAULT_ORPHANED_CHANGE_BUFFER_DELAY = 100; @@ -1030,10 +1030,6 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil return this.disposed; } - getResource(): URI { - return this.resource; - } - getStat(): IFileStatWithMetadata | undefined { return this.lastResolvedFileStat; } @@ -1144,6 +1140,6 @@ class DefaultSaveErrorHandler implements ISaveErrorHandler { constructor(@INotificationService private readonly notificationService: INotificationService) { } onSaveError(error: Error, model: TextFileEditorModel): void { - this.notificationService.error(nls.localize('genericSaveError', "Failed to save '{0}': {1}", basename(model.getResource()), toErrorMessage(error, false))); + this.notificationService.error(nls.localize('genericSaveError', "Failed to save '{0}': {1}", basename(model.resource), toErrorMessage(error, false))); } } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts index 562aa4c727e9..08ebc5edc4d0 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModelManager.ts @@ -304,7 +304,7 @@ export class TextFileEditorModelManager extends Disposable implements ITextFileE return; // already disposed } - if (this.mapResourceToPendingModelLoaders.has(model.getResource())) { + if (this.mapResourceToPendingModelLoaders.has(model.resource)) { return; // not yet loaded } diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 5a752b201286..4ab9efb61c71 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -15,6 +15,7 @@ import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { isNative } from 'vs/base/common/platform'; +import { IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; export const ITextFileService = createDecorator('textFileService'); @@ -328,7 +329,7 @@ export class TextFileModelChangeEvent { private _resource: URI; constructor(model: ITextFileEditorModel, private _kind: StateChange) { - this._resource = model.getResource(); + this._resource = model.resource; } get resource(): URI { @@ -492,13 +493,11 @@ export interface ILoadOptions { reason?: LoadReason; } -export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport, IModeSupport { +export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport, IModeSupport, IWorkingCopy { readonly onDidContentChange: Event; readonly onDidStateChange: Event; - getResource(): URI; - hasState(state: ModelState): boolean; updatePreferredEncoding(encoding: string | undefined): void; diff --git a/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts b/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts index dbddfc86a401..8ccf5a25c5db 100644 --- a/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileEditorModel.test.ts @@ -95,7 +95,7 @@ suite('Files - TextFileEditorModel', () => { assert.equal(accessor.workingCopyService.isDirty(model.resource), false); model.dispose(); - assert.ok(!accessor.modelService.getModel(model.getResource())); + assert.ok(!accessor.modelService.getModel(model.resource)); }); test('save - touching also emits saved event', async function () { @@ -123,7 +123,7 @@ suite('Files - TextFileEditorModel', () => { assert.ok(!workingCopyEvent); model.dispose(); - assert.ok(!accessor.modelService.getModel(model.getResource())); + assert.ok(!accessor.modelService.getModel(model.resource)); }); test('setEncoding - encode', function () { @@ -162,7 +162,7 @@ suite('Files - TextFileEditorModel', () => { assert.equal(model.textEditorModel!.getModeId(), mode); model.dispose(); - assert.ok(!accessor.modelService.getModel(model.getResource())); + assert.ok(!accessor.modelService.getModel(model.resource)); }); test('disposes when underlying model is destroyed', async function () { @@ -185,7 +185,7 @@ suite('Files - TextFileEditorModel', () => { await model.load(); assert.ok(model.isResolved()); model.dispose(); - assert.ok(!accessor.modelService.getModel(model.getResource())); + assert.ok(!accessor.modelService.getModel(model.resource)); }); test('Load returns dirty model as long as model is dirty', async function () { diff --git a/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts b/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts index 857096d4b0de..0494cbf139bb 100644 --- a/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileEditorModelManager.test.ts @@ -273,7 +273,7 @@ suite('Files - TextFileEditorModelManager', () => { const model = await manager.loadOrCreate(resource, { encoding: 'utf8' }); model.dispose(); assert.ok(!manager.get(resource)); - assert.ok(!accessor.modelService.getModel(model.getResource())); + assert.ok(!accessor.modelService.getModel(model.resource)); manager.dispose(); }); diff --git a/src/vs/workbench/services/textfile/test/textFileService.test.ts b/src/vs/workbench/services/textfile/test/textFileService.test.ts index d8f09e50b79a..fc486b3c0b7c 100644 --- a/src/vs/workbench/services/textfile/test/textFileService.test.ts +++ b/src/vs/workbench/services/textfile/test/textFileService.test.ts @@ -67,7 +67,7 @@ suite('Files - TextFileService', () => { test('confirm onWillShutdown - no veto', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const event = new BeforeShutdownEventImpl(); accessor.lifecycleService.fireWillShutdown(event); @@ -82,7 +82,7 @@ suite('Files - TextFileService', () => { test('confirm onWillShutdown - veto if user cancels', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; service.setConfirmResult(ConfirmResult.CANCEL); @@ -98,7 +98,7 @@ suite('Files - TextFileService', () => { test('confirm onWillShutdown - no veto and backups cleaned up if user does not want to save (hot.exit: off)', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; service.setConfirmResult(ConfirmResult.DONT_SAVE); @@ -124,7 +124,7 @@ suite('Files - TextFileService', () => { test('confirm onWillShutdown - save (hot.exit: off)', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; service.setConfirmResult(ConfirmResult.SAVE); @@ -143,18 +143,18 @@ suite('Files - TextFileService', () => { test('isDirty/getDirty - files and untitled', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; await model.load(); - assert.ok(!service.isDirty(model.getResource())); + assert.ok(!service.isDirty(model.resource)); model.textEditorModel!.setValue('foo'); - assert.ok(service.isDirty(model.getResource())); + assert.ok(service.isDirty(model.resource)); assert.equal(service.getDirty().length, 1); - assert.equal(service.getDirty([model.getResource()])[0].toString(), model.getResource().toString()); + assert.equal(service.getDirty([model.resource])[0].toString(), model.resource.toString()); const untitled = accessor.untitledTextEditorService.createOrGet(); const untitledModel = await untitled.resolve(); @@ -170,23 +170,23 @@ suite('Files - TextFileService', () => { test('save - file', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; await model.load(); model.textEditorModel!.setValue('foo'); - assert.ok(service.isDirty(model.getResource())); + assert.ok(service.isDirty(model.resource)); - const res = await service.save(model.getResource()); + const res = await service.save(model.resource); assert.ok(res); - assert.ok(!service.isDirty(model.getResource())); + assert.ok(!service.isDirty(model.resource)); }); test('save - UNC path', async function () { const untitledUncUri = URI.from({ scheme: 'untitled', authority: 'server', path: '/share/path/file.txt' }); model = instantiationService.createInstance(TextFileEditorModel, untitledUncUri, 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const mockedFileUri = untitledUncUri.with({ scheme: Schemas.file }); const mockedEditorInput = instantiationService.createInstance(TextFileEditorModel, mockedFileUri, 'utf8', undefined); @@ -210,65 +210,65 @@ suite('Files - TextFileService', () => { test('saveAll - file', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; await model.load(); model.textEditorModel!.setValue('foo'); - assert.ok(service.isDirty(model.getResource())); + assert.ok(service.isDirty(model.resource)); - const res = await service.saveAll([model.getResource()]); + const res = await service.saveAll([model.resource]); assert.ok(res); - assert.ok(!service.isDirty(model.getResource())); + assert.ok(!service.isDirty(model.resource)); assert.equal(res.results.length, 1); - assert.equal(res.results[0].source.toString(), model.getResource().toString()); + assert.equal(res.results[0].source.toString(), model.resource.toString()); }); test('saveAs - file', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; - service.setPromptPath(model.getResource()); + service.setPromptPath(model.resource); await model.load(); model.textEditorModel!.setValue('foo'); - assert.ok(service.isDirty(model.getResource())); + assert.ok(service.isDirty(model.resource)); - const res = await service.saveAs(model.getResource()); - assert.equal(res!.toString(), model.getResource().toString()); - assert.ok(!service.isDirty(model.getResource())); + const res = await service.saveAs(model.resource); + assert.equal(res!.toString(), model.resource.toString()); + assert.ok(!service.isDirty(model.resource)); }); test('revert - file', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; - service.setPromptPath(model.getResource()); + service.setPromptPath(model.resource); await model.load(); model!.textEditorModel!.setValue('foo'); - assert.ok(service.isDirty(model.getResource())); + assert.ok(service.isDirty(model.resource)); - const res = await service.revert(model.getResource()); + const res = await service.revert(model.resource); assert.ok(res); - assert.ok(!service.isDirty(model.getResource())); + assert.ok(!service.isDirty(model.resource)); }); test('delete - dirty file', async function () { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; await model.load(); model!.textEditorModel!.setValue('foo'); - assert.ok(service.isDirty(model.getResource())); + assert.ok(service.isDirty(model.resource)); - await service.delete(model.getResource()); - assert.ok(!service.isDirty(model.getResource())); + await service.delete(model.resource); + assert.ok(!service.isDirty(model.resource)); }); test('move - dirty file', async function () { @@ -282,27 +282,27 @@ suite('Files - TextFileService', () => { async function testMove(source: URI, target: URI, targetDirty?: boolean): Promise { let sourceModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, source, 'utf8', undefined); let targetModel: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, target, 'utf8', undefined); - (accessor.textFileService.models).add(sourceModel.getResource(), sourceModel); - (accessor.textFileService.models).add(targetModel.getResource(), targetModel); + (accessor.textFileService.models).add(sourceModel.resource, sourceModel); + (accessor.textFileService.models).add(targetModel.resource, targetModel); const service = accessor.textFileService; await sourceModel.load(); sourceModel.textEditorModel!.setValue('foo'); - assert.ok(service.isDirty(sourceModel.getResource())); + assert.ok(service.isDirty(sourceModel.resource)); if (targetDirty) { await targetModel.load(); targetModel.textEditorModel!.setValue('bar'); - assert.ok(service.isDirty(targetModel.getResource())); + assert.ok(service.isDirty(targetModel.resource)); } - await service.move(sourceModel.getResource(), targetModel.getResource(), true); + await service.move(sourceModel.resource, targetModel.resource, true); assert.equal(targetModel.textEditorModel!.getValue(), 'foo'); - assert.ok(!service.isDirty(sourceModel.getResource())); - assert.ok(service.isDirty(targetModel.getResource())); + assert.ok(!service.isDirty(sourceModel.resource)); + assert.ok(service.isDirty(targetModel.resource)); sourceModel.dispose(); targetModel.dispose(); @@ -413,7 +413,7 @@ suite('Files - TextFileService', () => { async function hotExitTest(this: any, setting: string, shutdownReason: ShutdownReason, multipleWindows: boolean, workspace: true, shouldVeto: boolean): Promise { model = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(model.getResource(), model); + (accessor.textFileService.models).add(model.resource, model); const service = accessor.textFileService; // Set hot exit config diff --git a/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts b/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts index a404c7e86e58..3ffe921e4cf6 100644 --- a/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts +++ b/src/vs/workbench/services/textmodelResolver/test/textModelResolverService.test.ts @@ -88,11 +88,11 @@ suite('Workbench - TextModelResolverService', () => { test('resolve file', async function () { const textModel = instantiationService.createInstance(TextFileEditorModel, toResource.call(this, '/path/file_resolver.txt'), 'utf8', undefined); - (accessor.textFileService.models).add(textModel.getResource(), textModel); + (accessor.textFileService.models).add(textModel.resource, textModel); await textModel.load(); - const ref = await accessor.textModelResolverService.createModelReference(textModel.getResource()); + const ref = await accessor.textModelResolverService.createModelReference(textModel.resource); const model = ref.object; const editorModel = model.textEditorModel; diff --git a/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts b/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts index 3d55bd3d1449..78cb84d606e6 100644 --- a/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts +++ b/src/vs/workbench/test/common/editor/untitledTextEditor.test.ts @@ -151,11 +151,11 @@ suite('Workbench untitled text editors', () => { const model3 = await service.loadOrCreate({ resource: input.getResource() }); - assert.equal(model3.getResource().toString(), input.getResource().toString()); + assert.equal(model3.resource.toString(), input.getResource().toString()); const file = URI.file(join('C:\\', '/foo/file44.txt')); const model4 = await service.loadOrCreate({ resource: file }); - assert.ok(service.hasAssociatedFilePath(model4.getResource())); + assert.ok(service.hasAssociatedFilePath(model4.resource)); assert.ok(model4.isDirty()); model1.dispose(); From 483a8a701d6fe8e76f5995332e0f0149f1e42db8 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 12 Nov 2019 08:32:13 -0800 Subject: [PATCH 44/60] Add more spacing for dropdowns --- src/vs/base/browser/ui/actionbar/actionbar.css | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.css b/src/vs/base/browser/ui/actionbar/actionbar.css index 60979ab095dc..623ff4d74214 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.css +++ b/src/vs/base/browser/ui/actionbar/actionbar.css @@ -90,4 +90,5 @@ display: flex; align-items: center; justify-content: center; + margin-right: 10px; } From a05e629253dbc84922ecffec208b0c00beb2482a Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 12 Nov 2019 17:12:06 +0100 Subject: [PATCH 45/60] #20183 move current problem contribution to editor status --- .../browser/parts/editor/editorStatus.ts | 135 +++++++++++++++- .../markers/browser/markers.contribution.ts | 148 +----------------- 2 files changed, 135 insertions(+), 148 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index b7ecb1411b05..71ac2878d4ee 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -6,7 +6,7 @@ import 'vs/css!./media/editorstatus'; import * as nls from 'vs/nls'; import { runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom'; -import { format } from 'vs/base/common/strings'; +import { format, compare } from 'vs/base/common/strings'; import { extname, basename, isEqual } from 'vs/base/common/resources'; import { areFunctions, withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; @@ -50,6 +50,8 @@ import { Event } from 'vs/base/common/event'; import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar'; +import { IMarker, IMarkerService, MarkerSeverity, IMarkerData } from 'vs/platform/markers/common/markers'; +import { find } from 'vs/base/common/arrays'; class SideBySideEditorEncodingSupport implements IEncodingSupport { constructor(private master: IEncodingSupport, private details: IEncodingSupport) { } @@ -282,6 +284,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { private readonly eolElement = this._register(new MutableDisposable()); private readonly modeElement = this._register(new MutableDisposable()); private readonly metadataElement = this._register(new MutableDisposable()); + private readonly currentProblemStatus: ShowCurrentMarkerInStatusbarContribution = this._register(this.instantiationService.createInstance(ShowCurrentMarkerInStatusbarContribution)); private readonly state = new State(); private readonly activeEditorListeners = this._register(new DisposableStore()); @@ -299,7 +302,8 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { @IConfigurationService private readonly configurationService: IConfigurationService, @INotificationService private readonly notificationService: INotificationService, @IAccessibilityService private readonly accessibilityService: IAccessibilityService, - @IStatusbarService private readonly statusbarService: IStatusbarService + @IStatusbarService private readonly statusbarService: IStatusbarService, + @IInstantiationService private readonly instantiationService: IInstantiationService, ) { super(); @@ -577,6 +581,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { this.onEncodingChange(activeControl, activeCodeEditor); this.onIndentationChange(activeCodeEditor); this.onMetadataChange(activeControl); + this.currentProblemStatus.update(activeCodeEditor); // Dispose old active editor listeners this.activeEditorListeners.clear(); @@ -594,6 +599,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { // Hook Listener for Selection changes this.activeEditorListeners.add(activeCodeEditor.onDidChangeCursorPosition((event: ICursorPositionChangedEvent) => { this.onSelectionChange(activeCodeEditor); + this.currentProblemStatus.update(activeCodeEditor); })); // Hook Listener for mode changes @@ -604,6 +610,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { // Hook Listener for content changes this.activeEditorListeners.add(activeCodeEditor.onDidChangeModelContent((e) => { this.onEOLChange(activeCodeEditor); + this.currentProblemStatus.update(activeCodeEditor); const selections = activeCodeEditor.getSelections(); if (selections) { @@ -824,6 +831,130 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { } } +class ShowCurrentMarkerInStatusbarContribution extends Disposable { + + private readonly statusBarEntryAccessor: MutableDisposable; + private editor: ICodeEditor | undefined = undefined; + private markers: IMarker[] = []; + private currentMarker: IMarker | null = null; + + constructor( + @IStatusbarService private readonly statusbarService: IStatusbarService, + @IMarkerService private readonly markerService: IMarkerService, + @IConfigurationService private readonly configurationService: IConfigurationService, + ) { + super(); + this.statusBarEntryAccessor = this._register(new MutableDisposable()); + this._register(markerService.onMarkerChanged(changedResources => this.onMarkerChanged(changedResources))); + this._register(Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('problems.showCurrentInStatus'))(() => this.updateStatus())); + } + + update(editor: ICodeEditor | undefined): void { + this.editor = editor; + this.updateStatus(); + } + + private updateStatus(): void { + const previousMarker = this.currentMarker; + this.currentMarker = this.getMarker(); + if (this.hasToUpdateStatus(previousMarker, this.currentMarker)) { + if (this.currentMarker) { + const line = this.currentMarker.message.split(/\r\n|\r|\n/g)[0]; + const text = `${this.getType(this.currentMarker)} ${line}`; + if (!this.statusBarEntryAccessor.value) { + this.statusBarEntryAccessor.value = this.statusbarService.addEntry({ text: '' }, 'statusbar.currentProblem', nls.localize('currentProblem', "Current Problem"), StatusbarAlignment.LEFT); + } + this.statusBarEntryAccessor.value.update({ text }); + } else { + this.statusBarEntryAccessor.clear(); + } + } + } + + private hasToUpdateStatus(previousMarker: IMarker | null, currentMarker: IMarker | null): boolean { + if (!currentMarker) { + return true; + } + if (!previousMarker) { + return true; + } + return IMarkerData.makeKey(previousMarker) !== IMarkerData.makeKey(currentMarker); + } + + private getType(marker: IMarker): string { + switch (marker.severity) { + case MarkerSeverity.Error: return '$(error)'; + case MarkerSeverity.Warning: return '$(warning)'; + case MarkerSeverity.Info: return '$(info)'; + } + return ''; + } + + private getMarker(): IMarker | null { + if (!this.configurationService.getValue('problems.showCurrentInStatus')) { + return null; + } + if (!this.editor) { + return null; + } + const model = this.editor.getModel(); + if (!model) { + return null; + } + const position = this.editor.getPosition(); + if (!position) { + return null; + } + return find(this.markers, marker => Range.containsPosition(marker, position)) || null; + } + + private onMarkerChanged(changedResources: ReadonlyArray): void { + if (!this.editor) { + return; + } + const model = this.editor.getModel(); + if (!model) { + return; + } + if (model && !changedResources.some(r => isEqual(model.uri, r))) { + return; + } + this.updateMarkers(); + } + + private updateMarkers(): void { + if (!this.editor) { + return; + } + const model = this.editor.getModel(); + if (!model) { + return; + } + if (model) { + this.markers = this.markerService.read({ + resource: model.uri, + severities: MarkerSeverity.Error | MarkerSeverity.Warning | MarkerSeverity.Info + }); + this.markers.sort(compareMarker); + } else { + this.markers = []; + } + this.updateStatus(); + } +} + +function compareMarker(a: IMarker, b: IMarker): number { + let res = compare(a.resource.toString(), b.resource.toString()); + if (res === 0) { + res = MarkerSeverity.compare(a.severity, b.severity); + } + if (res === 0) { + res = Range.compareRangesUsingStarts(a, b); + } + return res; +} + + function isWritableCodeEditor(codeEditor: ICodeEditor | undefined): boolean { if (!codeEditor) { return false; diff --git a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts index 48671e13b75a..578642134276 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts @@ -25,21 +25,10 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; import { ActivePanelContext } from 'vs/workbench/common/panel'; -import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar'; -import { IMarkerService, MarkerStatistics, IMarker, MarkerSeverity, IMarkerData } from 'vs/platform/markers/common/markers'; +import { IMarkerService, MarkerStatistics } from 'vs/platform/markers/common/markers'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; -import { IEditorContribution } from 'vs/editor/common/editorCommon'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { Event } from 'vs/base/common/event'; -import { registerEditorContribution } from 'vs/editor/browser/editorExtensions'; -import { URI } from 'vs/base/common/uri'; -import { isEqual } from 'vs/base/common/resources'; -import { find } from 'vs/base/common/arrays'; -import { Range } from 'vs/editor/common/core/range'; -import { compare } from 'vs/base/common/strings'; registerSingleton(IMarkersWorkbenchService, MarkersWorkbenchService, false); @@ -359,136 +348,3 @@ class MarkersStatusBarContributions extends Disposable implements IWorkbenchCont } workbenchRegistry.registerWorkbenchContribution(MarkersStatusBarContributions, LifecyclePhase.Restored); - -class ShowCurrentMarkerInStatusbarContribution extends Disposable implements IEditorContribution { - - public static readonly ID = 'editor.contrib.showCurrentMarkerInStatusbar'; - - private readonly rendererDisposable: MutableDisposable; - - constructor( - private readonly editor: ICodeEditor, - @IConfigurationService private readonly configurationService: IConfigurationService, - @IInstantiationService private readonly instantiationService: IInstantiationService - ) { - super(); - this.rendererDisposable = new MutableDisposable(); - this.onDidConfigurationChange(); - this._register(Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('problems.showCurrentInStatus'))(() => this.onDidConfigurationChange())); - } - - private onDidConfigurationChange(): void { - this.rendererDisposable.clear(); - if (this.configurationService.getValue('problems.showCurrentInStatus')) { - this.rendererDisposable.value = this.instantiationService.createInstance(ShowCurrentMarkerInStatusbarRenderer, this.editor); - } - } -} - -class ShowCurrentMarkerInStatusbarRenderer extends Disposable { - - private readonly statusBarEntryAccessor: MutableDisposable; - private markers: IMarker[] = []; - private currentMarker: IMarker | null = null; - - constructor( - private readonly editor: ICodeEditor, - @IStatusbarService private readonly statusbarService: IStatusbarService, - @IMarkerService private readonly markerService: IMarkerService - ) { - super(); - this.statusBarEntryAccessor = this._register(new MutableDisposable()); - this._register(markerService.onMarkerChanged(changedResources => this.onMarkerChanged(changedResources))); - this._register(editor.onDidChangeModel(() => this.updateMarkers())); - this._register(editor.onDidChangeCursorPosition(() => this.render())); - this.render(); - } - - private render(): void { - const previousMarker = this.currentMarker; - this.currentMarker = this.getMarker(); - if (this.hasToUpdateStatus(previousMarker, this.currentMarker)) { - this.updateStatus(); - } - } - - private hasToUpdateStatus(previousMarker: IMarker | null, currentMarker: IMarker | null): boolean { - if (!currentMarker) { - return true; - } - if (!previousMarker) { - return true; - } - return IMarkerData.makeKey(previousMarker) !== IMarkerData.makeKey(currentMarker); - } - - private updateStatus(): void { - if (this.currentMarker) { - const line = this.currentMarker.message.split(/\r\n|\r|\n/g)[0]; - const text = `${this.getType(this.currentMarker)} ${line}`; - if (this.statusBarEntryAccessor.value) { - this.statusBarEntryAccessor.value.update({ text }); - } else { - this.statusBarEntryAccessor.value = this.statusbarService.addEntry({ text }, 'statusbar.currentProblem', localize('currentProblem', "Current Problem"), StatusbarAlignment.LEFT); - } - } else { - this.statusBarEntryAccessor.clear(); - } - } - - private getType(marker: IMarker): string { - switch (marker.severity) { - case MarkerSeverity.Error: return '$(error)'; - case MarkerSeverity.Warning: return '$(warning)'; - case MarkerSeverity.Info: return '$(info)'; - } - return ''; - } - - private getMarker(): IMarker | null { - const model = this.editor.getModel(); - if (!model) { - return null; - } - const position = this.editor.getPosition(); - if (!position) { - return null; - } - return find(this.markers, marker => Range.containsPosition(marker, position)) || null; - } - - private onMarkerChanged(changedResources: ReadonlyArray): void { - const editorModel = this.editor.getModel(); - if (editorModel && !changedResources.some(r => isEqual(editorModel.uri, r))) { - return; - } - this.updateMarkers(); - } - - private updateMarkers(): void { - const editorModel = this.editor.getModel(); - if (editorModel) { - this.markers = this.markerService.read({ - resource: editorModel.uri, - severities: MarkerSeverity.Error | MarkerSeverity.Warning | MarkerSeverity.Info - }); - this.markers.sort(compareMarker); - } else { - this.markers = []; - } - this.render(); - } -} - -function compareMarker(a: IMarker, b: IMarker): number { - let res = compare(a.resource.toString(), b.resource.toString()); - if (res === 0) { - res = MarkerSeverity.compare(a.severity, b.severity); - } - if (res === 0) { - res = Range.compareRangesUsingStarts(a, b); - } - return res; -} - -registerEditorContribution(ShowCurrentMarkerInStatusbarContribution.ID, ShowCurrentMarkerInStatusbarContribution); From 8e1ce7174b77f58699d98b932c2605dc9efb82c7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Nov 2019 17:46:25 +0100 Subject: [PATCH 46/60] update references view extension --- build/builtInExtensions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/builtInExtensions.json b/build/builtInExtensions.json index 1723a82b4379..3c85dd690d5a 100644 --- a/build/builtInExtensions.json +++ b/build/builtInExtensions.json @@ -31,7 +31,7 @@ }, { "name": "ms-vscode.references-view", - "version": "0.0.34", + "version": "0.0.35", "repo": "https://github.com/Microsoft/vscode-reference-view", "metadata": { "id": "dc489f46-520d-4556-ae85-1f9eab3c412d", From 609c1374ddeb16a9c16f78d553a155267a1777f7 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 12 Nov 2019 09:08:42 -0800 Subject: [PATCH 47/60] Add padding to debug toolbar dropdown --- src/vs/workbench/contrib/debug/browser/media/debugToolBar.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/media/debugToolBar.css b/src/vs/workbench/contrib/debug/browser/media/debugToolBar.css index c16ed97a7b77..a0a76da7ec1d 100644 --- a/src/vs/workbench/contrib/debug/browser/media/debugToolBar.css +++ b/src/vs/workbench/contrib/debug/browser/media/debugToolBar.css @@ -17,9 +17,9 @@ .monaco-workbench .debug-toolbar .monaco-action-bar .action-item.select-container { margin-right: 7px; - } +.monaco-workbench .debug-toolbar .monaco-action-bar .action-item.select-container .monaco-select-box, .monaco-workbench .start-debug-action-item .select-container .monaco-select-box { padding: 0 22px 0 6px; } From d87b077f1ecc5ad9cebb2d31e6353807c0c18687 Mon Sep 17 00:00:00 2001 From: Miguel Solorio Date: Tue, 12 Nov 2019 09:18:31 -0800 Subject: [PATCH 48/60] Update codicons: fix debug stop icon --- .../ui/codiconLabel/codicon/codicon.css | 2 +- .../ui/codiconLabel/codicon/codicon.ttf | Bin 46380 -> 46380 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css b/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css index b5327ffa4835..753d70792994 100644 --- a/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css +++ b/src/vs/base/browser/ui/codiconLabel/codicon/codicon.css @@ -5,7 +5,7 @@ @font-face { font-family: "codicon"; - src: url("./codicon.ttf?7197ad7e38e9644da47ec42494d56501") format("truetype"); + src: url("./codicon.ttf?3443fb4013ab5a04c23a30f912dd6627") format("truetype"); } .codicon[class*='codicon-'] { diff --git a/src/vs/base/browser/ui/codiconLabel/codicon/codicon.ttf b/src/vs/base/browser/ui/codiconLabel/codicon/codicon.ttf index a5b716584910c5d9736ca105d139fb6dc4020648..ba3474205da690928d1da0baa9f557ae33a5b1d3 100644 GIT binary patch delta 89 zcmZ4UifPR&rU?!rN{wQDf6cCnxWaNFWZ`yv(Sr2>`3*9_#=B From 21c09314a89f0a928996af8a7fbacd6df568c838 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 18:34:08 +0100 Subject: [PATCH 49/60] files - add auto save config service --- .../common/instantiationService.ts | 2 +- .../browser/parts/editor/textDiffEditor.ts | 4 +- .../browser/parts/editor/textEditor.ts | 8 +- .../parts/editor/textResourceEditor.ts | 11 +- .../parts/quickopen/quickOpenController.ts | 8 +- .../backup/common/backupModelTracker.ts | 8 +- .../files/browser/editors/textFileEditor.ts | 6 +- .../files/browser/fileActions.contribution.ts | 2 +- .../contrib/files/browser/fileActions.ts | 21 +-- .../files/browser/views/openEditorsView.ts | 8 +- .../files/common/dirtyFilesIndicator.ts | 8 +- .../files/common/editors/fileEditorInput.ts | 8 +- .../files/electron-browser/textFileEditor.ts | 6 +- .../contrib/output/browser/logViewer.ts | 6 +- .../contrib/output/browser/outputPanel.ts | 6 +- .../preferences/browser/preferencesEditor.ts | 6 +- .../common/autoSaveConfigurationService.ts | 158 ++++++++++++++++++ .../textfile/browser/textFileService.ts | 95 ++--------- .../textfile/common/textFileEditorModel.ts | 10 +- .../services/textfile/common/textfiles.ts | 29 ---- .../electron-browser/nativeTextFileService.ts | 8 +- .../test/common/workingCopyService.test.ts | 7 +- .../workbench/test/workbenchTestServices.ts | 17 +- src/vs/workbench/workbench.common.main.ts | 1 + 24 files changed, 265 insertions(+), 178 deletions(-) create mode 100644 src/vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService.ts diff --git a/src/vs/platform/instantiation/common/instantiationService.ts b/src/vs/platform/instantiation/common/instantiationService.ts index 44be0d247979..f4b681204c86 100644 --- a/src/vs/platform/instantiation/common/instantiationService.ts +++ b/src/vs/platform/instantiation/common/instantiationService.ts @@ -157,7 +157,7 @@ export class InstantiationService implements IInstantiationService { graph.lookupOrInsertNode(item); // a weak but working heuristic for cycle checks - if (cycleCount++ > 100) { + if (cycleCount++ > 150) { throw new CyclicDependencyError(graph); } diff --git a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts index e4d132cc598c..8d4f411c71c5 100644 --- a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts @@ -33,6 +33,7 @@ import { EditorMemento } from 'vs/workbench/browser/parts/editor/baseEditor'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { EditorActivation, IEditorOptions } from 'vs/platform/editor/common/editor'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; /** * The text editor that leverages the diff text editor for the editing experience. @@ -55,8 +56,9 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor { @ITextFileService textFileService: ITextFileService, @IHostService hostService: IHostService, @IClipboardService private _clipboardService: IClipboardService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(TextDiffEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService); + super(TextDiffEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService, autoSaveConfigurationService); } protected getEditorMemento(editorGroupService: IEditorGroupsService, key: string, limit: number = 10): IEditorMemento { diff --git a/src/vs/workbench/browser/parts/editor/textEditor.ts b/src/vs/workbench/browser/parts/editor/textEditor.ts index ab5403342c39..d7042a433102 100644 --- a/src/vs/workbench/browser/parts/editor/textEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textEditor.ts @@ -16,7 +16,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; -import { ITextFileService, SaveReason, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, SaveReason } from 'vs/workbench/services/textfile/common/textfiles'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; import { isDiffEditor, isCodeEditor, getCodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -24,6 +24,7 @@ import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor import { CancellationToken } from 'vs/base/common/cancellation'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; const TEXT_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'textEditorViewState'; @@ -53,7 +54,8 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor { @ITextFileService private readonly _textFileService: ITextFileService, @IEditorService protected editorService: IEditorService, @IEditorGroupsService protected editorGroupService: IEditorGroupsService, - @IHostService private readonly hostService: IHostService + @IHostService private readonly hostService: IHostService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(id, telemetryService, themeService, storageService); @@ -165,7 +167,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor { } private maybeTriggerSaveAll(reason: SaveReason): void { - const mode = this.textFileService.getAutoSaveMode(); + const mode = this.autoSaveConfigurationService.getAutoSaveMode(); // Determine if we need to save all. In case of a window focus change we also save if auto save mode // is configured to be ON_FOCUS_CHANGE (editor focus change) diff --git a/src/vs/workbench/browser/parts/editor/textResourceEditor.ts b/src/vs/workbench/browser/parts/editor/textResourceEditor.ts index 640af28854b2..b4e50ce6a8f1 100644 --- a/src/vs/workbench/browser/parts/editor/textResourceEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textResourceEditor.ts @@ -24,6 +24,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor import { CancellationToken } from 'vs/base/common/cancellation'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; /** * An editor implementation that is capable of showing the contents of resource inputs. Uses @@ -41,9 +42,10 @@ export class AbstractTextResourceEditor extends BaseTextEditor { @IEditorGroupsService editorGroupService: IEditorGroupsService, @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, - @IHostService hostService: IHostService + @IHostService hostService: IHostService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(id, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService); + super(id, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService, autoSaveConfigurationService); } getTitle(): string | undefined { @@ -205,8 +207,9 @@ export class TextResourceEditor extends AbstractTextResourceEditor { @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, @IEditorGroupsService editorGroupService: IEditorGroupsService, - @IHostService hostService: IHostService + @IHostService hostService: IHostService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(TextResourceEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, editorGroupService, textFileService, editorService, hostService); + super(TextResourceEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, editorGroupService, textFileService, editorService, hostService, autoSaveConfigurationService); } } diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 945da6272a87..80aab18b2592 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -16,7 +16,7 @@ import { Mode, IEntryRunContext, IAutoFocus, IQuickNavigateConfiguration, IModel import { QuickOpenEntry, QuickOpenModel, QuickOpenEntryGroup, QuickOpenItemAccessorClass } from 'vs/base/parts/quickopen/browser/quickOpenModel'; import { QuickOpenWidget, HideReason } from 'vs/base/parts/quickopen/browser/quickOpenWidget'; import { ContributableActionProvider } from 'vs/workbench/browser/actions'; -import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { Registry } from 'vs/platform/registry/common/platform'; import { IResourceInput } from 'vs/platform/editor/common/editor'; import { IModeService } from 'vs/editor/common/services/modeService'; @@ -51,6 +51,7 @@ import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/commo import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; const HELP_PREFIX = '?'; @@ -735,7 +736,8 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { @ITextFileService private readonly textFileService: ITextFileService, @IConfigurationService private readonly configurationService: IConfigurationService, @ILabelService labelService: ILabelService, - @IFileService fileService: IFileService + @IFileService fileService: IFileService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(editorService); @@ -753,7 +755,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry { this.description = labelService.getUriLabel(resources.dirname(this.resource), { relative: true }); this.dirty = this.resource && this.textFileService.isDirty(this.resource); - if (this.dirty && this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + if (this.dirty && this.autoSaveConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { this.dirty = false; // no dirty decoration if auto save is on with a short timeout } } diff --git a/src/vs/workbench/contrib/backup/common/backupModelTracker.ts b/src/vs/workbench/contrib/backup/common/backupModelTracker.ts index 484a7ddce401..21d022ec1b72 100644 --- a/src/vs/workbench/contrib/backup/common/backupModelTracker.ts +++ b/src/vs/workbench/contrib/backup/common/backupModelTracker.ts @@ -6,10 +6,11 @@ import { URI as Uri } from 'vs/base/common/uri'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { Disposable } from 'vs/base/common/lifecycle'; -import { ITextFileService, TextFileModelChangeEvent, StateChange, IAutoSaveConfiguration } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, TextFileModelChangeEvent, StateChange } from 'vs/workbench/services/textfile/common/textfiles'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files'; +import { IAutoSaveConfigurationService, IAutoSaveConfiguration } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; const AUTO_SAVE_AFTER_DELAY_DISABLED_TIME = CONTENT_CHANGE_EVENT_BUFFER_DELAY + 500; @@ -21,6 +22,7 @@ export class BackupModelTracker extends Disposable implements IWorkbenchContribu @IBackupFileService private readonly backupFileService: IBackupFileService, @ITextFileService private readonly textFileService: ITextFileService, @IUntitledTextEditorService private readonly untitledTextEditorService: IUntitledTextEditorService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(); @@ -38,8 +40,8 @@ export class BackupModelTracker extends Disposable implements IWorkbenchContribu this._register(this.untitledTextEditorService.onDidChangeContent(e => this.onUntitledModelChanged(e))); this._register(this.untitledTextEditorService.onDidDisposeModel(e => this.discardBackup(e))); - // Listen to config changes - this._register(this.textFileService.onAutoSaveConfigurationChange(c => this.onAutoSaveConfigurationChange(c))); + // Listen to auto save config changes + this._register(this.autoSaveConfigurationService.onAutoSaveConfigurationChange(c => this.onAutoSaveConfigurationChange(c))); } private onAutoSaveConfigurationChange(configuration: IAutoSaveConfiguration): void { diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts index 922532520032..b683a64070ae 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditor.ts @@ -32,6 +32,7 @@ import { IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor'; import { createErrorWithActions } from 'vs/base/common/errorsWithActions'; import { MutableDisposable } from 'vs/base/common/lifecycle'; import { EditorActivation, IEditorOptions } from 'vs/platform/editor/common/editor'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; /** * An implementation of editor for file system resources. @@ -56,9 +57,10 @@ export class TextFileEditor extends BaseTextEditor { @IEditorGroupsService editorGroupService: IEditorGroupsService, @ITextFileService textFileService: ITextFileService, @IHostService hostService: IHostService, - @IExplorerService private readonly explorerService: IExplorerService + @IExplorerService private readonly explorerService: IExplorerService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(TextFileEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService); + super(TextFileEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService, autoSaveConfigurationService); this.updateRestoreViewStateConfiguration(); diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index cec21f34551a..1fb26f4e7639 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -18,7 +18,7 @@ import { isMacintosh } from 'vs/base/common/platform'; import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceNotReadonlyContext, ExplorerResourceCut, IExplorerService, ExplorerResourceMoveableToTrash, ExplorerViewletVisibleContext } from 'vs/workbench/contrib/files/common/files'; import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL } from 'vs/workbench/browser/actions/workspaceCommands'; import { CLOSE_SAVED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands'; -import { AutoSaveContext } from 'vs/workbench/services/textfile/common/textfiles'; +import { AutoSaveContext } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; import { ResourceContextKey } from 'vs/workbench/common/resources'; import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService'; import { URI } from 'vs/base/common/uri'; diff --git a/src/vs/workbench/contrib/files/browser/fileActions.ts b/src/vs/workbench/contrib/files/browser/fileActions.ts index ec20bae93dde..38d7fbac179e 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.ts @@ -5,7 +5,6 @@ import 'vs/css!./media/fileactions'; import * as nls from 'vs/nls'; -import * as types from 'vs/base/common/types'; import { isWindows, isWeb } from 'vs/base/common/platform'; import * as extpath from 'vs/base/common/extpath'; import { extname, basename } from 'vs/base/common/path'; @@ -17,7 +16,7 @@ import { Action } from 'vs/base/common/actions'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { VIEWLET_ID, IExplorerService, IFilesConfiguration } from 'vs/workbench/contrib/files/common/files'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { IFileService, AutoSaveConfiguration } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { toResource, SideBySideEditor } from 'vs/workbench/common/editor'; import { ExplorerViewlet } from 'vs/workbench/contrib/files/browser/explorerViewlet'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; @@ -47,6 +46,7 @@ import { ExplorerItem, NewExplorerItem } from 'vs/workbench/contrib/files/common import { onUnexpectedError, getErrorMessage } from 'vs/base/common/errors'; import { asDomUri, triggerDownload } from 'vs/base/browser/dom'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export const NEW_FILE_COMMAND_ID = 'explorer.newFile'; export const NEW_FILE_LABEL = nls.localize('newFile', "New File"); @@ -496,26 +496,13 @@ export class ToggleAutoSaveAction extends Action { constructor( id: string, label: string, - @IConfigurationService private readonly configurationService: IConfigurationService + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(id, label); } run(): Promise { - const setting = this.configurationService.inspect('files.autoSave'); - let userAutoSaveConfig = setting.user; - if (types.isUndefinedOrNull(userAutoSaveConfig)) { - userAutoSaveConfig = setting.default; // use default if setting not defined - } - - let newAutoSaveValue: string; - if ([AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE].some(s => s === userAutoSaveConfig)) { - newAutoSaveValue = AutoSaveConfiguration.OFF; - } else { - newAutoSaveValue = AutoSaveConfiguration.AFTER_DELAY; - } - - return this.configurationService.updateValue('files.autoSave', newAutoSaveValue, ConfigurationTarget.USER); + return this.autoSaveConfigurationService.toggleAutoSave(); } } diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index abbc65cacaeb..a182f6f962ca 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -15,7 +15,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IEditorInput, Verbosity } from 'vs/workbench/common/editor'; import { SaveAllAction, SaveAllInGroupAction, CloseGroupAction } from 'vs/workbench/contrib/files/browser/fileActions'; import { OpenEditorsFocusedContext, ExplorerFocusedContext, IFilesConfiguration, OpenEditor } from 'vs/workbench/contrib/files/common/files'; -import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; import { CloseAllEditorsAction, CloseEditorAction } from 'vs/workbench/browser/parts/editor/editorActions'; import { ToggleEditorLayoutAction } from 'vs/workbench/browser/actions/layoutActions'; @@ -43,6 +43,7 @@ import { ElementsDragAndDropData, DesktopDragAndDropData } from 'vs/base/browser import { URI } from 'vs/base/common/uri'; import { withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types'; import { isWeb } from 'vs/base/common/platform'; +import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; const $ = dom.$; @@ -76,7 +77,8 @@ export class OpenEditorsView extends ViewletPanel { @IContextKeyService private readonly contextKeyService: IContextKeyService, @IThemeService private readonly themeService: IThemeService, @ITelemetryService private readonly telemetryService: ITelemetryService, - @IMenuService private readonly menuService: IMenuService + @IMenuService private readonly menuService: IMenuService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super({ ...(options as IViewletPanelOptions), @@ -413,7 +415,7 @@ export class OpenEditorsView extends ViewletPanel { } private updateDirtyIndicator(): void { - let dirty = this.textFileService.getAutoSaveMode() !== AutoSaveMode.AFTER_SHORT_DELAY ? this.textFileService.getDirty().length + let dirty = this.autoSaveConfigurationService.getAutoSaveMode() !== AutoSaveMode.AFTER_SHORT_DELAY ? this.textFileService.getDirty().length : this.untitledTextEditorService.getDirty().length; if (dirty === 0) { dom.addClass(this.dirtyCountElement, 'hidden'); diff --git a/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts index 515a11480ba2..0513fcc3cf2c 100644 --- a/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts +++ b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts @@ -6,11 +6,11 @@ import * as nls from 'vs/nls'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { VIEWLET_ID } from 'vs/workbench/contrib/files/common/files'; -import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IWorkingCopyService, IWorkingCopy, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export class DirtyFilesIndicator extends Disposable implements IWorkbenchContribution { private readonly badgeHandle = this._register(new MutableDisposable()); @@ -22,10 +22,10 @@ export class DirtyFilesIndicator extends Disposable implements IWorkbenchContrib } constructor( - @ITextFileService private readonly textFileService: ITextFileService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IActivityService private readonly activityService: IActivityService, - @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService + @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(); @@ -42,7 +42,7 @@ export class DirtyFilesIndicator extends Disposable implements IWorkbenchContrib } private onWorkingCopyDidChangeDirty(copy: IWorkingCopy): void { - if (!!(copy.capabilities & WorkingCopyCapabilities.AutoSave) && this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + if (!!(copy.capabilities & WorkingCopyCapabilities.AutoSave) && this.autoSaveConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { return; // do not indicate changes to working copies that are auto saved after short delay } diff --git a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts index 399c49196c9f..d4efe1d00847 100644 --- a/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts @@ -11,12 +11,13 @@ import { EncodingMode, ConfirmResult, EditorInput, IFileEditorInput, ITextEditor import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel'; import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files'; -import { ITextFileService, AutoSaveMode, ModelState, TextFileModelChangeEvent, LoadReason, TextFileOperationError, TextFileOperationResult } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, ModelState, TextFileModelChangeEvent, LoadReason, TextFileOperationError, TextFileOperationResult } from 'vs/workbench/services/textfile/common/textfiles'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IReference } from 'vs/base/common/lifecycle'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { FILE_EDITOR_INPUT_ID, TEXT_FILE_EDITOR_ID, BINARY_FILE_EDITOR_ID } from 'vs/workbench/contrib/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; +import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; const enum ForceOpenAs { None, @@ -49,7 +50,8 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { @ITextFileService private readonly textFileService: ITextFileService, @ITextModelService private readonly textModelResolverService: ITextModelService, @ILabelService private readonly labelService: ILabelService, - @IFileService private readonly fileService: IFileService + @IFileService private readonly fileService: IFileService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(); @@ -234,7 +236,7 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { return true; // always indicate dirty state if we are in conflict or error state } - if (this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + if (this.autoSaveConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { return false; // fast auto save enabled so we do not declare dirty } diff --git a/src/vs/workbench/contrib/files/electron-browser/textFileEditor.ts b/src/vs/workbench/contrib/files/electron-browser/textFileEditor.ts index 18624e12e9a6..d2b5d4aa360c 100644 --- a/src/vs/workbench/contrib/files/electron-browser/textFileEditor.ts +++ b/src/vs/workbench/contrib/files/electron-browser/textFileEditor.ts @@ -25,6 +25,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IExplorerService } from 'vs/workbench/contrib/files/common/files'; import { IElectronService } from 'vs/platform/electron/node/electron'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; /** * An implementation of editor for file system resources. @@ -46,9 +47,10 @@ export class NativeTextFileEditor extends TextFileEditor { @IElectronService private readonly electronService: IElectronService, @IPreferencesService private readonly preferencesService: IPreferencesService, @IHostService hostService: IHostService, - @IExplorerService explorerService: IExplorerService + @IExplorerService explorerService: IExplorerService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(telemetryService, fileService, viewletService, instantiationService, contextService, storageService, configurationService, editorService, themeService, editorGroupService, textFileService, hostService, explorerService); + super(telemetryService, fileService, viewletService, instantiationService, contextService, storageService, configurationService, editorService, themeService, editorGroupService, textFileService, hostService, explorerService, autoSaveConfigurationService); } protected handleSetInputError(error: Error, input: FileEditorInput, options: EditorOptions | undefined): void { diff --git a/src/vs/workbench/contrib/output/browser/logViewer.ts b/src/vs/workbench/contrib/output/browser/logViewer.ts index ce500dfe4a33..31ee5aac4621 100644 --- a/src/vs/workbench/contrib/output/browser/logViewer.ts +++ b/src/vs/workbench/contrib/output/browser/logViewer.ts @@ -20,6 +20,7 @@ import { LOG_SCHEME, IFileOutputChannelDescriptor } from 'vs/workbench/contrib/o import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IHostService } from 'vs/workbench/services/host/browser/host'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export class LogViewerInput extends ResourceEditorInput { @@ -54,9 +55,10 @@ export class LogViewer extends AbstractTextResourceEditor { @IEditorGroupsService editorGroupService: IEditorGroupsService, @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, - @IHostService hostService: IHostService + @IHostService hostService: IHostService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(LogViewer.LOG_VIEWER_EDITOR_ID, telemetryService, instantiationService, storageService, textResourceConfigurationService, themeService, editorGroupService, textFileService, editorService, hostService); + super(LogViewer.LOG_VIEWER_EDITOR_ID, telemetryService, instantiationService, storageService, textResourceConfigurationService, themeService, editorGroupService, textFileService, editorService, hostService, autoSaveConfigurationService); } protected getConfigurationOverrides(): IEditorOptions { diff --git a/src/vs/workbench/contrib/output/browser/outputPanel.ts b/src/vs/workbench/contrib/output/browser/outputPanel.ts index d9eeefed5111..c2e14e0763a2 100644 --- a/src/vs/workbench/contrib/output/browser/outputPanel.ts +++ b/src/vs/workbench/contrib/output/browser/outputPanel.ts @@ -26,6 +26,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export class OutputPanel extends AbstractTextResourceEditor { private actions: IAction[] | undefined; @@ -44,9 +45,10 @@ export class OutputPanel extends AbstractTextResourceEditor { @IEditorGroupsService editorGroupService: IEditorGroupsService, @ITextFileService textFileService: ITextFileService, @IEditorService editorService: IEditorService, - @IHostService hostService: IHostService + @IHostService hostService: IHostService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(OUTPUT_PANEL_ID, telemetryService, instantiationService, storageService, textResourceConfigurationService, themeService, editorGroupService, textFileService, editorService, hostService); + super(OUTPUT_PANEL_ID, telemetryService, instantiationService, storageService, textResourceConfigurationService, themeService, editorGroupService, textFileService, editorService, hostService, autoSaveConfigurationService); this.scopedInstantiationService = instantiationService; } diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts index abec70f1f281..8c5d0468c3e1 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesEditor.ts @@ -55,6 +55,7 @@ import { DefaultSettingsEditorModel, SettingsEditorModel } from 'vs/workbench/se import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { IHostService } from 'vs/workbench/services/host/browser/host'; import { withNullAsUndefined, withUndefinedAsNull, assertIsDefined } from 'vs/base/common/types'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export class PreferencesEditor extends BaseEditor { @@ -981,9 +982,10 @@ export class DefaultPreferencesEditor extends BaseTextEditor { @ITextFileService textFileService: ITextFileService, @IEditorGroupsService editorGroupService: IEditorGroupsService, @IEditorService editorService: IEditorService, - @IHostService hostService: IHostService + @IHostService hostService: IHostService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(DefaultPreferencesEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService); + super(DefaultPreferencesEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService, autoSaveConfigurationService); } private static _getContributions(): IEditorContributionDescription[] { diff --git a/src/vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService.ts b/src/vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService.ts new file mode 100644 index 000000000000..9e7ac720a44b --- /dev/null +++ b/src/vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService.ts @@ -0,0 +1,158 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { Event, Emitter } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; +import { IFilesConfiguration, AutoSaveConfiguration } from 'vs/platform/files/common/files'; +import { isUndefinedOrNull } from 'vs/base/common/types'; + +export const AutoSaveContext = new RawContextKey('config.files.autoSave', undefined); + +export interface IAutoSaveConfiguration { + autoSaveDelay?: number; + autoSaveFocusChange: boolean; + autoSaveApplicationChange: boolean; +} + +export const enum AutoSaveMode { + OFF, + AFTER_SHORT_DELAY, + AFTER_LONG_DELAY, + ON_FOCUS_CHANGE, + ON_WINDOW_CHANGE +} + +export const IAutoSaveConfigurationService = createDecorator('autoSaveConfigurationService'); + +export interface IAutoSaveConfigurationService { + + _serviceBrand: undefined; + + readonly onAutoSaveConfigurationChange: Event; + + getAutoSaveMode(): AutoSaveMode; + + getAutoSaveConfiguration(): IAutoSaveConfiguration; + + toggleAutoSave(): Promise; +} + +export class AutoSaveConfigurationService extends Disposable implements IAutoSaveConfigurationService { + + _serviceBrand: undefined; + + private readonly _onAutoSaveConfigurationChange = this._register(new Emitter()); + readonly onAutoSaveConfigurationChange = this._onAutoSaveConfigurationChange.event; + + private configuredAutoSaveDelay?: number; + private configuredAutoSaveOnFocusChange: boolean | undefined; + private configuredAutoSaveOnWindowChange: boolean | undefined; + + private autoSaveContext: IContextKey; + + constructor( + @IContextKeyService contextKeyService: IContextKeyService, + @IConfigurationService private readonly configurationService: IConfigurationService + ) { + super(); + + this.autoSaveContext = AutoSaveContext.bindTo(contextKeyService); + + const configuration = configurationService.getValue(); + this.onFilesConfigurationChange(configuration); + + this.registerListeners(); + } + + private registerListeners(): void { + + // Files configuration changes + this._register(this.configurationService.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('files')) { + this.onFilesConfigurationChange(this.configurationService.getValue()); + } + })); + } + + private onFilesConfigurationChange(configuration: IFilesConfiguration): void { + const autoSaveMode = configuration?.files?.autoSave || AutoSaveConfiguration.OFF; + this.autoSaveContext.set(autoSaveMode); + switch (autoSaveMode) { + case AutoSaveConfiguration.AFTER_DELAY: + this.configuredAutoSaveDelay = configuration?.files?.autoSaveDelay; + this.configuredAutoSaveOnFocusChange = false; + this.configuredAutoSaveOnWindowChange = false; + break; + + case AutoSaveConfiguration.ON_FOCUS_CHANGE: + this.configuredAutoSaveDelay = undefined; + this.configuredAutoSaveOnFocusChange = true; + this.configuredAutoSaveOnWindowChange = false; + break; + + case AutoSaveConfiguration.ON_WINDOW_CHANGE: + this.configuredAutoSaveDelay = undefined; + this.configuredAutoSaveOnFocusChange = false; + this.configuredAutoSaveOnWindowChange = true; + break; + + default: + this.configuredAutoSaveDelay = undefined; + this.configuredAutoSaveOnFocusChange = false; + this.configuredAutoSaveOnWindowChange = false; + break; + } + + // Emit as event + this._onAutoSaveConfigurationChange.fire(this.getAutoSaveConfiguration()); + } + + getAutoSaveMode(): AutoSaveMode { + if (this.configuredAutoSaveOnFocusChange) { + return AutoSaveMode.ON_FOCUS_CHANGE; + } + + if (this.configuredAutoSaveOnWindowChange) { + return AutoSaveMode.ON_WINDOW_CHANGE; + } + + if (this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0) { + return this.configuredAutoSaveDelay <= 1000 ? AutoSaveMode.AFTER_SHORT_DELAY : AutoSaveMode.AFTER_LONG_DELAY; + } + + return AutoSaveMode.OFF; + } + + getAutoSaveConfiguration(): IAutoSaveConfiguration { + return { + autoSaveDelay: this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0 ? this.configuredAutoSaveDelay : undefined, + autoSaveFocusChange: !!this.configuredAutoSaveOnFocusChange, + autoSaveApplicationChange: !!this.configuredAutoSaveOnWindowChange + }; + } + + async toggleAutoSave(): Promise { + const setting = this.configurationService.inspect('files.autoSave'); + let userAutoSaveConfig = setting.user; + if (isUndefinedOrNull(userAutoSaveConfig)) { + userAutoSaveConfig = setting.default; // use default if setting not defined + } + + let newAutoSaveValue: string; + if ([AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE].some(s => s === userAutoSaveConfig)) { + newAutoSaveValue = AutoSaveConfiguration.OFF; + } else { + newAutoSaveValue = AutoSaveConfiguration.AFTER_DELAY; + } + + return this.configurationService.updateValue('files.autoSave', newAutoSaveValue, ConfigurationTarget.USER); + } +} + +registerSingleton(IAutoSaveConfigurationService, AutoSaveConfigurationService); diff --git a/src/vs/workbench/services/textfile/browser/textFileService.ts b/src/vs/workbench/services/textfile/browser/textFileService.ts index 7a68d53bd7a9..ea66d626d2e3 100644 --- a/src/vs/workbench/services/textfile/browser/textFileService.ts +++ b/src/vs/workbench/services/textfile/browser/textFileService.ts @@ -9,11 +9,11 @@ import * as objects from 'vs/base/common/objects'; import { Emitter, AsyncEmitter } from 'vs/base/common/event'; import * as platform from 'vs/base/common/platform'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; -import { IResult, ITextFileOperationResult, ITextFileService, ITextFileStreamContent, IAutoSaveConfiguration, AutoSaveMode, SaveReason, ITextFileEditorModelManager, ITextFileEditorModel, ModelState, ISaveOptions, AutoSaveContext, ITextFileContent, IResourceEncodings, IReadTextFileOptions, IWriteTextFileOptions, toBufferOrReadable, TextFileOperationError, TextFileOperationResult, FileOperationWillRunEvent, FileOperationDidRunEvent } from 'vs/workbench/services/textfile/common/textfiles'; +import { IResult, ITextFileOperationResult, ITextFileService, ITextFileStreamContent, SaveReason, ITextFileEditorModelManager, ITextFileEditorModel, ModelState, ISaveOptions, ITextFileContent, IResourceEncodings, IReadTextFileOptions, IWriteTextFileOptions, toBufferOrReadable, TextFileOperationError, TextFileOperationResult, FileOperationWillRunEvent, FileOperationDidRunEvent } from 'vs/workbench/services/textfile/common/textfiles'; import { ConfirmResult, IRevertOptions } from 'vs/workbench/common/editor'; import { ILifecycleService, ShutdownReason, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; -import { IFileService, IFilesConfiguration, FileOperationError, FileOperationResult, AutoSaveConfiguration, HotExitConfiguration, IFileStatWithMetadata, ICreateFileOptions, FileOperation } from 'vs/platform/files/common/files'; +import { IFileService, IFilesConfiguration, FileOperationError, FileOperationResult, HotExitConfiguration, IFileStatWithMetadata, ICreateFileOptions, FileOperation } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -24,7 +24,6 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ResourceMap } from 'vs/base/common/map'; import { Schemas } from 'vs/base/common/network'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; -import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { createTextBufferFactoryFromSnapshot, createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel'; import { IModelService } from 'vs/editor/common/services/modelService'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; @@ -38,6 +37,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { ITextSnapshot } from 'vs/editor/common/model'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; +import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; /** * The workbench file service implementation implements the raw file service spec and adds additional methods on top. @@ -48,9 +48,6 @@ export abstract class AbstractTextFileService extends Disposable implements ITex //#region events - private readonly _onAutoSaveConfigurationChange = this._register(new Emitter()); - readonly onAutoSaveConfigurationChange = this._onAutoSaveConfigurationChange.event; - private readonly _onFilesAssociationChange = this._register(new Emitter()); readonly onFilesAssociationChange = this._onFilesAssociationChange.event; @@ -68,11 +65,8 @@ export abstract class AbstractTextFileService extends Disposable implements ITex abstract get encoding(): IResourceEncodings; private currentFilesAssociationConfig: { [key: string]: string; }; - private configuredAutoSaveDelay?: number; - private configuredAutoSaveOnFocusChange: boolean | undefined; - private configuredAutoSaveOnWindowChange: boolean | undefined; + private configuredHotExit: string | undefined; - private autoSaveContext: IContextKey; constructor( @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @@ -87,22 +81,19 @@ export abstract class AbstractTextFileService extends Disposable implements ITex @INotificationService private readonly notificationService: INotificationService, @IBackupFileService private readonly backupFileService: IBackupFileService, @IHistoryService private readonly historyService: IHistoryService, - @IContextKeyService contextKeyService: IContextKeyService, @IDialogService private readonly dialogService: IDialogService, @IFileDialogService private readonly fileDialogService: IFileDialogService, @IEditorService private readonly editorService: IEditorService, - @ITextResourceConfigurationService protected readonly textResourceConfigurationService: ITextResourceConfigurationService + @ITextResourceConfigurationService protected readonly textResourceConfigurationService: ITextResourceConfigurationService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(); this._models = this._register(instantiationService.createInstance(TextFileEditorModelManager)); - this.autoSaveContext = AutoSaveContext.bindTo(contextKeyService); const configuration = configurationService.getValue(); this.currentFilesAssociationConfig = configuration?.files?.associations; - this.onFilesConfigurationChange(configuration); - this.registerListeners(); } @@ -120,6 +111,17 @@ export abstract class AbstractTextFileService extends Disposable implements ITex this.onFilesConfigurationChange(this.configurationService.getValue()); } })); + + // Auto save changes + this._register(this.autoSaveConfigurationService.onAutoSaveConfigurationChange(() => this.onAutoSaveConfigurationChange())); + } + + private onAutoSaveConfigurationChange(): void { + + // save all dirty when enabling auto save + if (this.autoSaveConfigurationService.getAutoSaveMode() !== AutoSaveMode.OFF) { + this.saveAll(); + } } protected onBeforeShutdown(reason: ShutdownReason): boolean | Promise { @@ -130,7 +132,7 @@ export abstract class AbstractTextFileService extends Disposable implements ITex // If auto save is enabled, save all files and then check again for dirty files // We DO NOT run any save participant if we are in the shutdown phase for performance reasons - if (this.getAutoSaveMode() !== AutoSaveMode.OFF) { + if (this.autoSaveConfigurationService.getAutoSaveMode() !== AutoSaveMode.OFF) { return this.saveAll(false /* files only */, { skipSaveParticipants: true }).then(() => { // If we still have dirty files, we either have untitled ones or files that cannot be saved @@ -302,43 +304,6 @@ export abstract class AbstractTextFileService extends Disposable implements ITex } protected onFilesConfigurationChange(configuration: IFilesConfiguration): void { - const wasAutoSaveEnabled = (this.getAutoSaveMode() !== AutoSaveMode.OFF); - - const autoSaveMode = configuration?.files?.autoSave || AutoSaveConfiguration.OFF; - this.autoSaveContext.set(autoSaveMode); - switch (autoSaveMode) { - case AutoSaveConfiguration.AFTER_DELAY: - this.configuredAutoSaveDelay = configuration?.files?.autoSaveDelay; - this.configuredAutoSaveOnFocusChange = false; - this.configuredAutoSaveOnWindowChange = false; - break; - - case AutoSaveConfiguration.ON_FOCUS_CHANGE: - this.configuredAutoSaveDelay = undefined; - this.configuredAutoSaveOnFocusChange = true; - this.configuredAutoSaveOnWindowChange = false; - break; - - case AutoSaveConfiguration.ON_WINDOW_CHANGE: - this.configuredAutoSaveDelay = undefined; - this.configuredAutoSaveOnFocusChange = false; - this.configuredAutoSaveOnWindowChange = true; - break; - - default: - this.configuredAutoSaveDelay = undefined; - this.configuredAutoSaveOnFocusChange = false; - this.configuredAutoSaveOnWindowChange = false; - break; - } - - // Emit as event - this._onAutoSaveConfigurationChange.fire(this.getAutoSaveConfiguration()); - - // save all dirty when enabling auto save - if (!wasAutoSaveEnabled && this.getAutoSaveMode() !== AutoSaveMode.OFF) { - this.saveAll(); - } // Check for change in files associations const filesAssociation = configuration?.files?.associations; @@ -1006,30 +971,6 @@ export abstract class AbstractTextFileService extends Disposable implements ITex //#region config - getAutoSaveMode(): AutoSaveMode { - if (this.configuredAutoSaveOnFocusChange) { - return AutoSaveMode.ON_FOCUS_CHANGE; - } - - if (this.configuredAutoSaveOnWindowChange) { - return AutoSaveMode.ON_WINDOW_CHANGE; - } - - if (this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0) { - return this.configuredAutoSaveDelay <= 1000 ? AutoSaveMode.AFTER_SHORT_DELAY : AutoSaveMode.AFTER_LONG_DELAY; - } - - return AutoSaveMode.OFF; - } - - getAutoSaveConfiguration(): IAutoSaveConfiguration { - return { - autoSaveDelay: this.configuredAutoSaveDelay && this.configuredAutoSaveDelay > 0 ? this.configuredAutoSaveDelay : undefined, - autoSaveFocusChange: !!this.configuredAutoSaveOnFocusChange, - autoSaveApplicationChange: !!this.configuredAutoSaveOnWindowChange - }; - } - get isHotExitEnabled(): boolean { return !this.environmentService.isExtensionDevelopment && this.configuredHotExit !== HotExitConfiguration.OFF; } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index b86d2ed4508d..c50d7ea04042 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -11,7 +11,7 @@ import { URI } from 'vs/base/common/uri'; import { isUndefinedOrNull, assertIsDefined } from 'vs/base/common/types'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ITextFileService, IAutoSaveConfiguration, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, ITextFileStreamContent, ILoadOptions, LoadReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; +import { ITextFileService, ModelState, ITextFileEditorModel, ISaveOptions, ISaveErrorHandler, ISaveParticipant, StateChange, SaveReason, ITextFileStreamContent, ILoadOptions, LoadReason, IResolvedTextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles'; import { EncodingMode } from 'vs/workbench/common/editor'; import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; @@ -30,6 +30,7 @@ import { isEqual, isEqualOrParent, extname, basename, joinPath } from 'vs/base/c import { onUnexpectedError } from 'vs/base/common/errors'; import { Schemas } from 'vs/base/common/network'; import { IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IAutoSaveConfigurationService, IAutoSaveConfiguration } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export interface IBackupMetaData { mtime: number; @@ -121,11 +122,12 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil @IEnvironmentService private readonly environmentService: IEnvironmentService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @ILogService private readonly logService: ILogService, - @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService + @IWorkingCopyService private readonly workingCopyService: IWorkingCopyService, + @IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService ) { super(modelService, modeService); - this.updateAutoSaveConfiguration(textFileService.getAutoSaveConfiguration()); + this.updateAutoSaveConfiguration(autoSaveConfigurationService.getAutoSaveConfiguration()); // Make known to working copy service this._register(this.workingCopyService.registerWorkingCopy(this)); @@ -135,7 +137,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil private registerListeners(): void { this._register(this.fileService.onFileChanges(e => this.onFileChanges(e))); - this._register(this.textFileService.onAutoSaveConfigurationChange(config => this.updateAutoSaveConfiguration(config))); + this._register(this.autoSaveConfigurationService.onAutoSaveConfigurationChange(config => this.updateAutoSaveConfiguration(config))); this._register(this.textFileService.onFilesAssociationChange(e => this.onFilesAssociationChange())); this._register(this.onDidStateChange(e => this.onStateChange(e))); } diff --git a/src/vs/workbench/services/textfile/common/textfiles.ts b/src/vs/workbench/services/textfile/common/textfiles.ts index 4ab9efb61c71..934141270205 100644 --- a/src/vs/workbench/services/textfile/common/textfiles.ts +++ b/src/vs/workbench/services/textfile/common/textfiles.ts @@ -11,7 +11,6 @@ import { IBaseStatWithMetadata, IFileStatWithMetadata, IReadFileOptions, IWriteF import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ITextEditorModel } from 'vs/editor/common/services/resolverService'; import { ITextBufferFactory, ITextModel, ITextSnapshot } from 'vs/editor/common/model'; -import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; import { isUndefinedOrNull } from 'vs/base/common/types'; import { isNative } from 'vs/base/common/platform'; @@ -23,8 +22,6 @@ export interface ITextFileService extends IDisposable { _serviceBrand: undefined; - readonly onAutoSaveConfigurationChange: Event; - readonly onFilesAssociationChange: Event; readonly isHotExitEnabled: boolean; @@ -144,16 +141,6 @@ export interface ITextFileService extends IDisposable { * confirming for all dirty resources. */ confirmSave(resources?: URI[]): Promise; - - /** - * Convenient fast access to the current auto save mode. - */ - getAutoSaveMode(): AutoSaveMode; - - /** - * Convenient fast access to the raw configured auto save settings. - */ - getAutoSaveConfiguration(): IAutoSaveConfiguration; } @@ -341,8 +328,6 @@ export class TextFileModelChangeEvent { } } -export const AutoSaveContext = new RawContextKey('config.files.autoSave', undefined); - export interface ITextFileOperationResult { results: IResult[]; } @@ -353,20 +338,6 @@ export interface IResult { success?: boolean; } -export interface IAutoSaveConfiguration { - autoSaveDelay?: number; - autoSaveFocusChange: boolean; - autoSaveApplicationChange: boolean; -} - -export const enum AutoSaveMode { - OFF, - AFTER_SHORT_DELAY, - AFTER_LONG_DELAY, - ON_FOCUS_CHANGE, - ON_WINDOW_CHANGE -} - export const enum SaveReason { EXPLICIT = 1, AUTO = 2, diff --git a/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts b/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts index 23cf1f058dcd..3a1487ec7796 100644 --- a/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts +++ b/src/vs/workbench/services/textfile/electron-browser/nativeTextFileService.ts @@ -38,11 +38,11 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/ import { INotificationService } from 'vs/platform/notification/common/notification'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; -import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ConfirmResult } from 'vs/workbench/common/editor'; import { assign } from 'vs/base/common/objects'; +import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export class NativeTextFileService extends AbstractTextFileService { @@ -59,15 +59,15 @@ export class NativeTextFileService extends AbstractTextFileService { @INotificationService notificationService: INotificationService, @IBackupFileService backupFileService: IBackupFileService, @IHistoryService historyService: IHistoryService, - @IContextKeyService contextKeyService: IContextKeyService, @IDialogService dialogService: IDialogService, @IFileDialogService fileDialogService: IFileDialogService, @IEditorService editorService: IEditorService, @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService, @IElectronService private readonly electronService: IElectronService, - @IProductService private readonly productService: IProductService + @IProductService private readonly productService: IProductService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { - super(contextService, fileService, untitledTextEditorService, lifecycleService, instantiationService, configurationService, modeService, modelService, environmentService, notificationService, backupFileService, historyService, contextKeyService, dialogService, fileDialogService, editorService, textResourceConfigurationService); + super(contextService, fileService, untitledTextEditorService, lifecycleService, instantiationService, configurationService, modeService, modelService, environmentService, notificationService, backupFileService, historyService, dialogService, fileDialogService, editorService, textResourceConfigurationService, autoSaveConfigurationService); } private _encoding: EncodingOracle | undefined; diff --git a/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts b/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts index 7bff97ff4082..a7797845a175 100644 --- a/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts +++ b/src/vs/workbench/services/workingCopy/test/common/workingCopyService.test.ts @@ -4,10 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { WorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { URI } from 'vs/base/common/uri'; import { Emitter } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; +import { TestWorkingCopyService } from 'vs/workbench/test/workbenchTestServices'; suite('WorkingCopyService', () => { @@ -48,7 +49,7 @@ suite('WorkingCopyService', () => { } test('registry - basics', () => { - const service = new WorkingCopyService(); + const service = new TestWorkingCopyService(); const onDidChangeDirty: IWorkingCopy[] = []; service.onDidChangeDirty(copy => onDidChangeDirty.push(copy)); @@ -104,7 +105,7 @@ suite('WorkingCopyService', () => { }); test('registry - multiple copies on same resource', () => { - const service = new WorkingCopyService(); + const service = new TestWorkingCopyService(); const onDidChangeDirty: IWorkingCopy[] = []; service.onDidChangeDirty(copy => onDidChangeDirty.push(copy)); diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 5d9d717d2bcc..b1e238cb5d5f 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -93,6 +93,7 @@ import { IEmptyWindowBackupInfo } from 'vs/platform/backup/node/backup'; import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; import { find } from 'vs/base/common/arrays'; import { WorkingCopyService, IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; +import { IAutoSaveConfigurationService, AutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); @@ -207,13 +208,13 @@ export class TestTextFileService extends NativeTextFileService { @INotificationService notificationService: INotificationService, @IBackupFileService backupFileService: IBackupFileService, @IHistoryService historyService: IHistoryService, - @IContextKeyService contextKeyService: IContextKeyService, @IDialogService dialogService: IDialogService, @IFileDialogService fileDialogService: IFileDialogService, @IEditorService editorService: IEditorService, @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService, @IElectronService electronService: IElectronService, - @IProductService productService: IProductService + @IProductService productService: IProductService, + @IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService ) { super( contextService, @@ -228,13 +229,13 @@ export class TestTextFileService extends NativeTextFileService { notificationService, backupFileService, historyService, - contextKeyService, dialogService, fileDialogService, editorService, textResourceConfigurationService, electronService, - productService + productService, + autoSaveConfigurationService ); } @@ -297,11 +298,13 @@ export class TestTextFileService extends NativeTextFileService { export function workbenchInstantiationService(): IInstantiationService { let instantiationService = new TestInstantiationService(new ServiceCollection([ILifecycleService, new TestLifecycleService()])); instantiationService.stub(IEnvironmentService, TestEnvironmentService); - instantiationService.stub(IContextKeyService, instantiationService.createInstance(MockContextKeyService)); + const contextKeyService = instantiationService.createInstance(MockContextKeyService); + instantiationService.stub(IContextKeyService, contextKeyService); const workspaceContextService = new TestContextService(TestWorkspace); instantiationService.stub(IWorkspaceContextService, workspaceContextService); const configService = new TestConfigurationService(); instantiationService.stub(IConfigurationService, configService); + instantiationService.stub(IAutoSaveConfigurationService, new AutoSaveConfigurationService(contextKeyService, configService)); instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService)); instantiationService.stub(IUntitledTextEditorService, instantiationService.createInstance(UntitledTextEditorService)); instantiationService.stub(IStorageService, new TestStorageService()); @@ -1467,6 +1470,4 @@ export class TestDialogMainService implements IDialogMainService { } } -export class TestWorkingCopyService extends WorkingCopyService { - -} +export class TestWorkingCopyService extends WorkingCopyService { } diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 8c9f50ad424b..3c0ed98e54e7 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -83,6 +83,7 @@ import 'vs/workbench/services/userDataSync/common/settingsMergeService'; import 'vs/workbench/services/path/common/remotePathService'; import 'vs/workbench/services/remote/common/remoteExplorerService'; import 'vs/workbench/services/workingCopy/common/workingCopyService'; +import 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; From 2d71ad39e00db56028cc33a445d7e2f6e1a9d10f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 18:41:43 +0100 Subject: [PATCH 50/60] fix indicator when auto save is turned on --- .../workbench/contrib/files/common/dirtyFilesIndicator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts index 0513fcc3cf2c..edb4a75e829c 100644 --- a/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts +++ b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts @@ -42,11 +42,11 @@ export class DirtyFilesIndicator extends Disposable implements IWorkbenchContrib } private onWorkingCopyDidChangeDirty(copy: IWorkingCopy): void { - if (!!(copy.capabilities & WorkingCopyCapabilities.AutoSave) && this.autoSaveConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { - return; // do not indicate changes to working copies that are auto saved after short delay + const gotDirty = copy.isDirty(); + if (gotDirty && !!(copy.capabilities & WorkingCopyCapabilities.AutoSave) && this.autoSaveConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) { + return; // do not indicate dirty of working copies that are auto saved after short delay } - const gotDirty = copy.isDirty(); if (gotDirty || this.hasDirtyCount) { this.updateActivityBadge(); } From b66599bbfdc539b6ca622e9b1d8f709a9483bfb9 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 18:45:23 +0100 Subject: [PATCH 51/60] files - fix tests properly --- src/vs/platform/files/test/node/diskFileService.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index 79ecd34d5f08..0b5b1ecf8bc0 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -134,7 +134,7 @@ suite('Disk File Service', function () { // we see random test failures when accessing the native file system. To // diagnose further, we retry node.js file access tests up to 3 times to // rule out any random disk issue. - this.retries(3); + // this.retries(3); setup(async () => { const logService = new NullLogService(); @@ -1493,15 +1493,15 @@ suite('Disk File Service', function () { } test('createFile', async () => { - assertCreateFile(contents => VSBuffer.fromString(contents)); + return assertCreateFile(contents => VSBuffer.fromString(contents)); }); test('createFile (readable)', async () => { - assertCreateFile(contents => bufferToReadable(VSBuffer.fromString(contents))); + return assertCreateFile(contents => bufferToReadable(VSBuffer.fromString(contents))); }); test('createFile (stream)', async () => { - assertCreateFile(contents => bufferToStream(VSBuffer.fromString(contents))); + return assertCreateFile(contents => bufferToStream(VSBuffer.fromString(contents))); }); async function assertCreateFile(converter: (content: string) => VSBuffer | VSBufferReadable | VSBufferReadableStream): Promise { From ddfca307b1bd29da040e82c8389638fc508248aa Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 18:48:27 +0100 Subject: [PATCH 52/60] encoding - still ignore 'ascii' --- src/vs/base/node/encoding.ts | 11 +++++++++++ src/vs/base/test/node/encoding/encoding.test.ts | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vs/base/node/encoding.ts b/src/vs/base/node/encoding.ts index c45032131704..c4cd563ef8f3 100644 --- a/src/vs/base/node/encoding.ts +++ b/src/vs/base/node/encoding.ts @@ -210,6 +210,17 @@ async function guessEncodingByBuffer(buffer: Buffer): Promise { return null; } + // Ignore 'ascii' as guessed encoding because that + // is almost never what we want, rather fallback + // to the configured encoding then. Otherwise, + // opening a ascii-only file with auto guessing + // enabled will put the file into 'ascii' mode + // and thus typing any special characters is + // not possible anymore. + if (guessed.encoding.toLowerCase() === 'ascii') { + return null; + } + return toIconvLiteEncoding(guessed.encoding); } diff --git a/src/vs/base/test/node/encoding/encoding.test.ts b/src/vs/base/test/node/encoding/encoding.test.ts index d8730a52b366..eef17fbddb61 100644 --- a/src/vs/base/test/node/encoding/encoding.test.ts +++ b/src/vs/base/test/node/encoding/encoding.test.ts @@ -200,7 +200,7 @@ suite('Encoding', () => { const file = getPathFromAmdModule(require, './fixtures/some_ansi.css'); const buffer = await readExactlyByFile(file, 512 * 8); const mimes = await encoding.detectEncodingFromBuffer(buffer, true); - assert.equal(mimes.encoding, 'ascii'); + assert.equal(mimes.encoding, null); }); test('autoGuessEncoding (ShiftJIS)', async function () { From 1a1e7c9545001dda62004415de824db918bd65e2 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 18:57:08 +0100 Subject: [PATCH 53/60] debt - allow extHostSearch in common (#84109) * debt - allow extHostSearch in common * web - implement text search provider * fix text search * Update extensions/vscode-api-tests/src/extension.ts Co-Authored-By: Rob Lourens --- extensions/vscode-api-tests/src/extension.ts | 48 ++- src/vs/workbench/api/common/extHostSearch.ts | 119 +++++- src/vs/workbench/api/node/extHost.services.ts | 4 +- src/vs/workbench/api/node/extHostSearch.ts | 119 +----- .../extensions/worker/extHost.services.ts | 4 +- .../search/common/textSearchManager.ts | 355 ++++++++++++++++++ .../services/search/node/textSearchAdapter.ts | 7 +- .../services/search/node/textSearchManager.ts | 350 +---------------- .../test/node/textSearchManager.test.ts | 6 +- .../api/extHostSearch.test.ts | 12 +- 10 files changed, 561 insertions(+), 463 deletions(-) create mode 100644 src/vs/workbench/services/search/common/textSearchManager.ts diff --git a/extensions/vscode-api-tests/src/extension.ts b/extensions/vscode-api-tests/src/extension.ts index a0aabfb09ec8..05646e66dc3a 100644 --- a/extensions/vscode-api-tests/src/extension.ts +++ b/extensions/vscode-api-tests/src/extension.ts @@ -366,9 +366,9 @@ function updateDiagnostics(document: vscode.TextDocument, collection: vscode.Dia } } -function enableSearch(_context: vscode.ExtensionContext, _memFs: MemFS): void { - // NOT YET SUPPORTED - //context.subscriptions.push(vscode.workspace.registerFileSearchProvider(SCHEME, memFs)); +function enableSearch(context: vscode.ExtensionContext, memFs: MemFS): void { + context.subscriptions.push(vscode.workspace.registerFileSearchProvider(SCHEME, memFs)); + context.subscriptions.push(vscode.workspace.registerTextSearchProvider(SCHEME, memFs)); } function enableTasks(): void { @@ -546,7 +546,7 @@ export class Directory implements vscode.FileStat { export type Entry = File | Directory; -export class MemFS implements vscode.FileSystemProvider, vscode.FileSearchProvider { +export class MemFS implements vscode.FileSystemProvider, vscode.FileSearchProvider, vscode.TextSearchProvider { root = new Directory(vscode.Uri.parse('memfs:/'), ''); @@ -796,16 +796,52 @@ export class MemFS implements vscode.FileSystemProvider, vscode.FileSearchProvid // --- search provider provideFileSearchResults(query: vscode.FileSearchQuery, _options: vscode.FileSearchOptions, _token: vscode.CancellationToken): vscode.ProviderResult { + return this._findFiles(query.pattern); + } + + private _findFiles(query: string | undefined): vscode.Uri[] { const files = this._getFiles(); const result: vscode.Uri[] = []; - const pattern = new RegExp(this._convertSimple2RegExpPattern(query.pattern)); + + const pattern = query ? new RegExp(this._convertSimple2RegExpPattern(query)) : null; for (const file of files) { - if (pattern.exec(file.name)) { + if (!pattern || pattern.exec(file.name)) { result.push(file.uri); } } return result; } + + private _textDecoder = new TextDecoder(); + + provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress, _token: vscode.CancellationToken) { + const result: vscode.TextSearchComplete = { limitHit: false }; + + const files = this._findFiles(options.includes[0]); + if (files) { + for (const file of files) { + const content = this._textDecoder.decode(this.readFile(file)); + + const lines = content.split('\n'); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const index = line.indexOf(query.pattern); + if (index !== -1) { + progress.report({ + uri: file, + ranges: new vscode.Range(new vscode.Position(i, index), new vscode.Position(i, index + query.pattern.length)), + preview: { + text: line, + matches: new vscode.Range(new vscode.Position(0, index), new vscode.Position(0, index + query.pattern.length)) + } + }); + } + } + } + } + + return result; + } } diff --git a/src/vs/workbench/api/common/extHostSearch.ts b/src/vs/workbench/api/common/extHostSearch.ts index efc6ca49825e..adc7c29d6ec4 100644 --- a/src/vs/workbench/api/common/extHostSearch.ts +++ b/src/vs/workbench/api/common/extHostSearch.ts @@ -3,10 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDisposable } from 'vs/base/common/lifecycle'; +import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import * as vscode from 'vscode'; -import { ExtHostSearchShape } from '../common/extHost.protocol'; +import { ExtHostSearchShape, MainThreadSearchShape, MainContext } from '../common/extHost.protocol'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { FileSearchManager } from 'vs/workbench/services/search/common/fileSearchManager'; +import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; +import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; +import { ILogService } from 'vs/platform/log/common/log'; +import { IRawFileQuery, ISearchCompleteStats, IFileQuery, IRawTextQuery, IRawQuery, ITextQuery, IFolderQuery } from 'vs/workbench/services/search/common/search'; +import { URI, UriComponents } from 'vs/base/common/uri'; +import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager'; export interface IExtHostSearch extends ExtHostSearchShape { registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable; @@ -14,3 +21,111 @@ export interface IExtHostSearch extends ExtHostSearchShape { } export const IExtHostSearch = createDecorator('IExtHostSearch'); + +export class ExtHostSearch implements ExtHostSearchShape { + + protected readonly _proxy: MainThreadSearchShape = this.extHostRpc.getProxy(MainContext.MainThreadSearch); + protected _handlePool: number = 0; + + private readonly _textSearchProvider = new Map(); + private readonly _textSearchUsedSchemes = new Set(); + private readonly _fileSearchProvider = new Map(); + private readonly _fileSearchUsedSchemes = new Set(); + + private readonly _fileSearchManager = new FileSearchManager(); + + constructor( + @IExtHostRpcService private extHostRpc: IExtHostRpcService, + @IURITransformerService protected _uriTransformer: IURITransformerService, + @ILogService protected _logService: ILogService + ) { } + + protected _transformScheme(scheme: string): string { + return this._uriTransformer.transformOutgoingScheme(scheme); + } + + registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable { + if (this._textSearchUsedSchemes.has(scheme)) { + throw new Error(`a text search provider for the scheme '${scheme}' is already registered`); + } + + this._textSearchUsedSchemes.add(scheme); + const handle = this._handlePool++; + this._textSearchProvider.set(handle, provider); + this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme)); + return toDisposable(() => { + this._textSearchUsedSchemes.delete(scheme); + this._textSearchProvider.delete(handle); + this._proxy.$unregisterProvider(handle); + }); + } + + registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable { + if (this._fileSearchUsedSchemes.has(scheme)) { + throw new Error(`a file search provider for the scheme '${scheme}' is already registered`); + } + + this._fileSearchUsedSchemes.add(scheme); + const handle = this._handlePool++; + this._fileSearchProvider.set(handle, provider); + this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme)); + return toDisposable(() => { + this._fileSearchUsedSchemes.delete(scheme); + this._fileSearchProvider.delete(handle); + this._proxy.$unregisterProvider(handle); + }); + } + + $provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise { + const query = reviveQuery(rawQuery); + const provider = this._fileSearchProvider.get(handle); + if (provider) { + return this._fileSearchManager.fileSearch(query, provider, batch => { + this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); + }, token); + } else { + throw new Error('unknown provider: ' + handle); + } + } + + $clearCache(cacheKey: string): Promise { + this._fileSearchManager.clearCache(cacheKey); + + return Promise.resolve(undefined); + } + + $provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: vscode.CancellationToken): Promise { + const provider = this._textSearchProvider.get(handle); + if (!provider || !provider.provideTextSearchResults) { + throw new Error(`Unknown provider ${handle}`); + } + + const query = reviveQuery(rawQuery); + const engine = this.createTextSearchManager(query, provider); + return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token); + } + + protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager { + return new TextSearchManager(query, provider, { + readdir: resource => Promise.resolve([]), // TODO@rob implement + toCanonicalName: encoding => encoding + }); + } +} + +export function reviveQuery(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery { + return { + ...rawQuery, // TODO@rob ??? + ...{ + folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery), + extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components)) + } + }; +} + +function reviveFolderQuery(rawFolderQuery: IFolderQuery): IFolderQuery { + return { + ...rawFolderQuery, + folder: URI.revive(rawFolderQuery.folder) + }; +} diff --git a/src/vs/workbench/api/node/extHost.services.ts b/src/vs/workbench/api/node/extHost.services.ts index a227d8a67b3f..9ae085f53664 100644 --- a/src/vs/workbench/api/node/extHost.services.ts +++ b/src/vs/workbench/api/node/extHost.services.ts @@ -18,7 +18,7 @@ import { ExtHostTask } from 'vs/workbench/api/node/extHostTask'; import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; -import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; +import { NativeExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths'; import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; @@ -38,7 +38,7 @@ registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); registerSingleton(IExtHostTerminalService, ExtHostTerminalService); registerSingleton(IExtHostTask, ExtHostTask); registerSingleton(IExtHostDebugService, ExtHostDebugService); -registerSingleton(IExtHostSearch, ExtHostSearch); +registerSingleton(IExtHostSearch, NativeExtHostSearch); registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths); registerSingleton(IExtHostExtensionService, ExtHostExtensionService); registerSingleton(IExtHostStorage, ExtHostStorage); diff --git a/src/vs/workbench/api/node/extHostSearch.ts b/src/vs/workbench/api/node/extHostSearch.ts index a5af222b2e66..3082bb706255 100644 --- a/src/vs/workbench/api/node/extHostSearch.ts +++ b/src/vs/workbench/api/node/extHostSearch.ts @@ -3,47 +3,37 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { CancellationToken } from 'vs/base/common/cancellation'; import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { URI, UriComponents } from 'vs/base/common/uri'; +import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; import { ILogService } from 'vs/platform/log/common/log'; -import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery, isSerializedFileMatch, ISerializedSearchProgressItem } from 'vs/workbench/services/search/common/search'; -import { FileSearchManager } from 'vs/workbench/services/search/common/fileSearchManager'; +import { IFileQuery, IRawFileQuery, ISearchCompleteStats, isSerializedFileMatch, ISerializedSearchProgressItem, ITextQuery } from 'vs/workbench/services/search/common/search'; import { SearchService } from 'vs/workbench/services/search/node/rawSearchService'; import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrepSearchProvider'; import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils'; -import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; import * as vscode from 'vscode'; -import { ExtHostSearchShape, MainContext, MainThreadSearchShape } from '../common/extHost.protocol'; import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService'; import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { ExtHostSearch, reviveQuery } from 'vs/workbench/api/common/extHostSearch'; +import { Schemas } from 'vs/base/common/network'; +import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; +import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager'; -export class ExtHostSearch implements ExtHostSearchShape { +export class NativeExtHostSearch extends ExtHostSearch { - private readonly _proxy: MainThreadSearchShape; - private readonly _textSearchProvider = new Map(); - private readonly _textSearchUsedSchemes = new Set(); - private readonly _fileSearchProvider = new Map(); - private readonly _fileSearchUsedSchemes = new Set(); - private _handlePool: number = 0; + protected _pfs: typeof pfs = pfs; // allow extending for tests private _internalFileSearchHandle: number = -1; private _internalFileSearchProvider: SearchService | null = null; - private _fileSearchManager: FileSearchManager; - - protected _pfs: typeof pfs = pfs; // allow extending for tests - constructor( @IExtHostRpcService extHostRpc: IExtHostRpcService, @IExtHostInitDataService initData: IExtHostInitDataService, - @IURITransformerService private _uriTransformer: IURITransformerService, - @ILogService private _logService: ILogService, + @IURITransformerService _uriTransformer: IURITransformerService, + @ILogService _logService: ILogService, ) { - this._proxy = extHostRpc.getProxy(MainContext.MainThreadSearch); - this._fileSearchManager = new FileSearchManager(); + super(extHostRpc, _uriTransformer, _logService); if (initData.remote.isRemote && initData.remote.authority) { this._registerEHSearchProviders(); @@ -52,8 +42,8 @@ export class ExtHostSearch implements ExtHostSearchShape { private _registerEHSearchProviders(): void { const outputChannel = new OutputChannel(this._logService); - this.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel)); - this.registerInternalFileSearchProvider('file', new SearchService()); + this.registerTextSearchProvider(Schemas.file, new RipgrepSearchProvider(outputChannel)); + this.registerInternalFileSearchProvider(Schemas.file, new SearchService()); } private registerInternalFileSearchProvider(scheme: string, provider: SearchService): IDisposable { @@ -67,59 +57,16 @@ export class ExtHostSearch implements ExtHostSearchShape { }); } - private _transformScheme(scheme: string): string { - return this._uriTransformer.transformOutgoingScheme(scheme); - } - - registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable { - if (this._textSearchUsedSchemes.has(scheme)) { - throw new Error(`a text search provider for the scheme '${scheme}' is already registered`); - } - - this._textSearchUsedSchemes.add(scheme); - const handle = this._handlePool++; - this._textSearchProvider.set(handle, provider); - this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme)); - return toDisposable(() => { - this._textSearchUsedSchemes.delete(scheme); - this._textSearchProvider.delete(handle); - this._proxy.$unregisterProvider(handle); - }); - } - - registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable { - if (this._fileSearchUsedSchemes.has(scheme)) { - throw new Error(`a file search provider for the scheme '${scheme}' is already registered`); - } - - this._fileSearchUsedSchemes.add(scheme); - const handle = this._handlePool++; - this._fileSearchProvider.set(handle, provider); - this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme)); - return toDisposable(() => { - this._fileSearchUsedSchemes.delete(scheme); - this._fileSearchProvider.delete(handle); - this._proxy.$unregisterProvider(handle); - }); - } - - $provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: CancellationToken): Promise { + $provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise { const query = reviveQuery(rawQuery); if (handle === this._internalFileSearchHandle) { return this.doInternalFileSearch(handle, session, query, token); - } else { - const provider = this._fileSearchProvider.get(handle); - if (provider) { - return this._fileSearchManager.fileSearch(query, provider, batch => { - this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource)); - }, token); - } else { - throw new Error('unknown provider: ' + handle); - } } + + return super.$provideFileSearchResults(handle, session, rawQuery, token); } - private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: CancellationToken): Promise { + private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: vscode.CancellationToken): Promise { const onResult = (ev: ISerializedSearchProgressItem) => { if (isSerializedFileMatch(ev)) { ev = [ev]; @@ -147,37 +94,11 @@ export class ExtHostSearch implements ExtHostSearchShape { this._internalFileSearchProvider.clearCache(cacheKey); } - this._fileSearchManager.clearCache(cacheKey); - - return Promise.resolve(undefined); + return super.$clearCache(cacheKey); } - $provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: CancellationToken): Promise { - const provider = this._textSearchProvider.get(handle); - if (!provider || !provider.provideTextSearchResults) { - throw new Error(`Unknown provider ${handle}`); - } - - const query = reviveQuery(rawQuery); - const engine = new TextSearchManager(query, provider, this._pfs); - return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token); + protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager { + return new NativeTextSearchManager(query, provider); } } -function reviveQuery(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery { - return { - ...rawQuery, // TODO - ...{ - folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery), - extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components)) - } - }; -} - -function reviveFolderQuery(rawFolderQuery: IFolderQuery): IFolderQuery { - return { - ...rawFolderQuery, - folder: URI.revive(rawFolderQuery.folder) - }; -} - diff --git a/src/vs/workbench/services/extensions/worker/extHost.services.ts b/src/vs/workbench/services/extensions/worker/extHost.services.ts index 3bdfa1a79fa5..ed2e8767cf12 100644 --- a/src/vs/workbench/services/extensions/worker/extHost.services.ts +++ b/src/vs/workbench/services/extensions/worker/extHost.services.ts @@ -13,7 +13,7 @@ import { IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors } from 'vs/work import { IExtHostTerminalService, WorkerExtHostTerminalService } from 'vs/workbench/api/common/extHostTerminalService'; import { IExtHostTask, WorkerExtHostTask } from 'vs/workbench/api/common/extHostTask'; import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; -import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; +import { IExtHostSearch, ExtHostSearch } from 'vs/workbench/api/common/extHostSearch'; import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths'; import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService'; import { IExtHostStorage, ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; @@ -32,6 +32,7 @@ registerSingleton(IExtHostCommands, ExtHostCommands); registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors); registerSingleton(IExtHostStorage, ExtHostStorage); registerSingleton(IExtHostExtensionService, ExtHostExtensionService); +registerSingleton(IExtHostSearch, ExtHostSearch); // register services that only throw errors function NotImplementedProxy(name: ServiceIdentifier): { new(): T } { @@ -51,7 +52,6 @@ function NotImplementedProxy(name: ServiceIdentifier): { new(): T } { registerSingleton(IExtHostTerminalService, WorkerExtHostTerminalService); registerSingleton(IExtHostTask, WorkerExtHostTask); registerSingleton(IExtHostDebugService, class extends NotImplementedProxy(IExtHostDebugService) { }); -registerSingleton(IExtHostSearch, class extends NotImplementedProxy(IExtHostSearch) { }); registerSingleton(IExtensionStoragePaths, class extends NotImplementedProxy(IExtensionStoragePaths) { whenReady = Promise.resolve(); }); diff --git a/src/vs/workbench/services/search/common/textSearchManager.ts b/src/vs/workbench/services/search/common/textSearchManager.ts new file mode 100644 index 000000000000..223374a7bdd3 --- /dev/null +++ b/src/vs/workbench/services/search/common/textSearchManager.ts @@ -0,0 +1,355 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'vs/base/common/path'; +import { mapArrayOrNot } from 'vs/base/common/arrays'; +import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; +import { toErrorMessage } from 'vs/base/common/errorMessage'; +import * as resources from 'vs/base/common/resources'; +import * as glob from 'vs/base/common/glob'; +import { URI } from 'vs/base/common/uri'; +import { IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search'; +import { TextSearchProvider, TextSearchResult, TextSearchMatch, TextSearchComplete, Range, TextSearchOptions, TextSearchQuery } from 'vs/workbench/services/search/common/searchExtTypes'; +import { nextTick } from 'vs/base/common/process'; + +export interface IFileUtils { + readdir: (resource: URI) => Promise; + toCanonicalName: (encoding: string) => string; +} + +export class TextSearchManager { + + private collector: TextSearchResultsCollector | null = null; + + private isLimitHit = false; + private resultCount = 0; + + constructor(private query: ITextQuery, private provider: TextSearchProvider, private fileUtils: IFileUtils) { } + + search(onProgress: (matches: IFileMatch[]) => void, token: CancellationToken): Promise { + const folderQueries = this.query.folderQueries || []; + const tokenSource = new CancellationTokenSource(); + token.onCancellationRequested(() => tokenSource.cancel()); + + return new Promise((resolve, reject) => { + this.collector = new TextSearchResultsCollector(onProgress); + + let isCanceled = false; + const onResult = (result: TextSearchResult, folderIdx: number) => { + if (isCanceled) { + return; + } + + if (!this.isLimitHit) { + const resultSize = this.resultSize(result); + if (extensionResultIsMatch(result) && typeof this.query.maxResults === 'number' && this.resultCount + resultSize > this.query.maxResults) { + this.isLimitHit = true; + isCanceled = true; + tokenSource.cancel(); + + result = this.trimResultToSize(result, this.query.maxResults - this.resultCount); + } + + const newResultSize = this.resultSize(result); + this.resultCount += newResultSize; + if (newResultSize > 0) { + this.collector!.add(result, folderIdx); + } + } + }; + + // For each root folder + Promise.all(folderQueries.map((fq, i) => { + return this.searchInFolder(fq, r => onResult(r, i), tokenSource.token); + })).then(results => { + tokenSource.dispose(); + this.collector!.flush(); + + const someFolderHitLImit = results.some(result => !!result && !!result.limitHit); + resolve({ + limitHit: this.isLimitHit || someFolderHitLImit, + stats: { + type: 'textSearchProvider' + } + }); + }, (err: Error) => { + tokenSource.dispose(); + const errMsg = toErrorMessage(err); + reject(new Error(errMsg)); + }); + }); + } + + private resultSize(result: TextSearchResult): number { + const match = result; + return Array.isArray(match.ranges) ? + match.ranges.length : + 1; + } + + private trimResultToSize(result: TextSearchMatch, size: number): TextSearchMatch { + const rangesArr = Array.isArray(result.ranges) ? result.ranges : [result.ranges]; + const matchesArr = Array.isArray(result.preview.matches) ? result.preview.matches : [result.preview.matches]; + + return { + ranges: rangesArr.slice(0, size), + preview: { + matches: matchesArr.slice(0, size), + text: result.preview.text + }, + uri: result.uri + }; + } + + private searchInFolder(folderQuery: IFolderQuery, onResult: (result: TextSearchResult) => void, token: CancellationToken): Promise { + const queryTester = new QueryGlobTester(this.query, folderQuery); + const testingPs: Promise[] = []; + const progress = { + report: (result: TextSearchResult) => { + if (!this.validateProviderResult(result)) { + return; + } + + const hasSibling = folderQuery.folder.scheme === 'file' ? + glob.hasSiblingPromiseFn(() => { + return this.fileUtils.readdir(resources.dirname(result.uri)); + }) : + undefined; + + const relativePath = resources.relativePath(folderQuery.folder, result.uri); + if (relativePath) { + testingPs.push( + queryTester.includedInQuery(relativePath, path.basename(relativePath), hasSibling) + .then(included => { + if (included) { + onResult(result); + } + })); + } + } + }; + + const searchOptions = this.getSearchOptionsForFolder(folderQuery); + return new Promise(resolve => nextTick(resolve)) + .then(() => this.provider.provideTextSearchResults(patternInfoToQuery(this.query.contentPattern), searchOptions, progress, token)) + .then(result => { + return Promise.all(testingPs) + .then(() => result); + }); + } + + private validateProviderResult(result: TextSearchResult): boolean { + if (extensionResultIsMatch(result)) { + if (Array.isArray(result.ranges)) { + if (!Array.isArray(result.preview.matches)) { + console.warn('INVALID - A text search provider match\'s`ranges` and`matches` properties must have the same type.'); + return false; + } + + if ((result.preview.matches).length !== result.ranges.length) { + console.warn('INVALID - A text search provider match\'s`ranges` and`matches` properties must have the same length.'); + return false; + } + } else { + if (Array.isArray(result.preview.matches)) { + console.warn('INVALID - A text search provider match\'s`ranges` and`matches` properties must have the same length.'); + return false; + } + } + } + + return true; + } + + private getSearchOptionsForFolder(fq: IFolderQuery): TextSearchOptions { + const includes = resolvePatternsForProvider(this.query.includePattern, fq.includePattern); + const excludes = resolvePatternsForProvider(this.query.excludePattern, fq.excludePattern); + + const options = { + folder: URI.from(fq.folder), + excludes, + includes, + useIgnoreFiles: !fq.disregardIgnoreFiles, + useGlobalIgnoreFiles: !fq.disregardGlobalIgnoreFiles, + followSymlinks: !fq.ignoreSymlinks, + encoding: fq.fileEncoding && this.fileUtils.toCanonicalName(fq.fileEncoding), + maxFileSize: this.query.maxFileSize, + maxResults: this.query.maxResults, + previewOptions: this.query.previewOptions, + afterContext: this.query.afterContext, + beforeContext: this.query.beforeContext + }; + (options).usePCRE2 = this.query.usePCRE2; + return options; + } +} + +function patternInfoToQuery(patternInfo: IPatternInfo): TextSearchQuery { + return { + isCaseSensitive: patternInfo.isCaseSensitive || false, + isRegExp: patternInfo.isRegExp || false, + isWordMatch: patternInfo.isWordMatch || false, + isMultiline: patternInfo.isMultiline || false, + pattern: patternInfo.pattern + }; +} + +export class TextSearchResultsCollector { + private _batchedCollector: BatchedCollector; + + private _currentFolderIdx: number = -1; + private _currentUri: URI | undefined; + private _currentFileMatch: IFileMatch | null = null; + + constructor(private _onResult: (result: IFileMatch[]) => void) { + this._batchedCollector = new BatchedCollector(512, items => this.sendItems(items)); + } + + add(data: TextSearchResult, folderIdx: number): void { + // Collects TextSearchResults into IInternalFileMatches and collates using BatchedCollector. + // This is efficient for ripgrep which sends results back one file at a time. It wouldn't be efficient for other search + // providers that send results in random order. We could do this step afterwards instead. + if (this._currentFileMatch && (this._currentFolderIdx !== folderIdx || !resources.isEqual(this._currentUri, data.uri))) { + this.pushToCollector(); + this._currentFileMatch = null; + } + + if (!this._currentFileMatch) { + this._currentFolderIdx = folderIdx; + this._currentFileMatch = { + resource: data.uri, + results: [] + }; + } + + this._currentFileMatch.results!.push(extensionResultToFrontendResult(data)); + } + + private pushToCollector(): void { + const size = this._currentFileMatch && this._currentFileMatch.results ? + this._currentFileMatch.results.length : + 0; + this._batchedCollector.addItem(this._currentFileMatch!, size); + } + + flush(): void { + this.pushToCollector(); + this._batchedCollector.flush(); + } + + private sendItems(items: IFileMatch[]): void { + this._onResult(items); + } +} + +function extensionResultToFrontendResult(data: TextSearchResult): ITextSearchResult { + // Warning: result from RipgrepTextSearchEH has fake Range. Don't depend on any other props beyond these... + if (extensionResultIsMatch(data)) { + return { + preview: { + matches: mapArrayOrNot(data.preview.matches, m => ({ + startLineNumber: m.start.line, + startColumn: m.start.character, + endLineNumber: m.end.line, + endColumn: m.end.character + })), + text: data.preview.text + }, + ranges: mapArrayOrNot(data.ranges, r => ({ + startLineNumber: r.start.line, + startColumn: r.start.character, + endLineNumber: r.end.line, + endColumn: r.end.character + })) + }; + } else { + return { + text: data.text, + lineNumber: data.lineNumber + }; + } +} + +export function extensionResultIsMatch(data: TextSearchResult): data is TextSearchMatch { + return !!(data).preview; +} + +/** + * Collects items that have a size - before the cumulative size of collected items reaches START_BATCH_AFTER_COUNT, the callback is called for every + * set of items collected. + * But after that point, the callback is called with batches of maxBatchSize. + * If the batch isn't filled within some time, the callback is also called. + */ +export class BatchedCollector { + private static readonly TIMEOUT = 4000; + + // After START_BATCH_AFTER_COUNT items have been collected, stop flushing on timeout + private static readonly START_BATCH_AFTER_COUNT = 50; + + private totalNumberCompleted = 0; + private batch: T[] = []; + private batchSize = 0; + private timeoutHandle: any; + + constructor(private maxBatchSize: number, private cb: (items: T[]) => void) { + } + + addItem(item: T, size: number): void { + if (!item) { + return; + } + + this.addItemToBatch(item, size); + } + + addItems(items: T[], size: number): void { + if (!items) { + return; + } + + this.addItemsToBatch(items, size); + } + + private addItemToBatch(item: T, size: number): void { + this.batch.push(item); + this.batchSize += size; + this.onUpdate(); + } + + private addItemsToBatch(item: T[], size: number): void { + this.batch = this.batch.concat(item); + this.batchSize += size; + this.onUpdate(); + } + + private onUpdate(): void { + if (this.totalNumberCompleted < BatchedCollector.START_BATCH_AFTER_COUNT) { + // Flush because we aren't batching yet + this.flush(); + } else if (this.batchSize >= this.maxBatchSize) { + // Flush because the batch is full + this.flush(); + } else if (!this.timeoutHandle) { + // No timeout running, start a timeout to flush + this.timeoutHandle = setTimeout(() => { + this.flush(); + }, BatchedCollector.TIMEOUT); + } + } + + flush(): void { + if (this.batchSize) { + this.totalNumberCompleted += this.batchSize; + this.cb(this.batch); + this.batch = []; + this.batchSize = 0; + + if (this.timeoutHandle) { + clearTimeout(this.timeoutHandle); + this.timeoutHandle = 0; + } + } + } +} diff --git a/src/vs/workbench/services/search/node/textSearchAdapter.ts b/src/vs/workbench/services/search/node/textSearchAdapter.ts index 37bca799785e..5d7c484e3ca5 100644 --- a/src/vs/workbench/services/search/node/textSearchAdapter.ts +++ b/src/vs/workbench/services/search/node/textSearchAdapter.ts @@ -7,12 +7,11 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import * as pfs from 'vs/base/node/pfs'; import { IFileMatch, IProgressMessage, ITextQuery, ITextSearchStats, ITextSearchMatch, ISerializedFileMatch, ISerializedSearchSuccess } from 'vs/workbench/services/search/common/search'; import { RipgrepTextSearchEngine } from 'vs/workbench/services/search/node/ripgrepTextSearchEngine'; -import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; +import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; export class TextSearchEngineAdapter { - constructor(private query: ITextQuery) { - } + constructor(private query: ITextQuery) { } search(token: CancellationToken, onResult: (matches: ISerializedFileMatch[]) => void, onMessage: (message: IProgressMessage) => void): Promise { if ((!this.query.folderQueries || !this.query.folderQueries.length) && (!this.query.extraFileResources || !this.query.extraFileResources.length)) { @@ -30,7 +29,7 @@ export class TextSearchEngineAdapter { onMessage({ message: msg }); } }; - const textSearchManager = new TextSearchManager(this.query, new RipgrepTextSearchEngine(pretendOutputChannel), pfs); + const textSearchManager = new NativeTextSearchManager(this.query, new RipgrepTextSearchEngine(pretendOutputChannel), pfs); return new Promise((resolve, reject) => { return textSearchManager .search( diff --git a/src/vs/workbench/services/search/node/textSearchManager.ts b/src/vs/workbench/services/search/node/textSearchManager.ts index e7586a912cdf..3433ce355376 100644 --- a/src/vs/workbench/services/search/node/textSearchManager.ts +++ b/src/vs/workbench/services/search/node/textSearchManager.ts @@ -3,352 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as path from 'vs/base/common/path'; -import { mapArrayOrNot } from 'vs/base/common/arrays'; -import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; -import { toErrorMessage } from 'vs/base/common/errorMessage'; -import * as resources from 'vs/base/common/resources'; -import * as glob from 'vs/base/common/glob'; -import { URI } from 'vs/base/common/uri'; import { toCanonicalName } from 'vs/base/node/encoding'; import * as pfs from 'vs/base/node/pfs'; -import { IExtendedExtensionSearchOptions, IFileMatch, IFolderQuery, IPatternInfo, ISearchCompleteStats, ITextQuery, ITextSearchContext, ITextSearchMatch, ITextSearchResult, QueryGlobTester, resolvePatternsForProvider } from 'vs/workbench/services/search/common/search'; -import { TextSearchProvider, TextSearchResult, TextSearchMatch, TextSearchComplete, Range, TextSearchOptions, TextSearchQuery } from 'vs/workbench/services/search/common/searchExtTypes'; +import { ITextQuery } from 'vs/workbench/services/search/common/search'; +import { TextSearchProvider } from 'vs/workbench/services/search/common/searchExtTypes'; +import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager'; -export class TextSearchManager { +export class NativeTextSearchManager extends TextSearchManager { - private collector: TextSearchResultsCollector | null = null; - - private isLimitHit = false; - private resultCount = 0; - - constructor(private query: ITextQuery, private provider: TextSearchProvider, private _pfs: typeof pfs = pfs) { - } - - search(onProgress: (matches: IFileMatch[]) => void, token: CancellationToken): Promise { - const folderQueries = this.query.folderQueries || []; - const tokenSource = new CancellationTokenSource(); - token.onCancellationRequested(() => tokenSource.cancel()); - - return new Promise((resolve, reject) => { - this.collector = new TextSearchResultsCollector(onProgress); - - let isCanceled = false; - const onResult = (result: TextSearchResult, folderIdx: number) => { - if (isCanceled) { - return; - } - - if (!this.isLimitHit) { - const resultSize = this.resultSize(result); - if (extensionResultIsMatch(result) && typeof this.query.maxResults === 'number' && this.resultCount + resultSize > this.query.maxResults) { - this.isLimitHit = true; - isCanceled = true; - tokenSource.cancel(); - - result = this.trimResultToSize(result, this.query.maxResults - this.resultCount); - } - - const newResultSize = this.resultSize(result); - this.resultCount += newResultSize; - if (newResultSize > 0) { - this.collector!.add(result, folderIdx); - } - } - }; - - // For each root folder - Promise.all(folderQueries.map((fq, i) => { - return this.searchInFolder(fq, r => onResult(r, i), tokenSource.token); - })).then(results => { - tokenSource.dispose(); - this.collector!.flush(); - - const someFolderHitLImit = results.some(result => !!result && !!result.limitHit); - resolve({ - limitHit: this.isLimitHit || someFolderHitLImit, - stats: { - type: 'textSearchProvider' - } - }); - }, (err: Error) => { - tokenSource.dispose(); - const errMsg = toErrorMessage(err); - reject(new Error(errMsg)); - }); + constructor(query: ITextQuery, provider: TextSearchProvider, _pfs: typeof pfs = pfs) { + super(query, provider, { + readdir: resource => _pfs.readdir(resource.fsPath), + toCanonicalName: name => toCanonicalName(name) }); } - - private resultSize(result: TextSearchResult): number { - const match = result; - return Array.isArray(match.ranges) ? - match.ranges.length : - 1; - } - - private trimResultToSize(result: TextSearchMatch, size: number): TextSearchMatch { - const rangesArr = Array.isArray(result.ranges) ? result.ranges : [result.ranges]; - const matchesArr = Array.isArray(result.preview.matches) ? result.preview.matches : [result.preview.matches]; - - return { - ranges: rangesArr.slice(0, size), - preview: { - matches: matchesArr.slice(0, size), - text: result.preview.text - }, - uri: result.uri - }; - } - - private searchInFolder(folderQuery: IFolderQuery, onResult: (result: TextSearchResult) => void, token: CancellationToken): Promise { - const queryTester = new QueryGlobTester(this.query, folderQuery); - const testingPs: Promise[] = []; - const progress = { - report: (result: TextSearchResult) => { - if (!this.validateProviderResult(result)) { - return; - } - - const hasSibling = folderQuery.folder.scheme === 'file' ? - glob.hasSiblingPromiseFn(() => { - return this.readdir(path.dirname(result.uri.fsPath)); - }) : - undefined; - - const relativePath = path.relative(folderQuery.folder.fsPath, result.uri.fsPath); - testingPs.push( - queryTester.includedInQuery(relativePath, path.basename(relativePath), hasSibling) - .then(included => { - if (included) { - onResult(result); - } - })); - } - }; - - const searchOptions = this.getSearchOptionsForFolder(folderQuery); - return new Promise(resolve => process.nextTick(resolve)) - .then(() => this.provider.provideTextSearchResults(patternInfoToQuery(this.query.contentPattern), searchOptions, progress, token)) - .then(result => { - return Promise.all(testingPs) - .then(() => result); - }); - } - - private validateProviderResult(result: TextSearchResult): boolean { - if (extensionResultIsMatch(result)) { - if (Array.isArray(result.ranges)) { - if (!Array.isArray(result.preview.matches)) { - console.warn('INVALID - A text search provider match\'s`ranges` and`matches` properties must have the same type.'); - return false; - } - - if ((result.preview.matches).length !== result.ranges.length) { - console.warn('INVALID - A text search provider match\'s`ranges` and`matches` properties must have the same length.'); - return false; - } - } else { - if (Array.isArray(result.preview.matches)) { - console.warn('INVALID - A text search provider match\'s`ranges` and`matches` properties must have the same length.'); - return false; - } - } - } - - return true; - } - - private readdir(dirname: string): Promise { - return this._pfs.readdir(dirname); - } - - private getSearchOptionsForFolder(fq: IFolderQuery): TextSearchOptions { - const includes = resolvePatternsForProvider(this.query.includePattern, fq.includePattern); - const excludes = resolvePatternsForProvider(this.query.excludePattern, fq.excludePattern); - - const options = { - folder: URI.from(fq.folder), - excludes, - includes, - useIgnoreFiles: !fq.disregardIgnoreFiles, - useGlobalIgnoreFiles: !fq.disregardGlobalIgnoreFiles, - followSymlinks: !fq.ignoreSymlinks, - encoding: fq.fileEncoding && toCanonicalName(fq.fileEncoding), - maxFileSize: this.query.maxFileSize, - maxResults: this.query.maxResults, - previewOptions: this.query.previewOptions, - afterContext: this.query.afterContext, - beforeContext: this.query.beforeContext - }; - (options).usePCRE2 = this.query.usePCRE2; - return options; - } -} - -function patternInfoToQuery(patternInfo: IPatternInfo): TextSearchQuery { - return { - isCaseSensitive: patternInfo.isCaseSensitive || false, - isRegExp: patternInfo.isRegExp || false, - isWordMatch: patternInfo.isWordMatch || false, - isMultiline: patternInfo.isMultiline || false, - pattern: patternInfo.pattern - }; -} - -export class TextSearchResultsCollector { - private _batchedCollector: BatchedCollector; - - private _currentFolderIdx: number = -1; - private _currentUri: URI | undefined; - private _currentFileMatch: IFileMatch | null = null; - - constructor(private _onResult: (result: IFileMatch[]) => void) { - this._batchedCollector = new BatchedCollector(512, items => this.sendItems(items)); - } - - add(data: TextSearchResult, folderIdx: number): void { - // Collects TextSearchResults into IInternalFileMatches and collates using BatchedCollector. - // This is efficient for ripgrep which sends results back one file at a time. It wouldn't be efficient for other search - // providers that send results in random order. We could do this step afterwards instead. - if (this._currentFileMatch && (this._currentFolderIdx !== folderIdx || !resources.isEqual(this._currentUri, data.uri))) { - this.pushToCollector(); - this._currentFileMatch = null; - } - - if (!this._currentFileMatch) { - this._currentFolderIdx = folderIdx; - this._currentFileMatch = { - resource: data.uri, - results: [] - }; - } - - this._currentFileMatch.results!.push(extensionResultToFrontendResult(data)); - } - - private pushToCollector(): void { - const size = this._currentFileMatch && this._currentFileMatch.results ? - this._currentFileMatch.results.length : - 0; - this._batchedCollector.addItem(this._currentFileMatch!, size); - } - - flush(): void { - this.pushToCollector(); - this._batchedCollector.flush(); - } - - private sendItems(items: IFileMatch[]): void { - this._onResult(items); - } -} - -function extensionResultToFrontendResult(data: TextSearchResult): ITextSearchResult { - // Warning: result from RipgrepTextSearchEH has fake Range. Don't depend on any other props beyond these... - if (extensionResultIsMatch(data)) { - return { - preview: { - matches: mapArrayOrNot(data.preview.matches, m => ({ - startLineNumber: m.start.line, - startColumn: m.start.character, - endLineNumber: m.end.line, - endColumn: m.end.character - })), - text: data.preview.text - }, - ranges: mapArrayOrNot(data.ranges, r => ({ - startLineNumber: r.start.line, - startColumn: r.start.character, - endLineNumber: r.end.line, - endColumn: r.end.character - })) - }; - } else { - return { - text: data.text, - lineNumber: data.lineNumber - }; - } -} - -export function extensionResultIsMatch(data: TextSearchResult): data is TextSearchMatch { - return !!(data).preview; -} - -/** - * Collects items that have a size - before the cumulative size of collected items reaches START_BATCH_AFTER_COUNT, the callback is called for every - * set of items collected. - * But after that point, the callback is called with batches of maxBatchSize. - * If the batch isn't filled within some time, the callback is also called. - */ -export class BatchedCollector { - private static readonly TIMEOUT = 4000; - - // After START_BATCH_AFTER_COUNT items have been collected, stop flushing on timeout - private static readonly START_BATCH_AFTER_COUNT = 50; - - private totalNumberCompleted = 0; - private batch: T[] = []; - private batchSize = 0; - private timeoutHandle: any; - - constructor(private maxBatchSize: number, private cb: (items: T[]) => void) { - } - - addItem(item: T, size: number): void { - if (!item) { - return; - } - - this.addItemToBatch(item, size); - } - - addItems(items: T[], size: number): void { - if (!items) { - return; - } - - this.addItemsToBatch(items, size); - } - - private addItemToBatch(item: T, size: number): void { - this.batch.push(item); - this.batchSize += size; - this.onUpdate(); - } - - private addItemsToBatch(item: T[], size: number): void { - this.batch = this.batch.concat(item); - this.batchSize += size; - this.onUpdate(); - } - - private onUpdate(): void { - if (this.totalNumberCompleted < BatchedCollector.START_BATCH_AFTER_COUNT) { - // Flush because we aren't batching yet - this.flush(); - } else if (this.batchSize >= this.maxBatchSize) { - // Flush because the batch is full - this.flush(); - } else if (!this.timeoutHandle) { - // No timeout running, start a timeout to flush - this.timeoutHandle = setTimeout(() => { - this.flush(); - }, BatchedCollector.TIMEOUT); - } - } - - flush(): void { - if (this.batchSize) { - this.totalNumberCompleted += this.batchSize; - this.cb(this.batch); - this.batch = []; - this.batchSize = 0; - - if (this.timeoutHandle) { - clearTimeout(this.timeoutHandle); - this.timeoutHandle = 0; - } - } - } } diff --git a/src/vs/workbench/services/search/test/node/textSearchManager.test.ts b/src/vs/workbench/services/search/test/node/textSearchManager.test.ts index 1efabf6224d8..fec67730fa07 100644 --- a/src/vs/workbench/services/search/test/node/textSearchManager.test.ts +++ b/src/vs/workbench/services/search/test/node/textSearchManager.test.ts @@ -9,9 +9,9 @@ import { URI } from 'vs/base/common/uri'; import { Progress } from 'vs/platform/progress/common/progress'; import { ITextQuery, QueryType } from 'vs/workbench/services/search/common/search'; import { ProviderResult, TextSearchComplete, TextSearchOptions, TextSearchProvider, TextSearchQuery, TextSearchResult } from 'vs/workbench/services/search/common/searchExtTypes'; -import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; +import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; -suite('TextSearchManager', () => { +suite('NativeTextSearchManager', () => { test('fixes encoding', async () => { let correctEncoding = false; const provider: TextSearchProvider = { @@ -33,7 +33,7 @@ suite('TextSearchManager', () => { }] }; - const m = new TextSearchManager(query, provider); + const m = new NativeTextSearchManager(query, provider); await m.search(() => { }, new CancellationTokenSource().token); assert.ok(correctEncoding); diff --git a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts index bf71ebfaf5c2..d90cbe042567 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostSearch.test.ts @@ -12,7 +12,7 @@ import { joinPath } from 'vs/base/common/resources'; import { URI, UriComponents } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; import { MainContext, MainThreadSearchShape } from 'vs/workbench/api/common/extHost.protocol'; -import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; +import { NativeExtHostSearch } from 'vs/workbench/api/node/extHostSearch'; import { Range } from 'vs/workbench/api/common/extHostTypes'; import { IFileMatch, IFileQuery, IPatternInfo, IRawFileMatch2, ISearchCompleteStats, ISearchQuery, ITextQuery, QueryType, resultIsMatch } from 'vs/workbench/services/search/common/search'; import { TestRPCProtocol } from 'vs/workbench/test/electron-browser/api/testRPCProtocol'; @@ -21,9 +21,11 @@ import { NullLogService } from 'vs/platform/log/common/log'; import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; import { mock } from 'vs/workbench/test/electron-browser/api/mock'; import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService'; +import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager'; +import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager'; let rpcProtocol: TestRPCProtocol; -let extHostSearch: ExtHostSearch; +let extHostSearch: NativeExtHostSearch; const disposables = new DisposableStore(); let mockMainThreadSearch: MockMainThreadSearch; @@ -138,7 +140,7 @@ suite('ExtHostSearch', () => { rpcProtocol.set(MainContext.MainThreadSearch, mockMainThreadSearch); mockPFS = {}; - extHostSearch = new class extends ExtHostSearch { + extHostSearch = new class extends NativeExtHostSearch { constructor() { super( rpcProtocol, @@ -148,6 +150,10 @@ suite('ExtHostSearch', () => { ); this._pfs = mockPFS as any; } + + protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager { + return new NativeTextSearchManager(query, provider, this._pfs); + } }; }); From 6d1ddf073053ec4f63de39f07b57b4f619c0cb4c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 19:06:48 +0100 Subject: [PATCH 54/60] web - fix problems to show up from yarn web --- extensions/vscode-api-tests/src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/vscode-api-tests/src/extension.ts b/extensions/vscode-api-tests/src/extension.ts index 05646e66dc3a..7d345d9ae955 100644 --- a/extensions/vscode-api-tests/src/extension.ts +++ b/extensions/vscode-api-tests/src/extension.ts @@ -344,7 +344,7 @@ function enableProblems(context: vscode.ExtensionContext): void { } function updateDiagnostics(document: vscode.TextDocument, collection: vscode.DiagnosticCollection): void { - if (document && document.fileName === '/large.ts') { + if (document && document.fileName === '/sample-folder/large.ts') { collection.set(document.uri, [{ code: '', message: 'cannot assign twice to immutable variable `storeHouses`', From 54a6229d6855fbd5b861276a3ff6eccd6b3f1cc7 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Nov 2019 19:19:35 +0100 Subject: [PATCH 55/60] web - workaround new window issue with pwa --- src/vs/code/browser/workbench/workbench.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index a599f5a7ebf0..28b0e9a3b156 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -11,7 +11,6 @@ import { Disposable } from 'vs/base/common/lifecycle'; import { request } from 'vs/base/parts/request/browser/request'; import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/windows'; import { isEqual } from 'vs/base/common/resources'; -import { isStandalone } from 'vs/base/browser/browser'; interface ICredential { service: string; @@ -223,7 +222,7 @@ class WorkspaceProvider implements IWorkspaceProvider { if (options?.reuse) { window.location.href = targetHref; } else { - if (isStandalone) { + if (this.isRunningInPWA()) { // TODO@ben figure out why browser.isStandalone would not work? window.open(targetHref, '_blank', 'toolbar=no'); // ensures to open another 'standalone' window! } else { window.open(targetHref); @@ -232,6 +231,10 @@ class WorkspaceProvider implements IWorkspaceProvider { } } + private isRunningInPWA(): boolean { + return (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches); + } + private createTargetUrl(workspace: IWorkspace, options?: { reuse?: boolean, payload?: object }): string | undefined { // Empty From fdd406ef822101f5d133bdaaf818af48edecde20 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 12 Nov 2019 10:13:38 -0800 Subject: [PATCH 56/60] Fix #83850 Intercept ctrl+A on the settings page so it won't select the full page text --- .../preferences/browser/settingsEditor2.ts | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 36c63be5ea99..b05433b5f86b 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -4,13 +4,18 @@ *--------------------------------------------------------------------------------------------*/ import * as DOM from 'vs/base/browser/dom'; +import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; +import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { ITreeElement } from 'vs/base/browser/ui/tree/tree'; +import { Action } from 'vs/base/common/actions'; import * as arrays from 'vs/base/common/arrays'; import { Delayer, ThrottledDelayer, timeout } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import * as collections from 'vs/base/common/collections'; import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors'; import { Iterator } from 'vs/base/common/iterator'; +import { KeyCode } from 'vs/base/common/keyCodes'; +import * as platform from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; import { isArray, withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; @@ -36,13 +41,11 @@ import { AbstractSettingRenderer, ISettingLinkClickEvent, ISettingOverrideClickE import { ISettingsEditorViewState, parseQuery, SearchResultIdx, SearchResultModel, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels'; import { settingsTextInputBorder } from 'vs/workbench/contrib/preferences/browser/settingsWidgets'; import { createTOCIterator, TOCTree, TOCTreeModel } from 'vs/workbench/contrib/preferences/browser/tocTree'; -import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, EXTENSION_SETTING_TAG, IPreferencesSearchService, ISearchProvider, MODIFIED_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS } from 'vs/workbench/contrib/preferences/common/preferences'; +import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, EXTENSION_SETTING_TAG, IPreferencesSearchService, ISearchProvider, MODIFIED_SETTING_TAG, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IPreferencesService, ISearchResult, ISettingsEditorModel, ISettingsEditorOptions, SettingsEditorOptions, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { Settings2EditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; -import { Action } from 'vs/base/common/actions'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; function createGroupIterator(group: SettingsTreeGroupElement): Iterator> { const groupsIt = Iterator.fromArray(group.children); @@ -212,6 +215,7 @@ export class SettingsEditor2 extends BaseEditor { this.createHeader(this.rootElement); this.createBody(this.rootElement); + this.addCtrlAInterceptor(this.rootElement); this.updateStyles(); } @@ -587,6 +591,21 @@ export class SettingsEditor2 extends BaseEditor { ); } + private addCtrlAInterceptor(container: HTMLElement): void { + this._register(DOM.addStandardDisposableListener(container, DOM.EventType.KEY_DOWN, (e: StandardKeyboardEvent) => { + if ( + e.keyCode === KeyCode.KEY_A && + (platform.isMacintosh ? e.metaKey : e.ctrlKey) && + e.target.tagName !== 'TEXTAREA' && + e.target.tagName !== 'INPUT' + ) { + // Avoid browser ctrl+a + e.browserEvent.stopPropagation(); + e.browserEvent.preventDefault(); + } + })); + } + private createFocusSink(container: HTMLElement, callback: (e: any) => boolean, label: string): HTMLElement { const listFocusSink = DOM.append(container, $('.settings-tree-focus-sink')); listFocusSink.setAttribute('aria-label', label); From 40677e0787f109d642bc114e3f69bff2f835e21d Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 12 Nov 2019 10:28:08 -0800 Subject: [PATCH 57/60] Fix #84496 Handle getting non-JSON response from the experiment service endpoint --- .../experiments/common/experimentService.ts | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/experiments/common/experimentService.ts b/src/vs/workbench/contrib/experiments/common/experimentService.ts index 188efd95a27f..11b6c10aa511 100644 --- a/src/vs/workbench/contrib/experiments/common/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/common/experimentService.ts @@ -167,18 +167,22 @@ export class ExperimentService extends Disposable implements IExperimentService this.storageService.store(storageKey, JSON.stringify(experimentState), StorageScope.GLOBAL); } - protected getExperiments(): Promise { + protected async getExperiments(): Promise { if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { - return Promise.resolve([]); + return []; } - return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => { + + try { + const context = await this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None); if (context.res.statusCode !== 200) { - return Promise.resolve(null); + return null; } - return asJson(context).then((result: any) => { - return result && Array.isArray(result['experiments']) ? result['experiments'] : []; - }); - }, () => Promise.resolve(null)); + const result: any = await asJson(context); + return result && Array.isArray(result['experiments']) ? result['experiments'] : []; + } catch (_e) { + // Bad request or invalid JSON + return null; + } } private loadExperiments(): Promise { From 8ae2921645a9f06686e66580b59a24cce63733b7 Mon Sep 17 00:00:00 2001 From: Greg Van Liew Date: Tue, 12 Nov 2019 10:55:04 -0800 Subject: [PATCH 58/60] Nits in settings comments --- extensions/typescript-language-features/package.nls.json | 6 +++--- src/vs/editor/common/config/editorOptions.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index c9ea95731934..bb4187716ba0 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -30,7 +30,7 @@ "format.placeOpenBraceOnNewLineForFunctions": "Defines whether an open brace is put onto a new line for functions or not.", "format.placeOpenBraceOnNewLineForControlBlocks": "Defines whether an open brace is put onto a new line for control blocks or not.", "format.semicolons": "Defines handling of optional semicolons. Requires using TypeScript 3.7 or newer in the workspace.", - "format.semicolons.ignore": "Don’t insert or remove any semicolons.", + "format.semicolons.ignore": "Don't insert or remove any semicolons.", "format.semicolons.insert": "Insert semicolons at statement ends.", "format.semicolons.remove": "Remove unnecessary semicolons.", "javascript.validate.enable": "Enable/disable JavaScript validation.", @@ -43,8 +43,8 @@ "typescript.selectTypeScriptVersion.title": "Select TypeScript Version...", "typescript.reportStyleChecksAsWarnings": "Report style checks as warnings.", "javascript.implicitProjectConfig.checkJs": "Enable/disable semantic checking of JavaScript files. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.", - "typescript.npm": "Specifies the path to the NPM executable used for Automatic Type Acquisition. Requires using TypeScript 2.3.4 or newer in the workspace.", - "typescript.check.npmIsInstalled": "Check if NPM is installed for Automatic Type Acquisition.", + "typescript.npm": "Specifies the path to the npm executable used for Automatic Type Acquisition. Requires using TypeScript 2.3.4 or newer in the workspace.", + "typescript.check.npmIsInstalled": "Check if npm is installed for Automatic Type Acquisition.", "configuration.suggest.names": "Enable/disable including unique names from the file in JavaScript suggestions. Note that name suggestions are always disabled in JavaScript code that is semantically checked using `@ts-check` or `checkJs`.", "typescript.tsc.autoDetect": "Controls auto detection of tsc tasks.", "typescript.tsc.autoDetect.off": "Disable this feature.", diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index b20246a3734a..de2c41dddd37 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -3155,10 +3155,10 @@ export const EditorOptions = { ['default', 'all'] as const, { enumDescriptions: [ - nls.localize('cursorSurroundingLinesStyle.default', "`cursorSurroundingLines` is enforced only when triggered from keyboard and api"), + nls.localize('cursorSurroundingLinesStyle.default', "`cursorSurroundingLines` is enforced only when triggered via the keyboard or API."), nls.localize('cursorSurroundingLinesStyle.all', "`cursorSurroundingLines` is enforced always.") ], - description: nls.localize('cursorSurroundingLinesStyle', "Controls when `cursorSurroundingLines` should be enforced") + description: nls.localize('cursorSurroundingLinesStyle', "Controls when `cursorSurroundingLines` should be enforced.") } )), cursorWidth: register(new EditorIntOption( From b33979cbe433b8ea25e35a07f7bb16d30508d7b3 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 12 Nov 2019 17:39:41 +0100 Subject: [PATCH 59/60] Use active foreground when inactive (fixes #72952) --- .../workbench/browser/parts/quickinput/quickInputList.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts index cb9791317b06..1e62ba48a8aa 100644 --- a/src/vs/workbench/browser/parts/quickinput/quickInputList.ts +++ b/src/vs/workbench/browser/parts/quickinput/quickInputList.ts @@ -22,7 +22,7 @@ import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlighte import { memoize } from 'vs/base/common/decorators'; import { range } from 'vs/base/common/arrays'; import * as platform from 'vs/base/common/platform'; -import { listFocusBackground, pickerGroupBorder, pickerGroupForeground, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry'; +import { listFocusBackground, pickerGroupBorder, pickerGroupForeground, activeContrastBorder, listFocusForeground } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Action } from 'vs/base/common/actions'; @@ -590,12 +590,18 @@ function compareEntries(elementA: ListElement, elementB: ListElement, lookFor: s } registerThemingParticipant((theme, collector) => { + // Override inactive focus foreground with active focus foreground for single-pick case. + const listInactiveFocusForeground = theme.getColor(listFocusForeground); + if (listInactiveFocusForeground) { + collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { color: ${listInactiveFocusForeground}; }`); + } // Override inactive focus background with active focus background for single-pick case. const listInactiveFocusBackground = theme.getColor(listFocusBackground); if (listInactiveFocusBackground) { collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { background-color: ${listInactiveFocusBackground}; }`); collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused:hover { background-color: ${listInactiveFocusBackground}; }`); } + // dotted instead of solid (as in listWidget.ts) to match QuickOpen const activeContrast = theme.getColor(activeContrastBorder); if (activeContrast) { collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { outline: 1px dotted ${activeContrast}; outline-offset: -1px; }`); From 3948b798b62ded00076422f30064ccf7214848f8 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 12 Nov 2019 13:56:51 -0600 Subject: [PATCH 60/60] Fix #84355 Always open settings GUI when command is invoked with a query --- .../contrib/preferences/browser/preferences.contribution.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts index 5e544b6a1c50..36d2c63d1b0a 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferences.contribution.ts @@ -215,7 +215,8 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ when: null, primary: KeyMod.CtrlCmd | KeyCode.US_COMMA, handler: (accessor, args: string | undefined) => { - accessor.get(IPreferencesService).openSettings(undefined, typeof args === 'string' ? args : undefined); + const query = typeof args === 'string' ? args : undefined; + accessor.get(IPreferencesService).openSettings(query ? false : undefined, query); } });