From 411f7ec701096ba3d206dcd3dc429f8ba4464b42 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 5 Dec 2023 14:57:21 +0100 Subject: [PATCH 01/37] keep hover open when the alt key is pressed --- src/vs/editor/contrib/hover/browser/hover.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index fe17f36c2c0..ea0d9fb412d 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -217,6 +217,10 @@ export class ModesHoverController extends Disposable implements IEditorContribut // so moving the mouse has no effect return; } + if (mouseEvent.event.altKey) { + // When the alt key is pressed, hover remains open + return; + } const mouseIsOverWidget = this._isMouseOverWidget(mouseEvent); // If the mouse is over the widget and the hiding timeout is defined, then cancel it From 5202e7bd7ba2c7c294dd54f0e525f413de8c8cbd Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 5 Dec 2023 07:14:01 -0800 Subject: [PATCH 02/37] Warn on opaque needsTransparency colors, expose to workbench fixes #200050 --- src/vs/platform/theme/common/colorRegistry.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index c7ecd0485b4..2eab35be3ad 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -88,9 +88,10 @@ export interface IColorRegistry { * Register a color to the registry. * @param id The color id as used in theme description files * @param defaults The default values + * @param needsTransparency Whether the color requires transparency * @description the description */ - registerColor(id: string, defaults: ColorDefaults, description: string): ColorIdentifier; + registerColor(id: string, defaults: ColorDefaults, description: string, needsTransparency?: boolean): ColorIdentifier; /** * Register a color to the registry. @@ -139,6 +140,10 @@ class ColorRegistry implements IColorRegistry { if (deprecationMessage) { propertySchema.deprecationMessage = deprecationMessage; } + if (needsTransparency) { + propertySchema.pattern = '^#(?:(?[0-9a-fA-f]{3}[0-9a-eA-E])|(?:[0-9a-fA-F]{6}(?:(?![fF]{2})(?:[0-9a-fA-F]{2}))))?$'; + propertySchema.patternErrorMessage = 'This color must be transparent or it will obscure the selection'; + } this.colorSchema.properties[id] = propertySchema; this.colorReferenceSchema.enum.push(id); this.colorReferenceSchema.enumDescriptions.push(description); From 93c589cfc6aab0f9bca1e49cc22cf2c7cbc424c1 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 5 Dec 2023 07:17:25 -0800 Subject: [PATCH 03/37] Use a generic error message --- src/vs/platform/theme/common/colorRegistry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/theme/common/colorRegistry.ts b/src/vs/platform/theme/common/colorRegistry.ts index 2eab35be3ad..303c4577fa6 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -142,7 +142,7 @@ class ColorRegistry implements IColorRegistry { } if (needsTransparency) { propertySchema.pattern = '^#(?:(?[0-9a-fA-f]{3}[0-9a-eA-E])|(?:[0-9a-fA-F]{6}(?:(?![fF]{2})(?:[0-9a-fA-F]{2}))))?$'; - propertySchema.patternErrorMessage = 'This color must be transparent or it will obscure the selection'; + propertySchema.patternErrorMessage = 'This color must be transparent or it will obscure content'; } this.colorSchema.properties[id] = propertySchema; this.colorReferenceSchema.enum.push(id); From c733e05d942a2ed212167e184fc2c293618b0688 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 5 Dec 2023 07:20:39 -0800 Subject: [PATCH 04/37] Adopt needsTransparency in terminal --- .../contrib/terminal/common/terminalColorRegistry.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts b/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts index 15e5cef62aa..34fa7dea75f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalColorRegistry.ts @@ -77,7 +77,7 @@ export const TERMINAL_FIND_MATCH_BACKGROUND_COLOR = registerColor('terminal.find // Use regular selection background in high contrast with a thick border hcDark: null, hcLight: '#0F4A85' -}, nls.localize('terminal.findMatchBackground', 'Color of the current search match in the terminal. The color must not be opaque so as not to hide underlying terminal content.')); +}, nls.localize('terminal.findMatchBackground', 'Color of the current search match in the terminal. The color must not be opaque so as not to hide underlying terminal content.'), true); export const TERMINAL_HOVER_HIGHLIGHT_BACKGROUND_COLOR = registerColor('terminal.hoverHighlightBackground', { dark: transparent(editorHoverHighlight, 0.5), light: transparent(editorHoverHighlight, 0.5), @@ -95,7 +95,7 @@ export const TERMINAL_FIND_MATCH_HIGHLIGHT_BACKGROUND_COLOR = registerColor('ter light: editorFindMatchHighlight, hcDark: null, hcLight: null -}, nls.localize('terminal.findMatchHighlightBackground', 'Color of the other search matches in the terminal. The color must not be opaque so as not to hide underlying terminal content.')); +}, nls.localize('terminal.findMatchHighlightBackground', 'Color of the other search matches in the terminal. The color must not be opaque so as not to hide underlying terminal content.'), true); export const TERMINAL_FIND_MATCH_HIGHLIGHT_BORDER_COLOR = registerColor('terminal.findMatchHighlightBorder', { dark: null, light: null, @@ -113,7 +113,7 @@ export const TERMINAL_DRAG_AND_DROP_BACKGROUND = registerColor('terminal.dropBac light: EDITOR_DRAG_AND_DROP_BACKGROUND, hcDark: EDITOR_DRAG_AND_DROP_BACKGROUND, hcLight: EDITOR_DRAG_AND_DROP_BACKGROUND -}, nls.localize('terminal.dragAndDropBackground', "Background color when dragging on top of terminals. The color should have transparency so that the terminal contents can still shine through.")); +}, nls.localize('terminal.dragAndDropBackground', "Background color when dragging on top of terminals. The color should have transparency so that the terminal contents can still shine through."), true); export const TERMINAL_TAB_ACTIVE_BORDER = registerColor('terminal.tab.activeBorder', { dark: TAB_ACTIVE_BORDER, light: TAB_ACTIVE_BORDER, From 0f4f9da9d406f87233412fdf97b6f7e25df08053 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 5 Dec 2023 16:57:25 +0100 Subject: [PATCH 05/37] added the property toggle locked and added an outline when the alt key is pressed --- src/vs/editor/contrib/hover/browser/contentHover.ts | 4 ++++ src/vs/editor/contrib/hover/browser/hover.css | 4 ++++ src/vs/editor/contrib/hover/browser/hover.ts | 10 ++++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index a33aba3a394..c361be19543 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -911,6 +911,10 @@ export class ContentHoverWidget extends ResizableContentWidget { public goToBottom(): void { this._hover.scrollbar.setScrollPosition({ scrollTop: this._hover.scrollbar.getScrollDimensions().scrollHeight }); } + + public toggleLocked(locked: boolean): void { + this._hover.containerDomNode.classList.toggle('locked', locked); + } } export class EditorHoverStatusBar extends Disposable implements IEditorHoverStatusBar { diff --git a/src/vs/editor/contrib/hover/browser/hover.css b/src/vs/editor/contrib/hover/browser/hover.css index 34695750fd4..649c7be5a3e 100644 --- a/src/vs/editor/contrib/hover/browser/hover.css +++ b/src/vs/editor/contrib/hover/browser/hover.css @@ -14,6 +14,10 @@ border-radius: 3px; } +.monaco-editor .monaco-hover.locked { + outline: 1px solid var(--vscode-editorHoverWidget-border); +} + .monaco-editor .monaco-hover a { color: var(--vscode-textLink-foreground); } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index ea0d9fb412d..a411963ec6f 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -206,6 +206,12 @@ export class ModesHoverController extends Disposable implements IEditorContribut private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { this._mouseMoveEvent = mouseEvent; + const isLocked = mouseEvent.event.altKey; + this._contentWidget?.widget.toggleLocked(isLocked); + if (mouseEvent.event.altKey) { + // When the alt key is pressed, hover remains open + return; + } if (this._contentWidget?.isFocused || this._contentWidget?.isResizing) { return; } @@ -217,10 +223,6 @@ export class ModesHoverController extends Disposable implements IEditorContribut // so moving the mouse has no effect return; } - if (mouseEvent.event.altKey) { - // When the alt key is pressed, hover remains open - return; - } const mouseIsOverWidget = this._isMouseOverWidget(mouseEvent); // If the mouse is over the widget and the hiding timeout is defined, then cancel it From 1bd5250a1df15f4c1c8c668410bff2e9a51b79ef Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 5 Dec 2023 17:08:20 +0100 Subject: [PATCH 06/37] doing the checks inside of the onKeyDown and onKeyUp listeners --- src/vs/editor/contrib/hover/browser/hover.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index a411963ec6f..f9d1c44c10e 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -58,6 +58,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut private _hoverActivatedByColorDecoratorClick: boolean = false; private _reactToEditorMouseMoveRunner: RunOnceScheduler; private _mouseMoveEvent: IEditorMouseEvent | undefined; + private _isLocked: boolean = false; static get(editor: ICodeEditor): ModesHoverController | null { return editor.getContribution(ModesHoverController.ID); @@ -96,6 +97,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut this._toUnhook.add(this._editor.onMouseUp((e: IEditorMouseEvent) => this._onEditorMouseUp(e))); this._toUnhook.add(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(e))); this._toUnhook.add(this._editor.onKeyDown((e: IKeyboardEvent) => this._onKeyDown(e))); + this._toUnhook.add(this._editor.onKeyUp((e: IKeyboardEvent) => this._onKeyUp(e))); } else { this._toUnhook.add(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(e))); this._toUnhook.add(this._editor.onKeyDown((e: IKeyboardEvent) => this._onKeyDown(e))); @@ -206,10 +208,8 @@ export class ModesHoverController extends Disposable implements IEditorContribut private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { this._mouseMoveEvent = mouseEvent; - const isLocked = mouseEvent.event.altKey; - this._contentWidget?.widget.toggleLocked(isLocked); - if (mouseEvent.event.altKey) { - // When the alt key is pressed, hover remains open + if (this._isLocked) { + // When the alt key is pressed, hover remains visible return; } if (this._contentWidget?.isFocused || this._contentWidget?.isResizing) { @@ -287,6 +287,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut if (!this._editor.hasModel()) { return; } + this._toggleLockedState(e.altKey); const resolvedKeyboardEvent = this._keybindingService.softDispatch(e, this._editor.getDomNode()); // If the beginning of a multi-chord keybinding is pressed, or the command aims to focus the hover, set the variable to true, otherwise false @@ -299,6 +300,17 @@ export class ModesHoverController extends Disposable implements IEditorContribut } } + private _onKeyUp(e: IKeyboardEvent): void { + this._toggleLockedState(!e.altKey); + } + + private _toggleLockedState(locked: boolean) { + if (this._isLocked !== locked) { + this._isLocked = locked; + this._contentWidget?.widget.toggleLocked(this._isLocked); + } + } + private _hideWidgets(): void { if (_sticky) { return; From ea0e5cda39f15f987a162ff39da18a541d989676 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 5 Dec 2023 17:39:13 +0100 Subject: [PATCH 07/37] Fixes #192440 --- .../editor/common/services/semanticTokensProviderStyling.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/common/services/semanticTokensProviderStyling.ts b/src/vs/editor/common/services/semanticTokensProviderStyling.ts index e08d06038bb..f248e0e23c2 100644 --- a/src/vs/editor/common/services/semanticTokensProviderStyling.ts +++ b/src/vs/editor/common/services/semanticTokensProviderStyling.ts @@ -105,21 +105,21 @@ export class SemanticTokensProviderStyling { public warnOverlappingSemanticTokens(lineNumber: number, startColumn: number): void { if (!this._hasWarnedOverlappingTokens) { this._hasWarnedOverlappingTokens = true; - console.warn(`Overlapping semantic tokens detected at lineNumber ${lineNumber}, column ${startColumn}`); + this._logService.warn(`Overlapping semantic tokens detected at lineNumber ${lineNumber}, column ${startColumn}`); } } public warnInvalidLengthSemanticTokens(lineNumber: number, startColumn: number): void { if (!this._hasWarnedInvalidLengthTokens) { this._hasWarnedInvalidLengthTokens = true; - console.warn(`Semantic token with invalid length detected at lineNumber ${lineNumber}, column ${startColumn}`); + this._logService.warn(`Semantic token with invalid length detected at lineNumber ${lineNumber}, column ${startColumn}`); } } public warnInvalidEditStart(previousResultId: string | undefined, resultId: string | undefined, editIndex: number, editStart: number, maxExpectedStart: number): void { if (!this._hasWarnedInvalidEditStart) { this._hasWarnedInvalidEditStart = true; - console.warn(`Invalid semantic tokens edit detected (previousResultId: ${previousResultId}, resultId: ${resultId}) at edit #${editIndex}: The provided start offset ${editStart} is outside the previous data (length ${maxExpectedStart}).`); + this._logService.warn(`Invalid semantic tokens edit detected (previousResultId: ${previousResultId}, resultId: ${resultId}) at edit #${editIndex}: The provided start offset ${editStart} is outside the previous data (length ${maxExpectedStart}).`); } } From cafbf86532bae621d165f8733b2e9de5896a90c0 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Dec 2023 18:00:28 +0100 Subject: [PATCH 08/37] add failing/skipped test for https://github.com/microsoft/vscode/issues/187055 (#200055) --- src/vs/base/test/common/filters.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/base/test/common/filters.test.ts b/src/vs/base/test/common/filters.test.ts index c80a6f84132..df8d25f3dab 100644 --- a/src/vs/base/test/common/filters.test.ts +++ b/src/vs/base/test/common/filters.test.ts @@ -498,6 +498,11 @@ suite('Filters', () => { assertTopScore(fuzzyScore, '_lineS', 0, '_lineS', '_lines'); }); + test.skip('Bad completion ranking changes valid variable name to class name when pressing "." #187055', function () { + assertTopScore(fuzzyScore, 'a', 1, 'A', 'a'); + assertTopScore(fuzzyScore, 'theme', 1, 'Theme', 'theme'); + }); + test('HTML closing tag proposal filtered out #38880', function () { assertMatches('\t\t<', '\t\t', '^\t^\t^', fuzzyScore, { patternPos: 0 }); assertMatches('\t\t<', '\t\t', '\t\t^', fuzzyScore, { patternPos: 2 }); From 4b6c84ef9c541ccb13bc21d897ee0f41cd6a1bf5 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Tue, 5 Dec 2023 09:35:36 -0800 Subject: [PATCH 09/37] add `css.format.spaceAroundSelectorSeparator: true` to the workspace and add spacing around `>` (#199993) --- .vscode/settings.json | 3 +- .../base/browser/ui/iconLabel/iconlabel.css | 2 +- .../codelens/browser/codelensWidget.css | 12 +- .../contrib/suggest/browser/media/suggest.css | 106 +++--- .../activitybar/media/activityaction.css | 2 +- .../parts/editor/media/breadcrumbscontrol.css | 18 +- .../contrib/comments/browser/media/review.css | 4 +- .../browser/media/extensionActions.css | 14 +- .../browser/media/runtimeExtensionsEditor.css | 2 +- .../contrib/inlineChat/browser/inlineChat.css | 2 +- .../browser/media/languageStatus.css | 26 +- .../notebook/browser/media/notebook.css | 2 +- .../browser/media/notebookCellChat.css | 2 +- .../browser/media/notebookFolding.css | 2 +- .../remote/browser/media/remoteViewlet.css | 2 +- .../browser/media/gettingStarted.css | 328 +++++++++--------- .../browser/media/walkThroughPart.css | 4 +- .../suggest/browser/media/suggest.css | 66 ++-- .../browser/media/userDataProfileView.css | 22 +- 19 files changed, 310 insertions(+), 309 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7434adcf4ae..163f114e7d7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -167,5 +167,6 @@ ], "[github-issues]": { "editor.wordWrap": "on" - } + }, + "css.format.spaceAroundSelectorSeparator": true, } diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index c847aecee2f..47f8891703c 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -51,7 +51,7 @@ opacity: 0.5; } -.monaco-icon-label>.monaco-icon-label-container>.monaco-icon-suffix-container>.label-suffix { +.monaco-icon-label > .monaco-icon-label-container > .monaco-icon-suffix-container > .label-suffix { opacity: .7; white-space: pre; } diff --git a/src/vs/editor/contrib/codelens/browser/codelensWidget.css b/src/vs/editor/contrib/codelens/browser/codelensWidget.css index ce61f837ef5..14711df31af 100644 --- a/src/vs/editor/contrib/codelens/browser/codelensWidget.css +++ b/src/vs/editor/contrib/codelens/browser/codelensWidget.css @@ -16,24 +16,24 @@ font-family: var(--vscode-editorCodeLens-fontFamily), var(--vscode-editorCodeLens-fontFamilyDefault); } -.monaco-editor .codelens-decoration>span, -.monaco-editor .codelens-decoration>a { +.monaco-editor .codelens-decoration > span, +.monaco-editor .codelens-decoration > a { user-select: none; -webkit-user-select: none; white-space: nowrap; vertical-align: sub; } -.monaco-editor .codelens-decoration>a { +.monaco-editor .codelens-decoration > a { text-decoration: none; } -.monaco-editor .codelens-decoration>a:hover { +.monaco-editor .codelens-decoration > a:hover { cursor: pointer; color: var(--vscode-editorLink-activeForeground) !important; } -.monaco-editor .codelens-decoration>a:hover .codicon { +.monaco-editor .codelens-decoration > a:hover .codicon { color: var(--vscode-editorLink-activeForeground) !important; } @@ -45,7 +45,7 @@ font-size: var(--vscode-editorCodeLens-fontSize); } -.monaco-editor .codelens-decoration>a:hover .codicon::before { +.monaco-editor .codelens-decoration > a:hover .codicon::before { cursor: pointer; } diff --git a/src/vs/editor/contrib/suggest/browser/media/suggest.css b/src/vs/editor/contrib/suggest/browser/media/suggest.css index bac06376685..597fa5411b3 100644 --- a/src/vs/editor/contrib/suggest/browser/media/suggest.css +++ b/src/vs/editor/contrib/suggest/browser/media/suggest.css @@ -71,24 +71,24 @@ margin-right: 0.3em; } -.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row>.contents>.main>.right>.readMore, -.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row.focused.string-label>.contents>.main>.right>.readMore { +.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row > .contents > .main > .right > .readMore, +.monaco-editor .suggest-widget.with-status-bar .monaco-list .monaco-list-row.focused.string-label > .contents > .main > .right > .readMore { display: none; } -.monaco-editor .suggest-widget.with-status-bar:not(.docs-side) .monaco-list .monaco-list-row:hover>.contents>.main>.right.can-expand-details>.details-label { +.monaco-editor .suggest-widget.with-status-bar:not(.docs-side) .monaco-list .monaco-list-row:hover > .contents > .main > .right.can-expand-details > .details-label { width: 100%; } /* Styles for Message element for when widget is loading or is empty */ -.monaco-editor .suggest-widget>.message { +.monaco-editor .suggest-widget > .message { padding-left: 22px; } /** Styles for the list element **/ -.monaco-editor .suggest-widget>.tree { +.monaco-editor .suggest-widget > .tree { height: 100%; width: 100%; } @@ -120,14 +120,14 @@ color: var(--vscode-editorSuggestWidget-selectedIconForeground); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents { flex: 1; height: 100%; overflow: hidden; padding-left: 2px; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main { display: flex; overflow: hidden; text-overflow: ellipsis; @@ -135,12 +135,12 @@ justify-content: space-between; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left, -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left, +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right { display: flex; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.focused)>.contents>.main .monaco-icon-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.focused) > .contents > .main .monaco-icon-label { color: var(--vscode-editorSuggestWidget-foreground); } @@ -148,48 +148,48 @@ font-weight: bold; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main .monaco-highlighted-label .highlight { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main .monaco-highlighted-label .highlight { color: var(--vscode-editorSuggestWidget-highlightForeground); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused>.contents>.main .monaco-highlighted-label .highlight { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused > .contents > .main .monaco-highlighted-label .highlight { color: var(--vscode-editorSuggestWidget-focusHighlightForeground); } /** ReadMore Icon styles **/ -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.codicon-close, -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.readMore::before { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .codicon-close, +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .readMore::before { color: inherit; opacity: 1; font-size: 14px; cursor: pointer; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.codicon-close { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .codicon-close { position: absolute; top: 6px; right: 2px; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.codicon-close:hover, -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.readMore:hover { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .codicon-close:hover, +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .readMore:hover { opacity: 1; } /** signature, qualifier, type/details opacity **/ -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label { opacity: 0.7; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.signature-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .signature-label { overflow: hidden; text-overflow: ellipsis; opacity: 0.6; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.qualifier-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .qualifier-label { margin-left: 12px; opacity: 0.4; font-size: 85%; @@ -201,7 +201,7 @@ /** Type Info and icon next to the label in the focused completion item **/ -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label { font-size: 85%; margin-left: 1.1em; overflow: hidden; @@ -209,58 +209,58 @@ white-space: nowrap; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label>.monaco-tokenized-source { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label > .monaco-tokenized-source { display: inline; } /** Details: if using CompletionItem#details, show on focus **/ -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label { display: none; } -.monaco-editor .suggest-widget:not(.shows-details) .monaco-list .monaco-list-row.focused>.contents>.main>.right>.details-label { +.monaco-editor .suggest-widget:not(.shows-details) .monaco-list .monaco-list-row.focused > .contents > .main > .right > .details-label { display: inline; } /** Details: if using CompletionItemLabel#details, always show **/ -.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label)>.contents>.main>.right>.details-label, -.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row.focused:not(.string-label)>.contents>.main>.right>.details-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label) > .contents > .main > .right > .details-label, +.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row.focused:not(.string-label) > .contents > .main > .right > .details-label { display: inline; } /** Ellipsis on hover **/ -.monaco-editor .suggest-widget:not(.docs-side) .monaco-list .monaco-list-row.focused:hover>.contents>.main>.right.can-expand-details>.details-label { +.monaco-editor .suggest-widget:not(.docs-side) .monaco-list .monaco-list-row.focused:hover > .contents > .main > .right.can-expand-details > .details-label { width: calc(100% - 26px); } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left { flex-shrink: 1; flex-grow: 1; overflow: hidden; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.monaco-icon-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .monaco-icon-label { flex-shrink: 0; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label)>.contents>.main>.left>.monaco-icon-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row:not(.string-label) > .contents > .main > .left > .monaco-icon-label { max-width: 100%; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label>.contents>.main>.left>.monaco-icon-label { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label > .contents > .main > .left > .monaco-icon-label { flex-shrink: 1; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right { overflow: hidden; flex-shrink: 4; max-width: 70%; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.readMore { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .readMore { display: inline-block; position: absolute; right: 10px; @@ -271,23 +271,23 @@ /** Do NOT display ReadMore when docs is side/below **/ -.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row>.contents>.main>.right>.readMore { +.monaco-editor .suggest-widget.docs-side .monaco-list .monaco-list-row > .contents > .main > .right > .readMore { display: none !important; } /** Do NOT display ReadMore when using plain CompletionItemLabel (details/documentation might not be resolved) **/ -.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label>.contents>.main>.right>.readMore { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row.string-label > .contents > .main > .right > .readMore { display: none; } /** Focused item can show ReadMore, but can't when docs is side/below **/ -.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused.string-label>.contents>.main>.right>.readMore { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused.string-label > .contents > .main > .right > .readMore { display: inline-block; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused:hover>.contents>.main>.right>.readMore { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row.focused:hover > .contents > .main > .right > .readMore { visibility: visible; } @@ -298,7 +298,7 @@ text-decoration: unset; } -.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated>.monaco-icon-label-container>.monaco-icon-name-container { +.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated > .monaco-icon-label-container > .monaco-icon-name-container { text-decoration: line-through; } @@ -372,17 +372,17 @@ display: none; } -.monaco-editor .suggest-details>.monaco-scrollable-element { +.monaco-editor .suggest-details > .monaco-scrollable-element { flex: 1; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body { box-sizing: border-box; height: 100%; width: 100%; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.type { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .type { flex: 2; overflow: hidden; text-overflow: ellipsis; @@ -392,55 +392,55 @@ padding: 4px 0 12px 5px; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.header>.type.auto-wrap { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .header > .type.auto-wrap { white-space: normal; word-break: break-all; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs { margin: 0; padding: 4px 5px; white-space: pre-wrap; } -.monaco-editor .suggest-details.no-type>.monaco-scrollable-element>.body>.docs { +.monaco-editor .suggest-details.no-type > .monaco-scrollable-element > .body > .docs { margin-right: 24px; overflow: hidden; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs { padding: 0; white-space: initial; min-height: calc(1rem + 8px); } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>div, -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>span:not(:empty) { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > div, +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > span:not(:empty) { padding: 4px 5px; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>div>p:first-child { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > div > p:first-child { margin-top: 0; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs>div>p:last-child { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs > div > p:last-child { margin-bottom: 0; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs .monaco-tokenized-source { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs .monaco-tokenized-source { white-space: pre; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs .code { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs .code { white-space: pre-wrap; word-wrap: break-word; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>.docs.markdown-docs .codicon { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > .docs.markdown-docs .codicon { vertical-align: sub; } -.monaco-editor .suggest-details>.monaco-scrollable-element>.body>p:empty { +.monaco-editor .suggest-details > .monaco-scrollable-element > .body > p:empty { display: none; } diff --git a/src/vs/workbench/browser/parts/activitybar/media/activityaction.css b/src/vs/workbench/browser/parts/activitybar/media/activityaction.css index abba016e91d..99df125f3a8 100644 --- a/src/vs/workbench/browser/parts/activitybar/media/activityaction.css +++ b/src/vs/workbench/browser/parts/activitybar/media/activityaction.css @@ -234,7 +234,7 @@ /* Right aligned */ -.monaco-workbench .activitybar.right>.content :not(.monaco-menu)>.monaco-action-bar .profile-badge, +.monaco-workbench .activitybar.right > .content :not(.monaco-menu) > .monaco-action-bar .profile-badge, .monaco-workbench .activitybar.right > .content :not(.monaco-menu) > .monaco-action-bar .badge { left: auto; right: 0; diff --git a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css index 3b8bac4565d..ec3ef9c9c13 100644 --- a/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css +++ b/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css @@ -3,17 +3,17 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control.hidden { +.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control.hidden { display: none; } -.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label, -.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label { +.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .monaco-icon-label, +.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .monaco-icon-label { text-decoration-line: underline; } -.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .hint-more, -.monaco-workbench .part.editor>.content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .hint-more { +.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.selected .hint-more, +.monaco-workbench .part.editor > .content .editor-group-container .breadcrumbs-control .monaco-breadcrumb-item.focused .hint-more { text-decoration-line: underline; } @@ -41,22 +41,22 @@ flex-direction: column; } -.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree>.input { +.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree > .input { padding: 5px 9px; position: relative; box-sizing: border-box; height: 36px; } -.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree>.tree { +.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree > .tree { height: calc(100% - 36px); } -.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive>.input { +.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive > .input { display: none; } -.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive>.tree { +.monaco-workbench .monaco-breadcrumbs-picker .highlighting-tree.inactive > .tree { height: 100%; } diff --git a/src/vs/workbench/contrib/comments/browser/media/review.css b/src/vs/workbench/contrib/comments/browser/media/review.css index b2ce28c5e14..cad293ca09e 100644 --- a/src/vs/workbench/contrib/comments/browser/media/review.css +++ b/src/vs/workbench/contrib/comments/browser/media/review.css @@ -298,8 +298,8 @@ width: auto; } -.review-widget .body .comment-additional-actions .button-bar>.monaco-text-button, -.review-widget .body .comment-additional-actions .button-bar>.monaco-button-dropdown { +.review-widget .body .comment-additional-actions .button-bar > .monaco-text-button, +.review-widget .body .comment-additional-actions .button-bar > .monaco-button-dropdown { margin: 0 10px 0 0; } diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css b/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css index 4ae58e118a1..b2eaa27034a 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css @@ -10,12 +10,12 @@ text-overflow: ellipsis; } -.monaco-action-bar .action-item>.action-label.extension-action.label, -.monaco-action-bar .action-dropdown-item>.action-label.extension-action.label { +.monaco-action-bar .action-item > .action-label.extension-action.label, +.monaco-action-bar .action-dropdown-item > .action-label.extension-action.label { padding: 0 5px; } -.monaco-action-bar .action-dropdown-item>.monaco-dropdown .action-label { +.monaco-action-bar .action-dropdown-item > .monaco-dropdown .action-label { padding: 0; } @@ -36,7 +36,7 @@ } .monaco-action-bar .action-item .action-label.extension-action.label, -.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator { +.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator { background-color: var(--vscode-extensionButton-background) !important; } @@ -48,12 +48,12 @@ background-color: var(--vscode-extensionButton-hoverBackground) !important; } -.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator>div { +.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator > div { background-color: var(--vscode-extensionButton-separator); } .monaco-action-bar .action-item .action-label.extension-action.label.prominent, -.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator.prominent { +.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator.prominent { background-color: var(--vscode-extensionButton-prominentBackground); } @@ -69,7 +69,7 @@ border: 1px solid var(--vscode-contrastBorder); } -.monaco-action-bar .action-item.action-dropdown-item>.action-dropdown-item-separator { +.monaco-action-bar .action-item.action-dropdown-item > .action-dropdown-item-separator { border-top: 1px solid var(--vscode-contrastBorder); border-bottom: 1px solid var(--vscode-contrastBorder); } diff --git a/src/vs/workbench/contrib/extensions/browser/media/runtimeExtensionsEditor.css b/src/vs/workbench/contrib/extensions/browser/media/runtimeExtensionsEditor.css index e1c4ea5afd2..7187efb1757 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/runtimeExtensionsEditor.css +++ b/src/vs/workbench/contrib/extensions/browser/media/runtimeExtensionsEditor.css @@ -31,7 +31,7 @@ text-align: right; } -.runtime-extensions-editor .extension .desc>.msg>span:not(:last-child)::after { +.runtime-extensions-editor .extension .desc > .msg > span:not(:last-child)::after { content: '\2022'; padding: 0 4px; opacity: .8; diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css index 6d16be3ce3a..9e4e77cfe38 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChat.css @@ -93,7 +93,7 @@ } /* UGLY - fighting against workbench styles */ -.monaco-workbench .part.editor>.content .monaco-editor .inline-chat .progress .monaco-progress-container { +.monaco-workbench .part.editor > .content .monaco-editor .inline-chat .progress .monaco-progress-container { top: 0; } diff --git a/src/vs/workbench/contrib/languageStatus/browser/media/languageStatus.css b/src/vs/workbench/contrib/languageStatus/browser/media/languageStatus.css index da152cb9208..f7fb23f59c6 100644 --- a/src/vs/workbench/contrib/languageStatus/browser/media/languageStatus.css +++ b/src/vs/workbench/contrib/languageStatus/browser/media/languageStatus.css @@ -25,7 +25,7 @@ } } -.monaco-workbench .statusbar DIV#status\.languageStatus A>SPAN.codicon.wiggle { +.monaco-workbench .statusbar DIV#status\.languageStatus A > SPAN.codicon.wiggle { animation-duration: .8s; animation-iteration-count: 1; animation-name: wiggle; @@ -62,60 +62,60 @@ border-bottom: 1px solid var(--vscode-notifications-border); } -.monaco-workbench .hover-language-status>.severity { +.monaco-workbench .hover-language-status > .severity { padding-right: 8px; flex: 1; margin: auto; display: none; } -.monaco-workbench .hover-language-status>.severity.sev3 { +.monaco-workbench .hover-language-status > .severity.sev3 { color: var(--vscode-notificationsErrorIcon-foreground) } -.monaco-workbench .hover-language-status>.severity.sev2 { +.monaco-workbench .hover-language-status > .severity.sev2 { color: var(--vscode-notificationsInfoIcon-foreground) } -.monaco-workbench .hover-language-status>.severity.show { +.monaco-workbench .hover-language-status > .severity.show { display: inherit; } -.monaco-workbench .hover-language-status>.element { +.monaco-workbench .hover-language-status > .element { display: flex; justify-content: space-between; vertical-align: middle; flex-grow: 100; } -.monaco-workbench .hover-language-status>.element>.left>.detail:not(:empty)::before { +.monaco-workbench .hover-language-status > .element > .left > .detail:not(:empty)::before { content: '\2013'; padding: 0 4px; opacity: 0.6; } -.monaco-workbench .hover-language-status>.element>.left>.label:empty { +.monaco-workbench .hover-language-status > .element > .left > .label:empty { display: none; } -.monaco-workbench .hover-language-status>.element .left { +.monaco-workbench .hover-language-status > .element .left { margin: auto 0; } -.monaco-workbench .hover-language-status>.element .right { +.monaco-workbench .hover-language-status > .element .right { margin: auto 0; display: flex; } -.monaco-workbench .hover-language-status>.element .right:not(:empty) { +.monaco-workbench .hover-language-status > .element .right:not(:empty) { padding-left: 16px; } -.monaco-workbench .hover-language-status>.element .right .monaco-link { +.monaco-workbench .hover-language-status > .element .right .monaco-link { margin: auto 0; white-space: nowrap; } -.monaco-workbench .hover-language-status>.element .right .monaco-action-bar:not(:first-child) { +.monaco-workbench .hover-language-status > .element .right .monaco-action-bar:not(:first-child) { padding-left: 8px; } diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebook.css b/src/vs/workbench/contrib/notebook/browser/media/notebook.css index c22bc652ca7..309b3b4ef84 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebook.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebook.css @@ -258,7 +258,7 @@ text-align: center; } -.monaco-workbench .notebookOverlay>.cell-list-container>.monaco-list>.monaco-scrollable-element>.monaco-list-rows>.monaco-list-row .cell-statusbar-hidden .execution-count-label { +.monaco-workbench .notebookOverlay > .cell-list-container > .monaco-list > .monaco-scrollable-element > .monaco-list-rows > .monaco-list-row .cell-statusbar-hidden .execution-count-label { line-height: 15px; } diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebookCellChat.css b/src/vs/workbench/contrib/notebook/browser/media/notebookCellChat.css index 5c0081e507d..fda2877f566 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebookCellChat.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebookCellChat.css @@ -97,7 +97,7 @@ } /* UGLY - fighting against workbench styles */ -.monaco-workbench .part.editor>.content .monaco-editor .inline-chat .progress .monaco-progress-container { +.monaco-workbench .part.editor > .content .monaco-editor .inline-chat .progress .monaco-progress-container { top: 0; } diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebookFolding.css b/src/vs/workbench/contrib/notebook/browser/media/notebookFolding.css index 8dc8d7eb123..7433c9a7eb2 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebookFolding.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebookFolding.css @@ -43,7 +43,7 @@ padding: 4px 4px 4px 4px; } -.monaco-workbench .notebookOverlay>.cell-list-container .notebook-folded-hint { +.monaco-workbench .notebookOverlay > .cell-list-container .notebook-folded-hint { position: absolute; user-select: none; } diff --git a/src/vs/workbench/contrib/remote/browser/media/remoteViewlet.css b/src/vs/workbench/contrib/remote/browser/media/remoteViewlet.css index ef32cf43f39..4ebb0d89702 100644 --- a/src/vs/workbench/contrib/remote/browser/media/remoteViewlet.css +++ b/src/vs/workbench/contrib/remote/browser/media/remoteViewlet.css @@ -13,7 +13,7 @@ flex-wrap: nowrap; } -.remote-help-content .monaco-list .monaco-list-row .remote-help-tree-node-item>.remote-help-tree-node-item-icon { +.remote-help-content .monaco-list .monaco-list-row .remote-help-tree-node-item > .remote-help-tree-node-item-icon { background-size: 16px; background-position: left center; background-repeat: no-repeat; diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css b/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css index 0790a628607..2a31a8ba681 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css @@ -8,7 +8,7 @@ background-image: url('../../../../browser/media/code-icon.svg'); } -.monaco-workbench .part.editor>.content .gettingStartedContainer { +.monaco-workbench .part.editor > .content .gettingStartedContainer { box-sizing: border-box; line-height: 22px; position: relative; @@ -20,26 +20,26 @@ outline: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.loading { +.monaco-workbench .part.editor > .content .gettingStartedContainer.loading { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer img { +.monaco-workbench .part.editor > .content .gettingStartedContainer img { max-width: 100%; max-height: 100%; object-fit: contain; pointer-events: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer { +.monaco-workbench .part.editor > .content .gettingStartedContainer { font-size: 13px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStarted { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStarted { height: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer h1 { +.monaco-workbench .part.editor > .content .gettingStartedContainer h1 { padding: 5px 0 0; margin: 0; border: none; @@ -48,24 +48,24 @@ white-space: nowrap; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .title { +.monaco-workbench .part.editor > .content .gettingStartedContainer .title { margin-top: 1em; margin-bottom: 1em; flex: 1 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .subtitle { +.monaco-workbench .part.editor > .content .gettingStartedContainer .subtitle { margin-top: .6em; font-size: 2em; display: block; } -.monaco-workbench.hc-black .part.editor>.content .gettingStartedContainer .subtitle, -.monaco-workbench.hc-light .part.editor>.content .gettingStartedContainer .subtitle { +.monaco-workbench.hc-black .part.editor > .content .gettingStartedContainer .subtitle, +.monaco-workbench.hc-light .part.editor > .content .gettingStartedContainer .subtitle { font-weight: 200; } -.monaco-workbench .part.editor>.content .gettingStartedContainer h2 { +.monaco-workbench .part.editor > .content .gettingStartedContainer h2 { font-weight: 400; margin-top: 0; margin-bottom: 5px; @@ -73,12 +73,12 @@ line-height: initial; } -.monaco-workbench .part.editor>.content .gettingStartedContainer a:focus { +.monaco-workbench .part.editor > .content .gettingStartedContainer a:focus { outline: 1px solid -webkit-focus-ring-color; outline-offset: -1px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide { width: 100%; height: 100%; padding: 0; @@ -88,23 +88,23 @@ top: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories { padding: 12px 24px; } /* duplicated until the getting-started specific setting is removed */ -.monaco-workbench .part.editor>.content .gettingStartedContainer.animatable .gettingStartedSlide { +.monaco-workbench .part.editor > .content .gettingStartedContainer.animatable .gettingStartedSlide { /* keep consistant with SLIDE_TRANSITION_TIME_MS in gettingStarted.ts */ transition: left 0.25s, opacity 0.25s; } -.monaco-workbench.reduce-motion .part.editor>.content .gettingStartedContainer .gettingStartedSlide, -.monaco-workbench.reduce-motion .part.editor>.content .gettingStartedContainer.animatable .gettingStartedSlide { +.monaco-workbench.reduce-motion .part.editor > .content .gettingStartedContainer .gettingStartedSlide, +.monaco-workbench.reduce-motion .part.editor > .content .gettingStartedContainer.animatable .gettingStartedSlide { /* keep consistant with SLIDE_TRANSITION_TIME_MS in gettingStarted.ts */ transition: left 0.0s, opacity 0.0s; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer { display: grid; height: 100%; max-width: 1200px; @@ -117,73 +117,73 @@ ". footer footer footer ."; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.width-constrained .gettingStartedSlideCategories>.gettingStartedCategoriesContainer { +.monaco-workbench .part.editor > .content .gettingStartedContainer.width-constrained .gettingStartedSlideCategories > .gettingStartedCategoriesContainer { grid-template-rows: auto min-content minmax(min-content, auto) min-content; grid-template-columns: 1fr; grid-template-areas: "header" "left-column" "right-column" "footer"; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.height-constrained .gettingStartedSlideCategories>.gettingStartedCategoriesContainer { +.monaco-workbench .part.editor > .content .gettingStartedContainer.height-constrained .gettingStartedSlideCategories > .gettingStartedCategoriesContainer { grid-template-rows: auto minmax(min-content, auto) min-content; grid-template-areas: "header" "left-column right-column" "footer footer"; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.height-constrained.width-constrained .gettingStartedSlideCategories>.gettingStartedCategoriesContainer { +.monaco-workbench .part.editor > .content .gettingStartedContainer.height-constrained.width-constrained .gettingStartedSlideCategories > .gettingStartedCategoriesContainer { grid-template-rows: min-content minmax(min-content, auto) min-content; grid-template-columns: 1fr; grid-template-areas: "left-column" "right-column" "footer"; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.width-constrained .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.header, .monaco-workbench .part.editor>.content .gettingStartedContainer.height-constrained .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.header { +.monaco-workbench .part.editor > .content .gettingStartedContainer.width-constrained .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .header, .monaco-workbench .part.editor > .content .gettingStartedContainer.height-constrained .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .header { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories li.showWalkthroughsEntry { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories li.showWalkthroughsEntry { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.noWalkthroughs .gettingStartedSlideCategories li.showWalkthroughsEntry, .gettingStartedContainer.noExtensions { +.monaco-workbench .part.editor > .content .gettingStartedContainer.noWalkthroughs .gettingStartedSlideCategories li.showWalkthroughsEntry, .gettingStartedContainer.noExtensions { display: unset; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>* { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > * { overflow: hidden; text-overflow: ellipsis; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.categories-column>div { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .categories-column > div { margin-bottom: 32px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.categories-column-left { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .categories-column-left { grid-area: left-column; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.categories-column-right { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .categories-column-right { grid-area: right-column; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.header { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .header { grid-area: header; align-self: end; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.footer { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .footer { grid-area: footer; justify-self: center; text-align: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .categories-slide-container { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .categories-slide-container { width: 90%; max-width: 1200px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .gap { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .gap { flex: 150px 0 1000 } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .category-title { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .category-title { margin: 4px 0 4px; font-size: 14px; font-weight: 500; @@ -194,58 +194,58 @@ white-space: nowrap; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .category-progress { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .category-progress { position: absolute; bottom: 0; left: 0; width: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category.no-progress { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category.no-progress { padding: 3px 6px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .getting-started-category.no-progress .category-progress { +.monaco-workbench .part.editor > .content .gettingStartedContainer .getting-started-category.no-progress .category-progress { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories ul { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories ul { list-style: none; margin: 0; line-height: 24px; padding-left: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories li { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories li { list-style: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .path { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .path { padding-left: 1em; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .icon-widget, -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .icon-widget, -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .featured-icon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .icon-widget, +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .icon-widget, +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .featured-icon { font-size: 20px; padding-right: 8px; position: relative; top: 3px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .codicon:not(.icon-widget, .featured-icon, .hide-category-button) { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .codicon:not(.icon-widget, .featured-icon, .hide-category-button) { margin: 0 2px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .codicon:first-child { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .codicon:first-child { margin-left: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .start-container img { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .start-container img { padding-right: 8px; position: relative; top: 3px; @@ -253,20 +253,20 @@ max-height: 16px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .keybinding-label { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .keybinding-label { padding-left: 1em; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .progress-bar-outer { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .progress-bar-outer { height: 4px; margin-top: 4px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .progress-bar-inner { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .progress-bar-inner { height: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category { width: calc(100% - 16px); font-size: 13px; box-sizing: border-box; @@ -276,36 +276,36 @@ text-align: left; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .getting-started-category { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .getting-started-category { position: relative; border-radius: 6px; overflow: hidden; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .main-content { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .main-content { display: flex; align-items: center; justify-content: flex-start; width: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured-description-content, -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured-description-content, +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content { text-align: left; margin-left: 28px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content > .codicon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content > .codicon { padding-right: 1px; font-size: 16px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content:not(:empty){ +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .description-content:not(:empty){ margin-bottom: 8px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured-description-content:not(:empty){ +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured-description-content:not(:empty){ margin-bottom: 8px; margin-left: 32px; overflow: hidden; @@ -314,7 +314,7 @@ -webkit-box-orient: vertical; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .new-badge { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .new-badge { justify-self: flex-end; align-self: flex-start; border-radius: 4px; @@ -324,13 +324,13 @@ white-space: nowrap; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured-badge { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured-badge { position: relative; top: -4px; left: -8px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured { border-top: 30px solid var(--vscode-activityBarBadge-background); width: 30px; box-sizing: border-box; @@ -339,23 +339,23 @@ position: absolute; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured .featured-icon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured .featured-icon { top: -30px; left: 4px; font-size: 14px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .codicon.hide-category-button { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .codicon.hide-category-button { margin-left: auto; top: 4px; right: 8px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category.featured .icon-widget { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category.featured .icon-widget { visibility: hidden; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .getting-started-category img.category-icon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .getting-started-category img.category-icon { padding-right: 8px; max-width: 20px; max-height: 20px; @@ -363,7 +363,7 @@ top: auto; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories .getting-started-category img.featured-icon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories .getting-started-category img.featured-icon { padding-right: 8px; max-width: 24px; max-height: 24px; @@ -371,80 +371,80 @@ position: relative; top: auto; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-category img.category-icon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-category img.category-icon { margin-right: 10px; margin-left: 10px; max-width: 32px; max-height: 32px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails { display: flex; flex-direction: column; overflow: hidden; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gap { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gap { flex: 150px 0 1000 } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-category { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-category { display: flex; margin-bottom: 24px; min-height: auto; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-columns .gap { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-columns .gap { flex: 150px 1 1000 } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent>.getting-started-category>.codicon-getting-started-setup { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent > .getting-started-category > .codicon-getting-started-setup { margin-right: 8px; font-size: 28px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-columns { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-columns { display: flex; justify-content: flex-start; padding: 40px 40px 0; max-height: calc(100% - 40px); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step { display: flex; width: 100%; overflow: hidden; border-radius: 6px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .button-container:not(:last-of-type) { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .button-container:not(:last-of-type) { margin-bottom: 6px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step.expanded { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step.expanded { cursor: default !important; border: 1px solid var(--vscode-welcomePage-tileBorder); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step.expanded h3 { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step.expanded h3 { color: var(--vscode-walkthrough-stepTitle-foreground); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step.expanded>.codicon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step.expanded > .codicon { cursor: pointer !important; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded) { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded) { height: 48px; background: none; color: var(--vscode-descriptionForeground); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded):hover { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded):hover { background: var(--vscode-welcomePage-tileHoverBackground); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded) .step-title { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded) .step-title { white-space: nowrap; text-overflow: ellipsis; display: inline-block; @@ -452,66 +452,66 @@ width: inherit; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-title .codicon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-title .codicon { position: relative; top: 2px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-columns .getting-started-detail-left>div { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-columns .getting-started-detail-left > div { width: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded) .step-description-container { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step:not(.expanded) .step-description-container { visibility: hidden; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-container { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-container { width: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description { padding-top: 8px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .actions { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .actions { margin-top: 12px; display: flex; align-items: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .shortcut-message { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .shortcut-message { display: flex; color: var(--vscode-descriptionForeground); font-size: 12px; margin-top: 12px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .shortcut-message .keybinding { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .shortcut-message .keybinding { font-weight: 600; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-next { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-next { margin-left: auto; margin-right: 10px; padding: 6px 12px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .codicon.hidden { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .codicon.hidden { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .codicon-getting-started-step-unchecked, -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .codicon-getting-started-step-checked { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .codicon-getting-started-step-unchecked, +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .codicon-getting-started-step-checked { margin-right: 8px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step-action { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step-action { padding: 6px 12px; font-size: 13px; margin-bottom: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-left { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-left { min-width: 330px; width: 40%; max-width: 400px; @@ -519,15 +519,15 @@ flex-direction: column; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .full-height-scrollable { +.monaco-workbench .part.editor > .content .gettingStartedContainer .full-height-scrollable { height: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-container { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-container { height: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent { height: 100%; max-width: 1200px; margin: 0 auto; @@ -543,7 +543,7 @@ ". footer footer footer ."; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.width-semi-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent { +.monaco-workbench .part.editor > .content .gettingStartedContainer.width-semi-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent { max-width: 500px; grid-template-columns: auto; grid-template-rows: 30px max-content minmax(30%, max-content) minmax(30%, 1fr) auto; @@ -551,45 +551,45 @@ grid-template-areas: "back" "title" "steps" "media" "footer"; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.width-semi-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent.markdown { +.monaco-workbench .part.editor > .content .gettingStartedContainer.width-semi-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent.markdown { grid-template-rows: 30px max-content minmax(30%, max-content) minmax(40%, 1fr) auto; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.width-semi-constrained.height-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent { +.monaco-workbench .part.editor > .content .gettingStartedContainer.width-semi-constrained.height-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent { grid-template-rows: 0 max-content minmax(25%, max-content) minmax(25%, 1fr) auto; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent>.prev-button { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent > .prev-button { grid-area: back; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent>.getting-started-category { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent > .getting-started-category { grid-area: title; align-self: flex-end; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent>.steps-container { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent > .steps-container { height: 100%; grid-area: steps; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent>.getting-started-media { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent > .getting-started-media { grid-area: media; align-self: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent.markdown>.getting-started-media { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent.markdown > .getting-started-media { height: inherit; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent.image>.getting-started-media { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent.image > .getting-started-media { grid-area: title-start / media-start / steps-end / media-end; align-self: unset; display: flex; justify-content: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.width-semi-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent.image>.getting-started-media { +.monaco-workbench .part.editor > .content .gettingStartedContainer.width-semi-constrained .gettingStartedSlideDetails .gettingStartedDetailsContent.image > .getting-started-media { grid-area: media; height: inherit; width: inherit; @@ -597,14 +597,14 @@ justify-content: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent>.getting-started-footer { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .gettingStartedDetailsContent > .getting-started-footer { grid-area: footer; align-self: flex-end; justify-self: center; text-align: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-right { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-right { display: flex; align-items: flex-start; justify-content: center; @@ -615,36 +615,36 @@ max-width: 800px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .index-list.getting-started .button-link { +.monaco-workbench .part.editor > .content .gettingStartedContainer .index-list.getting-started .button-link { margin: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .index-list.getting-started .see-all-walkthroughs { +.monaco-workbench .part.editor > .content .gettingStartedContainer .index-list.getting-started .see-all-walkthroughs { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.someWalkthroughsHidden .index-list.getting-started .see-all-walkthroughs { +.monaco-workbench .part.editor > .content .gettingStartedContainer.someWalkthroughsHidden .index-list.getting-started .see-all-walkthroughs { display: inline; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.noExtensions .index-list.featured-extensions { +.monaco-workbench .part.editor > .content .gettingStartedContainer.noExtensions .index-list.featured-extensions { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.noWalkthroughs .index-list.getting-started { +.monaco-workbench .part.editor > .content .gettingStartedContainer.noWalkthroughs .index-list.getting-started { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-right img { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-right img { object-fit: contain; cursor: unset; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-right img.clickable { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-detail-right img.clickable { cursor: pointer; } -.monaco-workbench .part.editor>.content .gettingStartedContainer button { +.monaco-workbench .part.editor > .content .gettingStartedContainer button { border: none; color: inherit; text-align: left; @@ -655,21 +655,21 @@ font-family: inherit; } -.monaco-workbench .part.editor>.content .gettingStartedContainer button:hover { +.monaco-workbench .part.editor > .content .gettingStartedContainer button:hover { cursor: pointer; } /* Don't show focus outline on mouse click. Instead only show outline on keyboard focus. */ -.monaco-workbench .part.editor>.content .gettingStartedContainer button:focus { +.monaco-workbench .part.editor > .content .gettingStartedContainer button:focus { outline: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer button:focus-visible { +.monaco-workbench .part.editor > .content .gettingStartedContainer button:focus-visible { outline: 1px solid var(--vscode-focusBorder); outline-offset: -1px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .prev-button.button-link { +.monaco-workbench .part.editor > .content .gettingStartedContainer .prev-button.button-link { position: absolute; left: 40px; top: 5px; @@ -679,91 +679,91 @@ display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.width-semi-constrained .prev-button.button-link { +.monaco-workbench .part.editor > .content .gettingStartedContainer.width-semi-constrained .prev-button.button-link { left: 0; top: -10px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.height-constrained .prev-button.button-link { +.monaco-workbench .part.editor > .content .gettingStartedContainer.height-constrained .prev-button.button-link { left: 0; top: -10px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.height-constrained .prev-button.button-link .codicon { +.monaco-workbench .part.editor > .content .gettingStartedContainer.height-constrained .prev-button.button-link .codicon { font-size: 20px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer.height-constrained .prev-button.button-link .moreText { +.monaco-workbench .part.editor > .content .gettingStartedContainer.height-constrained .prev-button.button-link .moreText { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .prev-button:hover { +.monaco-workbench .part.editor > .content .gettingStartedContainer .prev-button:hover { cursor: pointer; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .prev-button .codicon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .prev-button .codicon { position: relative; top: 3px; left: -4px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .button-link .codicon-arrow-right { +.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link .codicon-arrow-right { padding-left: 4px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .button-link .codicon-check-all { +.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link .codicon-check-all { padding-right: 4px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .skip { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .skip { display: block; margin: 2px auto; width: fit-content; text-align: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails h2 { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails h2 { font-size: 26px; font-weight: normal; margin: 0 0 8px 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails h2 .codicon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails h2 .codicon { font-size: 20px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails h3 { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails h3 { font-size: 13px; font-weight: 600; margin: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .subtitle { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .subtitle { font-size: 16px; margin: 0; padding: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStarted.showCategories .gettingStartedSlideDetails { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStarted.showCategories .gettingStartedSlideDetails { left: 100%; opacity: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStarted.showDetails .gettingStartedSlideCategories { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStarted.showDetails .gettingStartedSlideCategories { left: -100%; opacity: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStarted.showDetails .categoriesScrollbar .scrollbar.vertical { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStarted.showDetails .categoriesScrollbar .scrollbar.vertical { display: none; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .done-next-container { +.monaco-workbench .part.editor > .content .gettingStartedContainer .done-next-container { display: flex; padding: 16px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .button-link { +.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link { padding: 0; background: transparent; margin: 2px; @@ -773,20 +773,20 @@ max-width: 100%; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .done-next-container .button-link { +.monaco-workbench .part.editor > .content .gettingStartedContainer .done-next-container .button-link { display: flex; align-items: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .button-link.next { +.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link.next { margin-left: auto; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .button-link:hover { +.monaco-workbench .part.editor > .content .gettingStartedContainer .button-link:hover { background: transparent; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .openAWalkthrough>button, .monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .showOnStartup { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .openAWalkthrough > button, .monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .showOnStartup { text-align: center; display: flex; justify-content: center; @@ -794,7 +794,7 @@ gap: 8px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { color: inherit !important; height: 18px; width: 18px; @@ -805,45 +805,45 @@ } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox.codicon:not(.checked)::before { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox.codicon:not(.checked)::before { opacity: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.footer p { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .footer p { margin: 0; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer .index-list.start-container { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer .index-list.start-container { min-height: 156px; margin-bottom: 16px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideCategories>.gettingStartedCategoriesContainer>.footer>button { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideCategories > .gettingStartedCategoriesContainer > .footer > button { text-align: center; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .getting-started-category .codicon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .getting-started-category .codicon { top: 0px; } -.monaco-workbench .part.editor>.content .getting-started-category .codicon-star-full::before { +.monaco-workbench .part.editor > .content .getting-started-category .codicon-star-full::before { vertical-align: middle; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .hide-category-button { +.monaco-workbench .part.editor > .content .gettingStartedContainer .hide-category-button { visibility: hidden; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .getting-started-category:focus-within .hide-category-button, -.monaco-workbench .part.editor>.content .gettingStartedContainer .getting-started-category:hover .hide-category-button { +.monaco-workbench .part.editor > .content .gettingStartedContainer .getting-started-category:focus-within .hide-category-button, +.monaco-workbench .part.editor > .content .gettingStartedContainer .getting-started-category:hover .hide-category-button { visibility: visible; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description-container span { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description-container span { line-height: 1.3em; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description-container .monaco-button, .monaco-workbench .part.editor>.content .gettingStartedContainer .max-lines-3 { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description-container .monaco-button, .monaco-workbench .part.editor > .content .gettingStartedContainer .max-lines-3 { /* Supported everywhere: https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp#browser_compatibility */ -webkit-line-clamp: 3; display: -webkit-box; @@ -851,7 +851,7 @@ overflow: hidden; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description-container .monaco-button { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlideDetails .getting-started-step .step-description-container .monaco-button { height: 24px; width: fit-content; display: flex; @@ -860,16 +860,16 @@ min-width: max-content; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .hide-category-button { +.monaco-workbench .part.editor > .content .gettingStartedContainer .hide-category-button { padding: 3px; border-radius: 5px; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .hide-category-button::before { +.monaco-workbench .part.editor > .content .gettingStartedContainer .hide-category-button::before { vertical-align: unset; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .hide-category-button:hover { +.monaco-workbench .part.editor > .content .gettingStartedContainer .hide-category-button:hover { background-color: var(--vscode-toolbar-hoverBackground); } @@ -980,26 +980,26 @@ background-color: var(--vscode-welcomePage-progress-foreground); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .new-badge { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .new-badge { color: var(--vscode-activityBarBadge-foreground); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured .featured-icon { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .featured .featured-icon { color: var(--vscode-activityBarBadge-foreground); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-category .new-badge { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category .new-badge { background-color: var(--vscode-activityBarBadge-background); } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { background-color: var(--vscode-checkbox-background) !important; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { color: var(--vscode-checkbox-foreground) !important; } -.monaco-workbench .part.editor>.content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-checkbox { border-color: var(--vscode-checkbox-border) !important; } diff --git a/src/vs/workbench/contrib/welcomeWalkthrough/browser/media/walkThroughPart.css b/src/vs/workbench/contrib/welcomeWalkthrough/browser/media/walkThroughPart.css index 22cacd37226..ed362ff32c5 100644 --- a/src/vs/workbench/contrib/welcomeWalkthrough/browser/media/walkThroughPart.css +++ b/src/vs/workbench/contrib/welcomeWalkthrough/browser/media/walkThroughPart.css @@ -159,7 +159,7 @@ border-color: var(--vscode-contrastBorder); } -.monaco-workbench .part.editor>.content .walkThroughContent .monaco-editor-background, -.monaco-workbench .part.editor>.content .walkThroughContent .margin-view-overlays { +.monaco-workbench .part.editor > .content .walkThroughContent .monaco-editor-background, +.monaco-workbench .part.editor > .content .walkThroughContent .margin-view-overlays { background: var(--vscode-walkThrough-embeddedEditorBackground); } diff --git a/src/vs/workbench/services/suggest/browser/media/suggest.css b/src/vs/workbench/services/suggest/browser/media/suggest.css index 730b6fe66d5..366f7b7d6fd 100644 --- a/src/vs/workbench/services/suggest/browser/media/suggest.css +++ b/src/vs/workbench/services/suggest/browser/media/suggest.css @@ -69,8 +69,8 @@ margin-right: 0.3em; } -.monaco-workbench .workbench-suggest-widget.with-status-bar .monaco-list .monaco-list-row>.contents>.main>.right>.readMore, -.monaco-workbench .workbench-suggest-widget.with-status-bar .monaco-list .monaco-list-row.focused.string-label>.contents>.main>.right>.readMore { +.monaco-workbench .workbench-suggest-widget.with-status-bar .monaco-list .monaco-list-row > .contents > .main > .right > .readMore, +.monaco-workbench .workbench-suggest-widget.with-status-bar .monaco-list .monaco-list-row.focused.string-label > .contents > .main > .right > .readMore { display: none; } @@ -96,14 +96,14 @@ color: var(--vscode-editorSuggestWidget-selectedIconForeground); } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents { flex: 1; height: 100%; overflow: hidden; padding-left: 2px; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main { display: flex; overflow: hidden; text-overflow: ellipsis; @@ -111,12 +111,12 @@ justify-content: space-between; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left, -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left, +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right { display: flex; } -.workbench-suggest-widget .monaco-list .monaco-list-row:not(.focused)>.contents>.main .monaco-icon-label { +.workbench-suggest-widget .monaco-list .monaco-list-row:not(.focused) > .contents > .main .monaco-icon-label { color: var(--vscode-editorSuggestWidget-foreground); } @@ -124,11 +124,11 @@ font-weight: bold; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main .monaco-highlighted-label .highlight { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main .monaco-highlighted-label .highlight { color: var(--vscode-editorSuggestWidget-highlightForeground); } -.workbench-suggest-widget .monaco-list .monaco-list-row.focused>.contents>.main .monaco-highlighted-label .highlight { +.workbench-suggest-widget .monaco-list .monaco-list-row.focused > .contents > .main .monaco-highlighted-label .highlight { color: var(--vscode-editorSuggestWidget-focusHighlightForeground); } @@ -154,14 +154,14 @@ color: var(--vscode-editorSuggestWidget-selectedIconForeground); } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents { flex: 1; height: 100%; overflow: hidden; padding-left: 2px; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main { display: flex; overflow: hidden; text-overflow: ellipsis; @@ -169,12 +169,12 @@ justify-content: space-between; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left, -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left, +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right { display: flex; } -.workbench-suggest-widget .monaco-list .monaco-list-row:not(.focused)>.contents>.main .monaco-icon-label { +.workbench-suggest-widget .monaco-list .monaco-list-row:not(.focused) > .contents > .main .monaco-icon-label { color: var(--vscode-editorSuggestWidget-foreground); } @@ -182,11 +182,11 @@ font-weight: bold; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main .monaco-highlighted-label .highlight { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main .monaco-highlighted-label .highlight { color: var(--vscode-editorSuggestWidget-highlightForeground); } -.workbench-suggest-widget .monaco-list .monaco-list-row.focused>.contents>.main .monaco-highlighted-label .highlight { +.workbench-suggest-widget .monaco-list .monaco-list-row.focused > .contents > .main .monaco-highlighted-label .highlight { color: var(--vscode-editorSuggestWidget-focusHighlightForeground); } @@ -197,7 +197,7 @@ text-decoration: unset; } -.workbench-suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated>.monaco-icon-label-container>.monaco-icon-name-container { +.workbench-suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated > .monaco-icon-label-container > .monaco-icon-name-container { text-decoration: line-through; } @@ -239,17 +239,17 @@ } /** signature, qualifier, type/details opacity **/ -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label { opacity: 0.7; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.signature-label { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .signature-label { overflow: hidden; text-overflow: ellipsis; opacity: 0.6; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.qualifier-label { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .qualifier-label { margin-left: 12px; opacity: 0.4; font-size: 85%; @@ -261,7 +261,7 @@ /** Type Info and icon next to the label in the focused completion item **/ -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label { font-size: 85%; margin-left: 1.1em; overflow: hidden; @@ -269,59 +269,59 @@ white-space: nowrap; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label>.monaco-tokenized-source { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label > .monaco-tokenized-source { display: inline; } /** Details: if using CompletionItem#details, show on focus **/ -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.details-label { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .details-label { display: none; } -.workbench-suggest-widget:not(.shows-details) .monaco-list .monaco-list-row.focused>.contents>.main>.right>.details-label { +.workbench-suggest-widget:not(.shows-details) .monaco-list .monaco-list-row.focused > .contents > .main > .right > .details-label { display: inline; } /** Details: if using CompletionItemLabel#details, always show **/ -.workbench-suggest-widget .monaco-list .monaco-list-row:not(.string-label)>.contents>.main>.right>.details-label, -.workbench-suggest-widget.docs-side .monaco-list .monaco-list-row.focused:not(.string-label)>.contents>.main>.right>.details-label { +.workbench-suggest-widget .monaco-list .monaco-list-row:not(.string-label) > .contents > .main > .right > .details-label, +.workbench-suggest-widget.docs-side .monaco-list .monaco-list-row.focused:not(.string-label) > .contents > .main > .right > .details-label { display: inline; } /** Ellipsis on hover **/ -.workbench-suggest-widget:not(.docs-side) .monaco-list .monaco-list-row.focused:hover>.contents>.main>.right.can-expand-details>.details-label { +.workbench-suggest-widget:not(.docs-side) .monaco-list .monaco-list-row.focused:hover > .contents > .main > .right.can-expand-details > .details-label { width: calc(100% - 26px); } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left { flex-shrink: 1; flex-grow: 1; overflow: hidden; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.left>.monaco-icon-label { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .left > .monaco-icon-label { flex-shrink: 0; } -.workbench-suggest-widget .monaco-list .monaco-list-row:not(.string-label)>.contents>.main>.left>.monaco-icon-label { +.workbench-suggest-widget .monaco-list .monaco-list-row:not(.string-label) > .contents > .main > .left > .monaco-icon-label { max-width: 100%; } -.workbench-suggest-widget .monaco-list .monaco-list-row.string-label>.contents>.main>.left>.monaco-icon-label { +.workbench-suggest-widget .monaco-list .monaco-list-row.string-label > .contents > .main > .left > .monaco-icon-label { flex-shrink: 1; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right { overflow: hidden; flex-shrink: 4; max-width: 70%; } -.workbench-suggest-widget .monaco-list .monaco-list-row>.contents>.main>.right>.readMore { +.workbench-suggest-widget .monaco-list .monaco-list-row > .contents > .main > .right > .readMore { display: inline-block; position: absolute; right: 10px; diff --git a/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css b/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css index ea08aa254b2..f5de028325f 100644 --- a/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css +++ b/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css @@ -7,43 +7,43 @@ display: inherit; } -.monaco-workbench .pane>.pane-body>.profile-view-message-container { +.monaco-workbench .pane > .pane-body > .profile-view-message-container { display: flex; padding: 13px 20px 0px 20px; box-sizing: border-box; } -.monaco-workbench .pane>.pane-body>.profile-view-message-container p { +.monaco-workbench .pane > .pane-body > .profile-view-message-container p { margin-block-start: 0em; margin-block-end: 0em; } -.monaco-workbench .pane>.pane-body>.profile-view-message-container a { +.monaco-workbench .pane > .pane-body > .profile-view-message-container a { color: var(--vscode-textLink-foreground) } -.monaco-workbench .pane>.pane-body>.profile-view-message-container a:hover { +.monaco-workbench .pane > .pane-body > .profile-view-message-container a:hover { text-decoration: underline; color: var(--vscode-textLink-activeForeground) } -.monaco-workbench .pane>.pane-body>.profile-view-message-container a:active { +.monaco-workbench .pane > .pane-body > .profile-view-message-container a:active { color: var(--vscode-textLink-activeForeground) } -.monaco-workbench .pane>.pane-body>.profile-view-message-container.hide { +.monaco-workbench .pane > .pane-body > .profile-view-message-container.hide { display: none; } -.monaco-workbench .pane>.pane-body>.profile-view-buttons-container { +.monaco-workbench .pane > .pane-body > .profile-view-buttons-container { display: flex; flex-direction: column; padding: 13px 20px; box-sizing: border-box; } -.monaco-workbench .pane>.pane-body>.profile-view-buttons-container>.monaco-button, -.monaco-workbench .pane>.pane-body>.profile-view-buttons-container>.monaco-button-dropdown { +.monaco-workbench .pane > .pane-body > .profile-view-buttons-container > .monaco-button, +.monaco-workbench .pane > .pane-body > .profile-view-buttons-container > .monaco-button-dropdown { margin-block-start: 13px; margin-inline-start: 0px; margin-inline-end: 0px; @@ -52,11 +52,11 @@ margin-right: auto; } -.monaco-workbench .pane>.pane-body>.profile-view-buttons-container>.monaco-button-dropdown { +.monaco-workbench .pane > .pane-body > .profile-view-buttons-container > .monaco-button-dropdown { width: 100%; } -.monaco-workbench .pane>.pane-body>.profile-view-buttons-container>.monaco-button-dropdown>.monaco-dropdown-button { +.monaco-workbench .pane > .pane-body > .profile-view-buttons-container > .monaco-button-dropdown > .monaco-dropdown-button { display: flex; align-items: center; padding: 0 4px; From 7cd710eefe7a0a20f3f191a972ba5cc41b5a9e02 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Dec 2023 18:45:49 +0100 Subject: [PATCH 10/37] make sure `vscode.executeDocumentHighlights` return an array (#200062) re https://github.com/microsoft/vscode/issues/200056 --- .../browser/wordHighlighter.ts | 5 ++-- .../test/browser/extHostApiCommands.test.ts | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts index 525af0230a0..f7bd8e2eede 100644 --- a/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/browser/wordHighlighter.ts @@ -253,9 +253,10 @@ function computeOccurencesMultiModel(registry: LanguageFeatureRegistry { +registerModelAndPositionCommand('_executeDocumentHighlights', async (accessor, model, position) => { const languageFeaturesService = accessor.get(ILanguageFeaturesService); - return getOccurrencesAtPosition(languageFeaturesService.documentHighlightProvider, model, position, CancellationToken.None); + const map = await getOccurrencesAtPosition(languageFeaturesService.documentHighlightProvider, model, position, CancellationToken.None); + return map?.get(model.uri); }); class WordHighlighter { diff --git a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts index 35e7543d864..3a60e4c025b 100644 --- a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts +++ b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts @@ -681,6 +681,33 @@ suite('ExtHostLanguageFeatureCommands', function () { }); }); + // --- document highlights + + test('"vscode.executeDocumentHighlights" API has stopped returning DocumentHighlight[]#200056', async function () { + + + disposables.push(extHost.registerDocumentHighlightProvider(nullExtensionDescription, defaultSelector, { + provideDocumentHighlights() { + return [ + new types.DocumentHighlight(new types.Range(0, 17, 0, 25), types.DocumentHighlightKind.Read) + ]; + } + })); + + await rpcProtocol.sync(); + + return commands.executeCommand('vscode.executeDocumentHighlights', model.uri, new types.Position(0, 0)).then(values => { + assert.ok(Array.isArray(values)); + assert.strictEqual(values.length, 1); + const [first] = values; + assert.strictEqual(first.range.start.line, 0); + assert.strictEqual(first.range.start.character, 17); + assert.strictEqual(first.range.end.line, 0); + assert.strictEqual(first.range.end.character, 25); + }); + + }); + // --- outline test('Outline, back and forth', function () { From 455ca664b9dad6ad89b057cfa6e8e18062815971 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Dec 2023 18:56:59 +0100 Subject: [PATCH 11/37] working copy - enable file limits when resolving (#172129) (#200009) * working copy - enable file limits when resolving (#172129) * . --- src/vs/workbench/common/editor.ts | 4 ++- .../common/editor/resourceEditorInput.ts | 32 +++++++++++++++++-- .../common/editor/textResourceEditorInput.ts | 11 ++++--- .../files/browser/editors/fileEditorInput.ts | 30 ++--------------- .../mergeEditor/browser/mergeEditorInput.ts | 6 ++-- .../notebook/browser/notebookEditor.ts | 18 +++++++++-- .../contrib/notebook/common/notebookCommon.ts | 6 ++++ .../notebook/common/notebookEditorInput.ts | 16 ++++++---- .../notebook/common/notebookEditorModel.ts | 8 +++-- .../notebookEditorModelResolverService.ts | 5 +-- .../notebookEditorModelResolverServiceImpl.ts | 13 ++++---- .../performance/browser/perfviewEditor.ts | 7 ++-- .../textfile/common/textFileEditorModel.ts | 3 +- .../common/untitledTextEditorInput.ts | 6 ++-- .../common/storedFileWorkingCopy.ts | 13 ++++++-- .../common/storedFileWorkingCopyManager.ts | 3 +- .../parts/editor/resourceEditorInput.test.ts | 6 ++-- 17 files changed, 121 insertions(+), 66 deletions(-) diff --git a/src/vs/workbench/common/editor.ts b/src/vs/workbench/common/editor.ts index 2c0acaa442a..ee6a8e501c8 100644 --- a/src/vs/workbench/common/editor.ts +++ b/src/vs/workbench/common/editor.ts @@ -928,7 +928,7 @@ export interface IFileEditorInput extends EditorInput, IEncodingSupport, ILangua isResolved(): boolean; } -export interface IFileEditorInputOptions extends ITextEditorOptions { +export interface IFileLimitedEditorInputOptions extends IEditorOptions { /** * If provided, the size of the file will be checked against the limits @@ -937,6 +937,8 @@ export interface IFileEditorInputOptions extends ITextEditorOptions { readonly limits?: IFileReadLimits; } +export interface IFileEditorInputOptions extends ITextEditorOptions, IFileLimitedEditorInputOptions { } + export function createTooLargeFileError(group: IEditorGroup, input: EditorInput, options: IEditorOptions | undefined, message: string, preferencesService: IPreferencesService): Error { return createEditorOpenError(message, [ toAction({ diff --git a/src/vs/workbench/common/editor/resourceEditorInput.ts b/src/vs/workbench/common/editor/resourceEditorInput.ts index d1d5f8c5674..6f5af0deee3 100644 --- a/src/vs/workbench/common/editor/resourceEditorInput.ts +++ b/src/vs/workbench/common/editor/resourceEditorInput.ts @@ -3,14 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Verbosity, EditorInputWithPreferredResource, EditorInputCapabilities } from 'vs/workbench/common/editor'; +import { Verbosity, EditorInputWithPreferredResource, EditorInputCapabilities, IFileLimitedEditorInputOptions } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { URI } from 'vs/base/common/uri'; -import { IFileService } from 'vs/platform/files/common/files'; +import { ByteSize, IFileReadLimits, IFileService, getLargeFileConfirmationLimit } from 'vs/platform/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; import { dirname, isEqual } from 'vs/base/common/resources'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IMarkdownString } from 'vs/base/common/htmlContent'; +import { isConfigured } from 'vs/platform/configuration/common/configuration'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; /** * The base class for all editor inputs that open resources. @@ -43,7 +45,8 @@ export abstract class AbstractResourceEditorInput extends EditorInput implements preferredResource: URI | undefined, @ILabelService protected readonly labelService: ILabelService, @IFileService protected readonly fileService: IFileService, - @IFilesConfigurationService protected readonly filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService protected readonly filesConfigurationService: IFilesConfigurationService, + @ITextResourceConfigurationService protected readonly textResourceConfigurationService: ITextResourceConfigurationService ) { super(); @@ -179,4 +182,27 @@ export abstract class AbstractResourceEditorInput extends EditorInput implements override isReadonly(): boolean | IMarkdownString { return this.filesConfigurationService.isReadonly(this.resource); } + + protected ensureLimits(options?: IFileLimitedEditorInputOptions): IFileReadLimits | undefined { + if (options?.limits) { + return options.limits; // respect passed in limits if any + } + + // We want to determine the large file configuration based on the best defaults + // for the resource but also respecting user settings. We only apply user settings + // if explicitly configured by the user. Otherwise we pick the best limit for the + // resource scheme. + + const defaultSizeLimit = getLargeFileConfirmationLimit(this.resource); + let configuredSizeLimit: number | undefined = undefined; + + const configuredSizeLimitMb = this.textResourceConfigurationService.inspect(this.resource, null, 'workbench.editorLargeFileConfirmation'); + if (isConfigured(configuredSizeLimitMb)) { + configuredSizeLimit = configuredSizeLimitMb.value * ByteSize.MB; // normalize to MB + } + + return { + size: configuredSizeLimit ?? defaultSizeLimit + }; + } } diff --git a/src/vs/workbench/common/editor/textResourceEditorInput.ts b/src/vs/workbench/common/editor/textResourceEditorInput.ts index 02217560ffd..8416d2cc249 100644 --- a/src/vs/workbench/common/editor/textResourceEditorInput.ts +++ b/src/vs/workbench/common/editor/textResourceEditorInput.ts @@ -18,6 +18,7 @@ import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResource import { IReference } from 'vs/base/common/lifecycle'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; /** * The base class for all editor inputs that open in text editors. @@ -31,9 +32,10 @@ export abstract class AbstractTextResourceEditorInput extends AbstractResourceEd @ITextFileService protected readonly textFileService: ITextFileService, @ILabelService labelService: ILabelService, @IFileService fileService: IFileService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { - super(resource, preferredResource, labelService, fileService, filesConfigurationService); + super(resource, preferredResource, labelService, fileService, filesConfigurationService, textResourceConfigurationService); } override save(group: GroupIdentifier, options?: ITextFileSaveOptions): Promise { @@ -104,9 +106,10 @@ export class TextResourceEditorInput extends AbstractTextResourceEditorInput imp @IEditorService editorService: IEditorService, @IFileService fileService: IFileService, @ILabelService labelService: ILabelService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { - super(resource, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService); + super(resource, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService, textResourceConfigurationService); } override getName(): string { diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts index 3f4b1910cf4..dd25f4509bc 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts @@ -9,7 +9,7 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { AbstractTextResourceEditorInput } from 'vs/workbench/common/editor/textResourceEditorInput'; import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel'; -import { ByteSize, IFileReadLimits, IFileService, getLargeFileConfirmationLimit } from 'vs/platform/files/common/files'; +import { IFileService } from 'vs/platform/files/common/files'; import { ITextFileService, TextFileEditorModelState, TextFileResolveReason, TextFileOperationError, TextFileOperationResult, ITextFileEditorModel, EncodingMode } from 'vs/workbench/services/textfile/common/textfiles'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IReference, dispose, DisposableStore } from 'vs/base/common/lifecycle'; @@ -24,7 +24,6 @@ import { Schemas } from 'vs/base/common/network'; import { createTextBufferFactory } from 'vs/editor/common/model/textModel'; import { IPathService } from 'vs/workbench/services/path/common/pathService'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; -import { isConfigured } from 'vs/platform/configuration/common/configuration'; import { IMarkdownString } from 'vs/base/common/htmlContent'; const enum ForceOpenAs { @@ -99,9 +98,9 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, @IEditorService editorService: IEditorService, @IPathService private readonly pathService: IPathService, - @ITextResourceConfigurationService private readonly textResourceConfigurationService: ITextResourceConfigurationService + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { - super(resource, preferredResource, editorService, textFileService, labelService, fileService, filesConfigurationService); + super(resource, preferredResource, editorService, textFileService, labelService, fileService, filesConfigurationService, textResourceConfigurationService); this.model = this.textFileService.files.get(resource); @@ -396,29 +395,6 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements } } - private ensureLimits(options?: IFileEditorInputOptions): IFileReadLimits | undefined { - if (options?.limits) { - return options.limits; // respect passed in limits if any - } - - // We want to determine the large file configuration based on the best defaults - // for the resource but also respecting user settings. We only apply user settings - // if explicitly configured by the user. Otherwise we pick the best limit for the - // resource scheme. - - const defaultSizeLimit = getLargeFileConfirmationLimit(this.resource); - let configuredSizeLimit: number | undefined = undefined; - - const configuredSizeLimitMb = this.textResourceConfigurationService.inspect(this.resource, null, 'workbench.editorLargeFileConfirmation'); - if (isConfigured(configuredSizeLimitMb)) { - configuredSizeLimit = configuredSizeLimitMb.value * ByteSize.MB; // normalize to MB - } - - return { - size: configuredSizeLimit ?? defaultSizeLimit - }; - } - private async doResolveAsBinary(): Promise { const model = this.instantiationService.createInstance(BinaryEditorModel, this.preferredResource, this.getName()); await model.resolve(); diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts index e9f69bfa0ad..3304f0b90b7 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts @@ -8,6 +8,7 @@ import { autorun } from 'vs/base/common/observable'; import { isEqual } from 'vs/base/common/resources'; import { isDefined } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; import { localize } from 'vs/nls'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IFileService } from 'vs/platform/files/common/files'; @@ -60,9 +61,10 @@ export class MergeEditorInput extends AbstractTextResourceEditorInput implements @ILabelService labelService: ILabelService, @IFileService fileService: IFileService, @IConfigurationService private readonly configurationService: IConfigurationService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { - super(result, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService); + super(result, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService, textResourceConfigurationService); } override dispose(): void { diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts index 7bcd5a348d9..2370b8a2972 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditor.ts @@ -17,14 +17,14 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/tex import { localize } from 'vs/nls'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; -import { IFileService } from 'vs/platform/files/common/files'; +import { ByteSize, FileOperationError, FileOperationResult, IFileService, TooLargeFileOperationError } from 'vs/platform/files/common/files'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { Selection } from 'vs/editor/common/core/selection'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'; -import { DEFAULT_EDITOR_ASSOCIATION, EditorPaneSelectionChangeReason, EditorPaneSelectionCompareResult, EditorResourceAccessor, IEditorMemento, IEditorOpenContext, IEditorPaneSelection, IEditorPaneSelectionChangeEvent, createEditorOpenError, isEditorOpenError } from 'vs/workbench/common/editor'; +import { DEFAULT_EDITOR_ASSOCIATION, EditorPaneSelectionChangeReason, EditorPaneSelectionCompareResult, EditorResourceAccessor, IEditorMemento, IEditorOpenContext, IEditorPaneSelection, IEditorPaneSelectionChangeEvent, createEditorOpenError, createTooLargeFileError, isEditorOpenError } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/controller/coreActions'; import { INotebookEditorOptions, INotebookEditorPane, INotebookEditorViewState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; @@ -46,6 +46,7 @@ import { IWorkingCopyBackupService } from 'vs/workbench/services/workingCopy/com import { streamToBuffer } from 'vs/base/common/buffer'; import { ILogService } from 'vs/platform/log/common/log'; import { INotebookEditorWorkerService } from 'vs/workbench/contrib/notebook/common/services/notebookWorkerService'; +import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; const NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'NotebookEditorViewState'; @@ -90,6 +91,7 @@ export class NotebookEditor extends EditorPane implements INotebookEditorPane { @IWorkingCopyBackupService private readonly _workingCopyBackupService: IWorkingCopyBackupService, @ILogService private readonly logService: ILogService, @INotebookEditorWorkerService private readonly _notebookEditorWorkerService: INotebookEditorWorkerService, + @IPreferencesService private readonly _preferencesService: IPreferencesService, ) { super(NotebookEditor.ID, telemetryService, themeService, storageService); this._editorMemento = this.getEditorMemento(_editorGroupService, configurationService, NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY); @@ -327,6 +329,18 @@ export class NotebookEditor extends EditorPane implements INotebookEditorPane { throw e; } + // Handle case where a file is too large to open without confirmation + if ((e).fileOperationResult === FileOperationResult.FILE_TOO_LARGE && this.group) { + let message: string; + if (e instanceof TooLargeFileOperationError) { + message = localize('notebookTooLargeForHeapErrorWithSize', "The notebook is not displayed in the notebook editor because it is very large ({0}).", ByteSize.formatSize(e.size)); + } else { + message = localize('notebookTooLargeForHeapErrorWithoutSize', "The notebook is not displayed in the notebook editor because it is very large."); + } + + throw createTooLargeFileError(this.group, input, options, message, this._preferencesService); + } + const error = createEditorOpenError(e instanceof Error ? e : new Error((e ? e.message : '')), [ toAction({ id: 'workbench.notebook.action.openInTextEditor', label: localize('notebookOpenInTextEditor', "Open in Text Editor"), run: async () => { diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 99230c87970..e88290fa063 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -30,6 +30,7 @@ import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/no import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange'; import { IWorkingCopyBackupMeta, IWorkingCopySaveEvent } from 'vs/workbench/services/workingCopy/common/workingCopy'; import { IMarkdownString } from 'vs/base/common/htmlContent'; +import { IFileReadLimits } from 'vs/platform/files/common/files'; export const NOTEBOOK_EDITOR_ID = 'workbench.editor.notebook'; export const NOTEBOOK_DIFF_EDITOR_ID = 'workbench.editor.notebookTextDiffEditor'; @@ -787,6 +788,11 @@ export interface INotebookLoadOptions { * Go to disk bypassing any cache of the model if any. */ forceReadFromFile?: boolean; + /** + * If provided, the size of the file will be checked against the limits + * and an error will be thrown if any limit is exceeded. + */ + readonly limits?: IFileReadLimits; } export interface IResolvedNotebookEditorModel extends INotebookEditorModel { diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts index 1d6bba54100..8a0f53e0b8c 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as glob from 'vs/base/common/glob'; -import { GroupIdentifier, ISaveOptions, IMoveResult, IRevertOptions, EditorInputCapabilities, Verbosity, IUntypedEditorInput } from 'vs/workbench/common/editor'; +import { GroupIdentifier, ISaveOptions, IMoveResult, IRevertOptions, EditorInputCapabilities, Verbosity, IUntypedEditorInput, IFileLimitedEditorInputOptions } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService'; import { URI } from 'vs/base/common/uri'; @@ -18,7 +18,7 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { Schemas } from 'vs/base/common/network'; import { IFileService } from 'vs/platform/files/common/files'; import { AbstractResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput'; -import { IEditorOptions, IResourceEditorInput } from 'vs/platform/editor/common/editor'; +import { IResourceEditorInput } from 'vs/platform/editor/common/editor'; import { onUnexpectedError } from 'vs/base/common/errors'; import { VSBuffer } from 'vs/base/common/buffer'; import { IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy'; @@ -29,6 +29,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { localize } from 'vs/nls'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IMarkdownString } from 'vs/base/common/htmlContent'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; export interface NotebookEditorInputOptions { startDirty?: boolean; @@ -79,9 +80,10 @@ export class NotebookEditorInput extends AbstractResourceEditorInput { @IFileService fileService: IFileService, @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, @IExtensionService extensionService: IExtensionService, - @IEditorService editorService: IEditorService + @IEditorService editorService: IEditorService, + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { - super(resource, preferredResource, labelService, fileService, filesConfigurationService); + super(resource, preferredResource, labelService, fileService, filesConfigurationService, textResourceConfigurationService); this._defaultDirtyState = !!options.startDirty; // Automatically resolve this input when the "wanted" model comes to life via @@ -281,7 +283,7 @@ export class NotebookEditorInput extends AbstractResourceEditorInput { } } - override async resolve(_options?: IEditorOptions, perf?: NotebookPerfMarks): Promise { + override async resolve(_options?: IFileLimitedEditorInputOptions, perf?: NotebookPerfMarks): Promise { if (!await this._notebookService.canResolve(this.viewType)) { return null; } @@ -293,7 +295,7 @@ export class NotebookEditorInput extends AbstractResourceEditorInput { this._sideLoadedListener.dispose(); if (!this._editorModelReference) { - const ref = await this._notebookModelResolverService.resolve(this.resource, this.viewType); + const ref = await this._notebookModelResolverService.resolve(this.resource, this.viewType, this.ensureLimits(_options)); if (this._editorModelReference) { // Re-entrant, double resolve happened. Dispose the addition references and proceed // with the truth. @@ -313,7 +315,7 @@ export class NotebookEditorInput extends AbstractResourceEditorInput { this._onDidChangeDirty.fire(); } } else { - this._editorModelReference.object.load(); + this._editorModelReference.object.load({ limits: this.ensureLimits(_options) }); } if (this.options._backupId) { diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts index cb01185b511..4e7864c0667 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModel.ts @@ -136,7 +136,10 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE } this._workingCopy.onDidRevert(() => this._onDidRevertUntitled.fire()); } else { - this._workingCopy = await this._workingCopyManager.resolve(this.resource, options?.forceReadFromFile ? { reload: { async: false, force: true } } : undefined); + this._workingCopy = await this._workingCopyManager.resolve(this.resource, { + limits: options?.limits, + reload: options?.forceReadFromFile ? { async: false, force: true } : undefined + }); this._workingCopyListeners.add(this._workingCopy.onDidSave(e => this._onDidSave.fire(e))); this._workingCopyListeners.add(this._workingCopy.onDidChangeOrphaned(() => this._onDidChangeOrphaned.fire())); this._workingCopyListeners.add(this._workingCopy.onDidChangeReadonly(() => this._onDidChangeReadonly.fire())); @@ -152,7 +155,8 @@ export class SimpleNotebookEditorModel extends EditorModel implements INotebookE reload: { async: !options?.forceReadFromFile, force: options?.forceReadFromFile - } + }, + limits: options?.limits }); } diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverService.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverService.ts index e2d2a6c4fe4..3eff1eb5060 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverService.ts @@ -8,6 +8,7 @@ import { URI } from 'vs/base/common/uri'; import { IResolvedNotebookEditorModel } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { IReference } from 'vs/base/common/lifecycle'; import { Event, IWaitUntil } from 'vs/base/common/event'; +import { IFileReadLimits } from 'vs/platform/files/common/files'; export const INotebookEditorModelResolverService = createDecorator('INotebookModelResolverService'); @@ -49,6 +50,6 @@ export interface INotebookEditorModelResolverService { isDirty(resource: URI): boolean; - resolve(resource: URI, viewType?: string): Promise>; - resolve(resource: IUntitledNotebookResource, viewType: string): Promise>; + resolve(resource: URI, viewType?: string, limits?: IFileReadLimits): Promise>; + resolve(resource: IUntitledNotebookResource, viewType: string, limits?: IFileReadLimits): Promise>; } diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts index 9da04357e1b..bbc69d31aa2 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorModelResolverServiceImpl.ts @@ -21,6 +21,7 @@ import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/noteb import { assertIsDefined } from 'vs/base/common/types'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IFileReadLimits } from 'vs/platform/files/common/files'; class NotebookModelReferenceCollection extends ReferenceCollection> { @@ -58,7 +59,7 @@ class NotebookModelReferenceCollection extends ReferenceCollection { + protected async createReferencedObject(key: string, viewType: string, hasAssociatedFilePath: boolean, limits?: IFileReadLimits): Promise { // Untrack as being disposed this.modelsToDispose.delete(key); @@ -77,7 +78,7 @@ class NotebookModelReferenceCollection extends ReferenceCollection>; - async resolve(resource: IUntitledNotebookResource, viewType: string): Promise>; - async resolve(arg0: URI | IUntitledNotebookResource, viewType?: string): Promise> { + async resolve(resource: URI, viewType?: string, limits?: IFileReadLimits): Promise>; + async resolve(resource: IUntitledNotebookResource, viewType: string, limits?: IFileReadLimits): Promise>; + async resolve(arg0: URI | IUntitledNotebookResource, viewType?: string, limits?: IFileReadLimits): Promise> { let resource: URI; let hasAssociatedFilePath = false; if (URI.isUri(arg0)) { @@ -235,7 +236,7 @@ export class NotebookModelResolverServiceImpl implements INotebookEditorModelRes } } - const reference = this._data.acquire(resource.toString(), viewType, hasAssociatedFilePath); + const reference = this._data.acquire(resource.toString(), viewType, hasAssociatedFilePath, limits); try { const model = await reference.object; return { diff --git a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts index e953502efac..db3605eb6bd 100644 --- a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts @@ -27,6 +27,7 @@ import { isWeb } from 'vs/base/common/platform'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import * as perf from 'vs/base/common/performance'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; export class PerfviewContrib { @@ -59,7 +60,8 @@ export class PerfviewInput extends TextResourceEditorInput { @IEditorService editorService: IEditorService, @IFileService fileService: IFileService, @ILabelService labelService: ILabelService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { super( PerfviewInput.Uri, @@ -72,7 +74,8 @@ export class PerfviewInput extends TextResourceEditorInput { editorService, fileService, labelService, - filesConfigurationService + filesConfigurationService, + textResourceConfigurationService ); } } diff --git a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts index 4ae7f6692c6..e546ab6c566 100644 --- a/src/vs/workbench/services/textfile/common/textFileEditorModel.ts +++ b/src/vs/workbench/services/textfile/common/textFileEditorModel.ts @@ -443,7 +443,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil try { const content = await this.textFileService.readStream(this.resource, { acceptTextOnly: !allowBinary, - etag, encoding: this.preferredEncoding, + etag, + encoding: this.preferredEncoding, limits: options?.limits }); diff --git a/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts b/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts index 5780d63cce9..766081132c1 100644 --- a/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts +++ b/src/vs/workbench/services/untitled/common/untitledTextEditorInput.ts @@ -19,6 +19,7 @@ import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { dispose, IReference } from 'vs/base/common/lifecycle'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; /** * An editor input to be used for untitled text buffers. @@ -47,9 +48,10 @@ export class UntitledTextEditorInput extends AbstractTextResourceEditorInput imp @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @IPathService private readonly pathService: IPathService, @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, - @ITextModelService private readonly textModelService: ITextModelService + @ITextModelService private readonly textModelService: ITextModelService, + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { - super(model.resource, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService); + super(model.resource, undefined, editorService, textFileService, labelService, fileService, filesConfigurationService, textResourceConfigurationService); this.registerModelListeners(model); } diff --git a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts index 7a00e3208d8..aee59bce62b 100644 --- a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts +++ b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopy.ts @@ -7,7 +7,7 @@ import { localize } from 'vs/nls'; import { URI } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; -import { ETAG_DISABLED, FileOperationError, FileOperationResult, IFileService, IFileStatWithMetadata, IFileStreamContent, IWriteFileOptions, NotModifiedSinceFileOperationError } from 'vs/platform/files/common/files'; +import { ETAG_DISABLED, FileOperationError, FileOperationResult, IFileReadLimits, IFileService, IFileStatWithMetadata, IFileStreamContent, IWriteFileOptions, NotModifiedSinceFileOperationError } from 'vs/platform/files/common/files'; import { ISaveOptions, IRevertOptions, SaveReason } from 'vs/workbench/common/editor'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IWorkingCopyBackup, IWorkingCopyBackupMeta, IWorkingCopySaveEvent, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopy'; @@ -262,6 +262,12 @@ export interface IStoredFileWorkingCopyResolveOptions { * Go to disk bypassing any cache of the stored file working copy if any. */ readonly forceReadFromFile?: boolean; + + /** + * If provided, the size of the file will be checked against the limits + * and an error will be thrown if any limit is exceeded. + */ + readonly limits?: IFileReadLimits; } /** @@ -571,7 +577,10 @@ export class StoredFileWorkingCopy extend // Resolve Content try { - const content = await this.fileService.readFileStream(this.resource, { etag }); + const content = await this.fileService.readFileStream(this.resource, { + etag, + limits: options?.limits + }); // Clear orphaned state when resolving was successful this.setOrphaned(false); diff --git a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts index cfdce4134e3..f76fdd404c7 100644 --- a/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts +++ b/src/vs/workbench/services/workingCopy/common/storedFileWorkingCopyManager.ts @@ -475,7 +475,8 @@ export class StoredFileWorkingCopyManager const resolveOptions: IStoredFileWorkingCopyResolveOptions = { contents: options?.contents, - forceReadFromFile: options?.reload?.force + forceReadFromFile: options?.reload?.force, + limits: options?.limits }; // Working copy exists diff --git a/src/vs/workbench/test/browser/parts/editor/resourceEditorInput.test.ts b/src/vs/workbench/test/browser/parts/editor/resourceEditorInput.test.ts index f44f395fac6..7481879807d 100644 --- a/src/vs/workbench/test/browser/parts/editor/resourceEditorInput.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/resourceEditorInput.test.ts @@ -14,6 +14,7 @@ import { EditorInputCapabilities, Verbosity } from 'vs/workbench/common/editor'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; +import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; suite('ResourceEditorInput', () => { @@ -28,9 +29,10 @@ suite('ResourceEditorInput', () => { resource: URI, @ILabelService labelService: ILabelService, @IFileService fileService: IFileService, - @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService + @IFilesConfigurationService filesConfigurationService: IFilesConfigurationService, + @ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService ) { - super(resource, resource, labelService, fileService, filesConfigurationService); + super(resource, resource, labelService, fileService, filesConfigurationService, textResourceConfigurationService); } } From f746843c726509a7c722962a1a5c0915ad8141b5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 5 Dec 2023 18:59:17 +0100 Subject: [PATCH 12/37] update diff when document changes but don't auto-accept change regions (#200061) https://github.com/microsoft/vscode-copilot/issues/3206 --- .../contrib/inlineChat/browser/inlineChatStrategies.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index e352642e2d6..90d658b07d0 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -900,6 +900,10 @@ export class LiveStrategy3 extends EditModeStrategy { } : undefined; + this._sessionStore.add(this._session.textModelN.onDidChangeContent(e => { + this._showDiff(true, true); + })); + const zoneLineNumber = this._zone.position!.lineNumber; const myDistance = zoneLineNumber <= modifiedRange.startLineNumber ? modifiedRange.startLineNumber - zoneLineNumber From 8407e97b5b33b137fc98b9314661263ce01b102d Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 5 Dec 2023 18:15:31 +0100 Subject: [PATCH 13/37] Fixes #193640 --- src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts index 5817e88059f..3fd6e543a61 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditorWidget.ts @@ -483,13 +483,13 @@ export class DiffEditorWidget extends DelegatingEditor implements IDiffEditor { return; } - const model = this._diffModel.get()?.model; - if (!model) { return; } + const model = this._diffModel.get(); + if (!model || !model.isDiffUpToDate.get()) { return; } this._editors.modified.executeEdits('diffEditor', [ { range: diff.modified.toExclusiveRange(), - text: model.original.getValueInRange(diff.original.toExclusiveRange()) + text: model.model.original.getValueInRange(diff.original.toExclusiveRange()) } ]); } From 42720590a9876b9ffa44c4999848adc084159695 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 5 Dec 2023 12:32:58 -0600 Subject: [PATCH 14/37] Fix hover showing when navigating between ActionBar sections --- src/vs/base/browser/ui/actionbar/actionbar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index 562ef1efa5f..f72a8bbd9b6 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -201,7 +201,7 @@ export class ActionBar extends Disposable implements IActionRunner { } // Recompute focused item - else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab)) { + else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab) || event.equals(KeyCode.UpArrow) || event.equals(KeyCode.DownArrow)) { this.updateFocusedItem(); } })); From d70a46b6bd65aade0248f900a6e67a85f1c2cde2 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Tue, 5 Dec 2023 11:01:33 -0800 Subject: [PATCH 15/37] chore: update grooming notebook labels (#200070) --- .vscode/notebooks/grooming.github-issues | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.vscode/notebooks/grooming.github-issues b/.vscode/notebooks/grooming.github-issues index 2d4ca60063d..cb32618ede6 100644 --- a/.vscode/notebooks/grooming.github-issues +++ b/.vscode/notebooks/grooming.github-issues @@ -7,46 +7,46 @@ { "kind": 2, "language": "github-issues", - "value": "// list of repos we work in\n$repos=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n" + "value": "// list of repos we work in\r\n$repos=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\r\n" }, { "kind": 1, "language": "markdown", - "value": "#### Missing Type label\n" + "value": "#### Missing Type label\r\n" }, { "kind": 2, "language": "github-issues", - "value": "$repos assignee:@me is:open type:issue -label:bug -label:\"info-needed\" -label:feature-request -label:under-discussion -label:debt -label:plan-item -label:upstream -label:polish -label:testplan-item -label:error-telemetry -label:engineering -label:endgame-plan\n" + "value": "$repos assignee:@me is:open type:issue -label:bug -label:\"info-needed\" -label:feature-request -label:under-discussion -label:debt -label:plan-item -label:upstream -label:polish -label:testplan-item -label:error-telemetry -label:engineering -label:endgame-plan\r\n" }, { "kind": 1, "language": "markdown", - "value": "#### Missing Area Label\n\nFeature area labels are light or strong blue (`1d76db` or `c5def5`) and they denote a specific feature or feature area, like `editor-clipboard` or `file-explorer`\n" + "value": "#### Missing Area Label\r\n\r\nFeature area labels are light or strong blue (`1d76db` or `c5def5`) and they denote a specific feature or feature area, like `editor-clipboard` or `file-explorer`\r\n" }, { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode assignee:@me is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:cloud-changes -label:code-lens -label:command-center -label:comments -label:config -label:containers -label:context-keys -label:continue-working-on -label:css-less-scss -label:custom-editors -label:debug -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet -label:emmet-parse -label:error-list -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:html -label:icon-brand -label:icons-product -label:image-preview -label:inlay-hints -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:issue-bot -label:issue-reporter -label:javascript -label:json -label:keybindings -label:keybindings-editor -label:keybindings-json -label:keyboard-layout -label:L10N -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:native-file-dialog -label:network -label:notebook -label:notebook-api -label:notebook-builtin-renderers -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-commenting -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-math -label:notebook-minimap -label:notebook-multiselect -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-rendering -label:notebook-serialization -label:notebook-serverless-web -label:notebook-statusbar -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-tabs -label:terminal-winpty -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:inline-chat -label:panel-chat -label:audio-cue -label:tasks -label:error-list -label:winget\n" + "value": "repo:microsoft/vscode assignee:@me is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:cloud-changes -label:code-lens -label:command-center -label:comments -label:config -label:containers -label:context-keys -label:continue-working-on -label:css-less-scss -label:custom-editors -label:debug -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-widgets -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet -label:emmet-parse -label:error-list -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:html -label:icon-brand -label:icons-product -label:image-preview -label:inlay-hints -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:issue-bot -label:issue-reporter -label:javascript -label:json -label:keybindings -label:keybindings-editor -label:keyboard-layout -label:L10N -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:native-file-dialog -label:network -label:notebook -label:notebook-api -label:notebook-builtin-renderers -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-commenting -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-math -label:notebook-minimap -label:notebook-multiselect -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-rendering -label:notebook-serialization -label:notebook-serverless-web -label:notebook-statusbar -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-tabs -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:inline-chat -label:panel-chat -label:audio-cue -label:tasks -label:error-list -label:winget\r\n" }, { "kind": 1, "language": "markdown", - "value": "### Missing Milestone\n" + "value": "### Missing Milestone\r\n" }, { "kind": 2, "language": "github-issues", - "value": "$repos assignee:@me is:open type:issue no:milestone -label:info-needed -label:triage-needed\n" + "value": "$repos assignee:@me is:open type:issue no:milestone -label:info-needed -label:triage-needed\r\n" }, { "kind": 1, "language": "markdown", - "value": "#### Not Actionable\n" + "value": "#### Not Actionable\r\n" }, { "kind": 2, "language": "github-issues", - "value": "$repos assignee:@me is:open label:\"info-needed\"\n" + "value": "$repos assignee:@me is:open label:\"info-needed\"\r\n" } ] \ No newline at end of file From 58a122e39b46daeff1efd7be69105b18553b0e97 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 5 Dec 2023 20:19:56 +0100 Subject: [PATCH 16/37] Fixes https://github.com/microsoft/monaco-editor/issues/2556 --- .../diffEditor/diffEditor.contribution.ts | 11 --------- .../standalone/browser/standalone-tokens.css | 23 +++++++++++-------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts b/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts index 986237029eb..554c842d24d 100644 --- a/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts +++ b/src/vs/editor/browser/widget/diffEditor/diffEditor.contribution.ts @@ -280,17 +280,6 @@ export class AccessibleDiffViewerPrev extends Action2 { export function findFocusedDiffEditor(accessor: ServicesAccessor): IDiffEditor | null { const codeEditorService = accessor.get(ICodeEditorService); const diffEditors = codeEditorService.listDiffEditors(); - const activeCodeEditor = codeEditorService.getFocusedCodeEditor() ?? codeEditorService.getActiveCodeEditor(); - if (!activeCodeEditor) { - return null; - } - - for (let i = 0, len = diffEditors.length; i < len; i++) { - const diffEditor = diffEditors[i]; - if (diffEditor.getModifiedEditor().getId() === activeCodeEditor.getId() || diffEditor.getOriginalEditor().getId() === activeCodeEditor.getId()) { - return diffEditor; - } - } const activeElement = getActiveElement(); if (activeElement) { diff --git a/src/vs/editor/standalone/browser/standalone-tokens.css b/src/vs/editor/standalone/browser/standalone-tokens.css index 0df4a9bac81..1fc85078f9e 100644 --- a/src/vs/editor/standalone/browser/standalone-tokens.css +++ b/src/vs/editor/standalone/browser/standalone-tokens.css @@ -37,14 +37,19 @@ clip-path: inset(50%); } -/*.monaco-editor.vs [tabindex="0"]:focus { - outline: 1px solid rgba(0, 122, 204, 0.4); +.monaco-editor, .monaco-diff-editor .synthetic-focus, +.monaco-editor, .monaco-diff-editor [tabindex="0"]:focus, +.monaco-editor, .monaco-diff-editor [tabindex="-1"]:focus, +.monaco-editor, .monaco-diff-editor button:focus, +.monaco-editor, .monaco-diff-editor input[type=button]:focus, +.monaco-editor, .monaco-diff-editor input[type=checkbox]:focus, +.monaco-editor, .monaco-diff-editor input[type=search]:focus, +.monaco-editor, .monaco-diff-editor input[type=text]:focus, +.monaco-editor, .monaco-diff-editor select:focus, +.monaco-editor, .monaco-diff-editor textarea:focus { + outline-width: 1px; + outline-style: solid; outline-offset: -1px; - opacity: 1 !important; + outline-color: var(--vscode-focusBorder); + opacity: 1 } - -.monaco-editor.vs-dark [tabindex="0"]:focus { - outline: 1px solid rgba(14, 99, 156, 0.6); - outline-offset: -1px; - opacity: 1 !important; -}*/ From f055b9b8b282072f1120fb24a622c7f20c5946d2 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:52:29 -0800 Subject: [PATCH 17/37] Respect early returns from pre-existing bash debug traps Fixes #179483 --- .../contrib/terminal/browser/media/shellIntegration-bash.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh index 50ea1e39a52..b64082777be 100755 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-bash.sh @@ -256,8 +256,8 @@ else __vsc_preexec_all() { if [ "$__vsc_in_command_execution" = "0" ]; then __vsc_in_command_execution="1" - builtin eval "${__vsc_dbg_trap}" __vsc_preexec + builtin eval "${__vsc_dbg_trap}" fi } trap '__vsc_preexec_all "$_"' DEBUG From cc62bd1ddd500de9b19000aa263f2eaf1d9fb70e Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 5 Dec 2023 12:38:10 -0800 Subject: [PATCH 18/37] cli: allow reading exec server token from env variable (#200079) --- cli/src/commands/args.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index 7863635ae99..a69d021cab8 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -223,7 +223,7 @@ pub struct CommandShellArgs { #[clap(long, num_args = 0..=1, default_missing_value = "0")] pub on_port: Option, /// Require the given token string to be given in the handshake. - #[clap(long)] + #[clap(long, env = "VSCODE_CLI_REQUIRE_TOKEN")] pub require_token: Option, /// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists #[clap(long, hide = true)] From 4a7480c147b9fcdfde978263d39c5e19d36c07aa Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 5 Dec 2023 15:10:00 -0600 Subject: [PATCH 19/37] update focus on left/right arrow --- src/vs/base/browser/ui/actionbar/actionbar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index f72a8bbd9b6..1db13db8b63 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -201,7 +201,7 @@ export class ActionBar extends Disposable implements IActionRunner { } // Recompute focused item - else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab) || event.equals(KeyCode.UpArrow) || event.equals(KeyCode.DownArrow)) { + else if (event.equals(KeyCode.Tab) || event.equals(KeyMod.Shift | KeyCode.Tab) || event.equals(KeyCode.UpArrow) || event.equals(KeyCode.DownArrow) || event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow)) { this.updateFocusedItem(); } })); From 703e21214e1c08036655718733a2250615c32312 Mon Sep 17 00:00:00 2001 From: netcon Date: Wed, 6 Dec 2023 05:21:18 +0800 Subject: [PATCH 20/37] fix: `workbench.editorAssociations` not work in workbench configurationDefaults (#194087) --- .../services/editor/browser/editorResolverService.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/services/editor/browser/editorResolverService.ts b/src/vs/workbench/services/editor/browser/editorResolverService.ts index 6e3c55e4cc6..91d1b7f6da9 100644 --- a/src/vs/workbench/services/editor/browser/editorResolverService.ts +++ b/src/vs/workbench/services/editor/browser/editorResolverService.ts @@ -276,11 +276,12 @@ export class EditorResolverService extends Disposable implements IEditorResolver getAllUserAssociations(): EditorAssociations { const inspectedEditorAssociations = this.configurationService.inspect<{ [fileNamePattern: string]: string }>(editorsAssociationsSettingId) || {}; + const defaultAssociations = inspectedEditorAssociations.defaultValue ?? {}; const workspaceAssociations = inspectedEditorAssociations.workspaceValue ?? {}; const userAssociations = inspectedEditorAssociations.userValue ?? {}; const rawAssociations: { [fileNamePattern: string]: string } = { ...workspaceAssociations }; - // We want to apply the user associations on top of the workspace associations but ignore duplicate keys. - for (const [key, value] of Object.entries(userAssociations)) { + // We want to apply the default associations and user associations on top of the workspace associations but ignore duplicate keys. + for (const [key, value] of Object.entries({ ...defaultAssociations, ...userAssociations })) { if (rawAssociations[key] === undefined) { rawAssociations[key] = value; } From 0d42a76e2fbbf04ab6725d68ea14fd23618fa38b Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 5 Dec 2023 14:05:26 -0800 Subject: [PATCH 21/37] debug: fix call resolveDebugConfigurationWithSubstitutedVariables with redirected type (#200080) * cli: allow reading exec server token from env variable * debug: fix call resolveDebugConfigurationWithSubstitutedVariables with redirected type Fixes #188979 --- src/vs/workbench/contrib/debug/browser/debugService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugService.ts b/src/vs/workbench/contrib/debug/browser/debugService.ts index a0e2bd56df4..9f1dad419b3 100644 --- a/src/vs/workbench/contrib/debug/browser/debugService.ts +++ b/src/vs/workbench/contrib/debug/browser/debugService.ts @@ -493,7 +493,7 @@ export class DebugService implements IDebugService { return false; } - const cfg = await this.configurationManager.resolveDebugConfigurationWithSubstitutedVariables(launch && launch.workspace ? launch.workspace.uri : undefined, type, resolvedConfig, initCancellationToken.token); + const cfg = await this.configurationManager.resolveDebugConfigurationWithSubstitutedVariables(launch && launch.workspace ? launch.workspace.uri : undefined, resolvedConfig.type, resolvedConfig, initCancellationToken.token); if (!cfg) { if (launch && type && cfg === null && !initCancellationToken.token.isCancellationRequested) { // show launch.json only for "config" being "null". await launch.openConfigFile({ preserveFocus: true, type }, initCancellationToken.token); From 56fda3234c206777d79629d2ea649281f6bf2d3f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 5 Dec 2023 23:13:44 +0100 Subject: [PATCH 22/37] Windows: "Reopen" after crash does not work with 1 window opened (fix #199960) (#200075) --- .../windows/electron-main/windowImpl.ts | 62 ++++++++++--------- .../electron-main/windowsMainService.ts | 11 +++- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/vs/platform/windows/electron-main/windowImpl.ts b/src/vs/platform/windows/electron-main/windowImpl.ts index b68fb6ebef1..36f9a65833f 100644 --- a/src/vs/platform/windows/electron-main/windowImpl.ts +++ b/src/vs/platform/windows/electron-main/windowImpl.ts @@ -839,7 +839,7 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { private async destroyWindow(reopen: boolean, skipRestoreEditors: boolean): Promise { const workspace = this._config?.workspace; - // check to discard editor state first + // check to discard editor state first if (skipRestoreEditors && workspace) { try { const workspaceStorage = this.storageMainService.workspaceStorage(workspace); @@ -854,37 +854,41 @@ export class CodeWindow extends BaseWindow implements ICodeWindow { // 'close' event will not be fired on destroy(), so signal crash via explicit event this._onDidDestroy.fire(); - // make sure to destroy the window as its renderer process is gone - this._win?.destroy(); + try { + // ask the windows service to open a new fresh window if specified + if (reopen && this._config) { - // ask the windows service to open a new fresh window if specified - if (reopen && this._config) { + // We have to reconstruct a openable from the current workspace + let uriToOpen: IWorkspaceToOpen | IFolderToOpen | undefined = undefined; + let forceEmpty = undefined; + if (isSingleFolderWorkspaceIdentifier(workspace)) { + uriToOpen = { folderUri: workspace.uri }; + } else if (isWorkspaceIdentifier(workspace)) { + uriToOpen = { workspaceUri: workspace.configPath }; + } else { + forceEmpty = true; + } - // We have to reconstruct a openable from the current workspace - let uriToOpen: IWorkspaceToOpen | IFolderToOpen | undefined = undefined; - let forceEmpty = undefined; - if (isSingleFolderWorkspaceIdentifier(workspace)) { - uriToOpen = { folderUri: workspace.uri }; - } else if (isWorkspaceIdentifier(workspace)) { - uriToOpen = { workspaceUri: workspace.configPath }; - } else { - forceEmpty = true; + // Delegate to windows service + const window = firstOrDefault(await this.windowsMainService.open({ + context: OpenContext.API, + userEnv: this._config.userEnv, + cli: { + ...this.environmentMainService.args, + _: [] // we pass in the workspace to open explicitly via `urisToOpen` + }, + urisToOpen: uriToOpen ? [uriToOpen] : undefined, + forceEmpty, + forceNewWindow: true, + remoteAuthority: this.remoteAuthority + })); + window?.focus(); } - - // Delegate to windows service - const window = firstOrDefault(await this.windowsMainService.open({ - context: OpenContext.API, - userEnv: this._config.userEnv, - cli: { - ...this.environmentMainService.args, - _: [] // we pass in the workspace to open explicitly via `urisToOpen` - }, - urisToOpen: uriToOpen ? [uriToOpen] : undefined, - forceEmpty, - forceNewWindow: true, - remoteAuthority: this.remoteAuthority - })); - window?.focus(); + } finally { + // make sure to destroy the window as its renderer process is gone. do this + // after the code for reopening the window, to prevent the entire application + // from quitting when the last window closes as a result. + this._win?.destroy(); } } diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 576725137cd..3053b0782ee 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -1495,7 +1495,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic const disposables = new DisposableStore(); disposables.add(createdWindow.onDidSignalReady(() => this._onDidSignalReadyWindow.fire(createdWindow))); disposables.add(Event.once(createdWindow.onDidClose)(() => this.onWindowClosed(createdWindow, disposables))); - disposables.add(Event.once(createdWindow.onDidDestroy)(() => this._onDidDestroyWindow.fire(createdWindow))); + disposables.add(Event.once(createdWindow.onDidDestroy)(() => this.onWindowDestroyed(createdWindow))); disposables.add(createdWindow.onDidMaximize(() => this._onDidMaximizeWindow.fire(createdWindow))); disposables.add(createdWindow.onDidUnmaximize(() => this._onDidUnmaximizeWindow.fire(createdWindow))); disposables.add(createdWindow.onDidTriggerSystemContextMenu(({ x, y }) => this._onDidTriggerSystemContextMenu.fire({ window: createdWindow, x, y }))); @@ -1627,6 +1627,15 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic disposables.dispose(); } + private onWindowDestroyed(window: ICodeWindow): void { + + // Remove from our list so that Electron can clean it up + this.windows.delete(window.id); + + // Emit + this._onDidDestroyWindow.fire(window); + } + getFocusedWindow(): ICodeWindow | undefined { const window = BrowserWindow.getFocusedWindow(); if (window) { From 4728954baa48be22d107cb459fe291ec44e0f13a Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 5 Dec 2023 20:59:47 +0100 Subject: [PATCH 23/37] Fixes #178245 --- .../linesSliceCharSequence.ts | 6 ++++- .../advanced.expected.diff.json | 8 +++++-- .../fixtures/shifting-parameters/1.tst | 1 + .../fixtures/shifting-parameters/2.tst | 1 + .../advanced.expected.diff.json | 22 +++++++++++++++++++ .../legacy.expected.diff.json | 22 +++++++++++++++++++ 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 src/vs/editor/test/node/diffing/fixtures/shifting-parameters/1.tst create mode 100644 src/vs/editor/test/node/diffing/fixtures/shifting-parameters/2.tst create mode 100644 src/vs/editor/test/node/diffing/fixtures/shifting-parameters/advanced.expected.diff.json create mode 100644 src/vs/editor/test/node/diffing/fixtures/shifting-parameters/legacy.expected.diff.json diff --git a/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts b/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts index fe408e95581..9edc63d335f 100644 --- a/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts +++ b/src/vs/editor/common/diff/defaultLinesDiffComputer/linesSliceCharSequence.ts @@ -92,6 +92,10 @@ export class LinesSliceCharSequence implements ISequence { // don't break between \r and \n return 0; } + if (prevCategory === CharBoundaryCategory.LineBreakLF) { + // prefer the linebreak before the change + return 150; + } let score = 0; if (prevCategory !== nextCategory) { @@ -187,7 +191,7 @@ const score: Record = { [CharBoundaryCategory.WordNumber]: 0, [CharBoundaryCategory.End]: 10, [CharBoundaryCategory.Other]: 2, - [CharBoundaryCategory.Separator]: 3, + [CharBoundaryCategory.Separator]: 30, [CharBoundaryCategory.Space]: 3, [CharBoundaryCategory.LineBreakCR]: 10, [CharBoundaryCategory.LineBreakLF]: 10, diff --git a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json index ca938c66689..b1de25a5907 100644 --- a/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/method-splitting/advanced.expected.diff.json @@ -21,8 +21,12 @@ "modifiedRange": "[7,76 -> 7,80]" }, { - "originalRange": "[12,153 -> 12,155 EOL]", - "modifiedRange": "[7,157 -> 8,1 EOL]" + "originalRange": "[12,153 -> 12,153]", + "modifiedRange": "[7,157 -> 7,181]" + }, + { + "originalRange": "[13,1 -> 13,1]", + "modifiedRange": "[8,1 -> 9,1]" }, { "originalRange": "[13,31 -> 13,31]", diff --git a/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/1.tst b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/1.tst new file mode 100644 index 00000000000..4e4a1168350 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/1.tst @@ -0,0 +1 @@ +function x(alignments: RangeMapping[]): x[] { } diff --git a/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/2.tst b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/2.tst new file mode 100644 index 00000000000..3bdfadaa26c --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/2.tst @@ -0,0 +1 @@ +function x(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[]): x[] { } diff --git a/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/advanced.expected.diff.json new file mode 100644 index 00000000000..3e860d858f8 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/advanced.expected.diff.json @@ -0,0 +1,22 @@ +{ + "original": { + "content": "function x(alignments: RangeMapping[]): x[] { }\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "function x(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[]): x[] { }\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[1,2)", + "modifiedRange": "[1,2)", + "innerChanges": [ + { + "originalRange": "[1,38 -> 1,38]", + "modifiedRange": "[1,38 -> 1,88]" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/legacy.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/legacy.expected.diff.json new file mode 100644 index 00000000000..3e860d858f8 --- /dev/null +++ b/src/vs/editor/test/node/diffing/fixtures/shifting-parameters/legacy.expected.diff.json @@ -0,0 +1,22 @@ +{ + "original": { + "content": "function x(alignments: RangeMapping[]): x[] { }\n", + "fileName": "./1.tst" + }, + "modified": { + "content": "function x(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[]): x[] { }\n", + "fileName": "./2.tst" + }, + "diffs": [ + { + "originalRange": "[1,2)", + "modifiedRange": "[1,2)", + "innerChanges": [ + { + "originalRange": "[1,38 -> 1,38]", + "modifiedRange": "[1,38 -> 1,88]" + } + ] + } + ] +} \ No newline at end of file From 16c469a671222fda0ab186461566ec05d4698b36 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 5 Dec 2023 14:35:27 -0800 Subject: [PATCH 24/37] eng: add a lint rule for ensureNoDisposablesAreLeakedInTestSuite (#200089) Adds a lint rule that ensures ensureNoDisposablesAreLeakedInTestSuite is called in suites. It grandfathers in existing files that were lacking the call entirely. This PR also includes manual fixes to files that used the function already but were missing it in one or more suites, which the lint rule detects. --- ...code-ensure-no-disposables-leak-in-test.ts | 38 ++ .eslintrc.json | 220 ++++++++++ .../base/parts/ipc/test/node/ipc.net.test.ts | 10 +- .../test/browser/ui/list/rangeMap.test.ts | 2 + .../test/browser/ui/tree/objectTree.test.ts | 10 +- src/vs/base/test/common/event.test.ts | 415 +++++++++--------- src/vs/base/test/common/history.test.ts | 2 + src/vs/base/test/common/lifecycle.test.ts | 7 +- .../test/browser/multicursor.test.ts | 2 + .../node/extensionsScannerService.test.ts | 2 + .../test/browser/fileUserDataProvider.test.ts | 40 +- .../common/userDataSyncStoreService.test.ts | 3 + .../test/browser/extHostDocumentData.test.ts | 2 + .../chat/test/common/chatModel.test.ts | 2 + .../test/browser/notebookCommon.test.ts | 5 + .../test/browser/notebookSelection.test.ts | 3 + .../services/label/test/browser/label.test.ts | 2 + 17 files changed, 531 insertions(+), 234 deletions(-) create mode 100644 .eslintplugin/code-ensure-no-disposables-leak-in-test.ts diff --git a/.eslintplugin/code-ensure-no-disposables-leak-in-test.ts b/.eslintplugin/code-ensure-no-disposables-leak-in-test.ts new file mode 100644 index 00000000000..ae3089036a6 --- /dev/null +++ b/.eslintplugin/code-ensure-no-disposables-leak-in-test.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as eslint from 'eslint'; +import { Node } from 'estree'; + +export = new class EnsureNoDisposablesAreLeakedInTestSuite implements eslint.Rule.RuleModule { + + readonly meta: eslint.Rule.RuleMetaData = { + type: 'problem', + messages: { + ensure: 'Suites should include a call to `ensureNoDisposablesAreLeakedInTestSuite()` to ensure no disposables are leaked in tests.' + } + }; + + create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { + const config = <{ exclude: string[] }>context.options[0]; + + const needle = context.getFilename().replace(/\\/g, '/'); + if (config.exclude.some((e) => needle.endsWith(e))) { + return {}; + } + + return { + [`Program > ExpressionStatement > CallExpression[callee.name='suite']`]: (node: Node) => { + const src = context.getSourceCode().getText(node) + if (!src.includes('ensureNoDisposablesAreLeakedInTestSuite(')) { + context.report({ + node, + messageId: 'ensure', + }); + } + }, + }; + } +}; diff --git a/.eslintrc.json b/.eslintrc.json index fd88130a1e8..d6d14e5d43b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -136,6 +136,226 @@ ] } }, + { + "files": [ + "src/vs/**/*.test.ts" + ], + "rules": { + "local/code-ensure-no-disposables-leak-in-test": [ + "warn", + { + // Files should (only) be removed from the list they adopt the leak detector + "exclude": [ + "src/vs/base/parts/sandbox/test/electron-sandbox/globals.test.ts", + "src/vs/base/test/browser/browser.test.ts", + "src/vs/base/test/browser/comparers.test.ts", + "src/vs/base/test/browser/dom.test.ts", + "src/vs/base/test/browser/formattedTextRenderer.test.ts", + "src/vs/base/test/browser/hash.test.ts", + "src/vs/base/test/browser/iconLabels.test.ts", + "src/vs/base/test/browser/indexedDB.test.ts", + "src/vs/base/test/browser/ui/contextview/contextview.test.ts", + "src/vs/base/test/browser/ui/menu/menubar.test.ts", + "src/vs/base/test/browser/ui/scrollbar/scrollableElement.test.ts", + "src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts", + "src/vs/base/test/common/arrays.test.ts", + "src/vs/base/test/common/arraysFind.test.ts", + "src/vs/base/test/common/assert.test.ts", + "src/vs/base/test/common/cache.test.ts", + "src/vs/base/test/common/charCode.test.ts", + "src/vs/base/test/common/collections.test.ts", + "src/vs/base/test/common/color.test.ts", + "src/vs/base/test/common/console.test.ts", + "src/vs/base/test/common/decorators.test.ts", + "src/vs/base/test/common/diff/diff.test.ts", + "src/vs/base/test/common/errors.test.ts", + "src/vs/base/test/common/filters.perf.test.ts", + "src/vs/base/test/common/filters.test.ts", + "src/vs/base/test/common/iconLabels.test.ts", + "src/vs/base/test/common/iterator.test.ts", + "src/vs/base/test/common/json.test.ts", + "src/vs/base/test/common/jsonEdit.test.ts", + "src/vs/base/test/common/jsonFormatter.test.ts", + "src/vs/base/test/common/keybindings.test.ts", + "src/vs/base/test/common/keyCodes.test.ts", + "src/vs/base/test/common/lazy.test.ts", + "src/vs/base/test/common/linkedList.test.ts", + "src/vs/base/test/common/linkedText.test.ts", + "src/vs/base/test/common/map.test.ts", + "src/vs/base/test/common/markdownString.test.ts", + "src/vs/base/test/common/marshalling.test.ts", + "src/vs/base/test/common/mime.test.ts", + "src/vs/base/test/common/naturalLanguage/korean.test.ts", + "src/vs/base/test/common/network.test.ts", + "src/vs/base/test/common/normalization.test.ts", + "src/vs/base/test/common/objects.test.ts", + "src/vs/base/test/common/observable.test.ts", + "src/vs/base/test/common/path.test.ts", + "src/vs/base/test/common/prefixTree.test.ts", + "src/vs/base/test/common/resources.test.ts", + "src/vs/base/test/common/resourceTree.test.ts", + "src/vs/base/test/common/scrollable.test.ts", + "src/vs/base/test/common/skipList.test.ts", + "src/vs/base/test/common/strings.test.ts", + "src/vs/base/test/common/stripComments.test.ts", + "src/vs/base/test/common/ternarySearchtree.test.ts", + "src/vs/base/test/common/tfIdf.test.ts", + "src/vs/base/test/common/types.test.ts", + "src/vs/base/test/common/uri.test.ts", + "src/vs/base/test/common/uuid.test.ts", + "src/vs/base/test/node/crypto.test.ts", + "src/vs/base/test/node/css.build.test.ts", + "src/vs/base/test/node/id.test.ts", + "src/vs/base/test/node/nodeStreams.test.ts", + "src/vs/base/test/node/port.test.ts", + "src/vs/base/test/node/powershell.test.ts", + "src/vs/base/test/node/snapshot.test.ts", + "src/vs/base/test/node/unc.test.ts", + "src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts", + "src/vs/editor/contrib/codeAction/test/browser/codeActionKeybindingResolver.test.ts", + "src/vs/editor/contrib/codeAction/test/browser/codeActionModel.test.ts", + "src/vs/editor/contrib/dropOrPasteInto/test/browser/editSort.test.ts", + "src/vs/editor/contrib/folding/test/browser/foldingModel.test.ts", + "src/vs/editor/contrib/folding/test/browser/foldingRanges.test.ts", + "src/vs/editor/contrib/folding/test/browser/indentFold.test.ts", + "src/vs/editor/contrib/folding/test/browser/indentRangeProvider.test.ts", + "src/vs/editor/contrib/gotoSymbol/test/browser/referencesModel.test.ts", + "src/vs/editor/contrib/smartSelect/test/browser/smartSelect.test.ts", + "src/vs/editor/contrib/snippet/test/browser/snippetParser.test.ts", + "src/vs/editor/contrib/snippet/test/browser/snippetSession.test.ts", + "src/vs/editor/contrib/snippet/test/browser/snippetVariables.test.ts", + "src/vs/editor/contrib/suggest/test/browser/completionModel.test.ts", + "src/vs/editor/contrib/suggest/test/browser/suggestMemory.test.ts", + "src/vs/editor/test/common/services/languageService.test.ts", + "src/vs/editor/test/node/classification/typescript.test.ts", + "src/vs/editor/test/node/diffing/defaultLinesDiffComputer.test.ts", + "src/vs/editor/test/node/diffing/fixtures.test.ts", + "src/vs/platform/configuration/test/common/configuration.test.ts", + "src/vs/platform/configuration/test/common/configurationModels.test.ts", + "src/vs/platform/configuration/test/common/configurationRegistry.test.ts", + "src/vs/platform/contextkey/test/common/contextkey.test.ts", + "src/vs/platform/contextkey/test/common/parser.test.ts", + "src/vs/platform/contextkey/test/common/scanner.test.ts", + "src/vs/platform/dialogs/test/common/dialog.test.ts", + "src/vs/platform/environment/test/node/argv.test.ts", + "src/vs/platform/environment/test/node/userDataPath.test.ts", + "src/vs/platform/extensionManagement/test/common/configRemotes.test.ts", + "src/vs/platform/extensionManagement/test/common/extensionManagement.test.ts", + "src/vs/platform/extensions/test/common/extensionValidator.test.ts", + "src/vs/platform/externalTerminal/electron-main/externalTerminalService.test.ts", + "src/vs/platform/instantiation/test/common/graph.test.ts", + "src/vs/platform/instantiation/test/common/instantiationService.test.ts", + "src/vs/platform/keybinding/test/common/abstractKeybindingService.test.ts", + "src/vs/platform/keybinding/test/common/keybindingLabels.test.ts", + "src/vs/platform/keybinding/test/common/keybindingResolver.test.ts", + "src/vs/platform/markers/test/common/markerService.test.ts", + "src/vs/platform/opener/test/common/opener.test.ts", + "src/vs/platform/progress/test/common/progress.test.ts", + "src/vs/platform/registry/test/common/platform.test.ts", + "src/vs/platform/remote/test/common/remoteHosts.test.ts", + "src/vs/platform/telemetry/test/browser/1dsAppender.test.ts", + "src/vs/platform/telemetry/test/browser/telemetryService.test.ts", + "src/vs/platform/telemetry/test/common/telemetryLogAppender.test.ts", + "src/vs/platform/undoRedo/test/common/undoRedoService.test.ts", + "src/vs/platform/userDataSync/test/common/extensionsMerge.test.ts", + "src/vs/platform/userDataSync/test/common/globalStateMerge.test.ts", + "src/vs/platform/userDataSync/test/common/settingsMerge.test.ts", + "src/vs/platform/userDataSync/test/common/snippetsMerge.test.ts", + "src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts", + "src/vs/platform/workspace/test/common/workspace.test.ts", + "src/vs/platform/workspaces/test/common/workspaces.test.ts", + "src/vs/platform/workspaces/test/electron-main/workspaces.test.ts", + "src/vs/server/test/node/serverConnectionToken.test.ts", + "src/vs/workbench/api/test/browser/extHost.api.impl.test.ts", + "src/vs/workbench/api/test/browser/extHostApiCommands.test.ts", + "src/vs/workbench/api/test/browser/extHostBulkEdits.test.ts", + "src/vs/workbench/api/test/browser/extHostCommands.test.ts", + "src/vs/workbench/api/test/browser/extHostDocumentSaveParticipant.test.ts", + "src/vs/workbench/api/test/browser/extHostMessagerService.test.ts", + "src/vs/workbench/api/test/browser/extHostTelemetry.test.ts", + "src/vs/workbench/api/test/browser/extHostTextEditor.test.ts", + "src/vs/workbench/api/test/browser/extHostTypeConverter.test.ts", + "src/vs/workbench/api/test/browser/extHostTypes.test.ts", + "src/vs/workbench/api/test/browser/extHostWorkspace.test.ts", + "src/vs/workbench/api/test/browser/mainThreadConfiguration.test.ts", + "src/vs/workbench/api/test/browser/mainThreadDocuments.test.ts", + "src/vs/workbench/api/test/common/extensionHostMain.test.ts", + "src/vs/workbench/api/test/common/extHostExtensionActivator.test.ts", + "src/vs/workbench/api/test/node/extHostTunnelService.test.ts", + "src/vs/workbench/contrib/bulkEdit/test/browser/bulkCellEdits.test.ts", + "src/vs/workbench/contrib/chat/test/common/chatWordCounter.test.ts", + "src/vs/workbench/contrib/debug/test/browser/baseDebugView.test.ts", + "src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts", + "src/vs/workbench/contrib/debug/test/browser/callStack.test.ts", + "src/vs/workbench/contrib/debug/test/browser/debugHover.test.ts", + "src/vs/workbench/contrib/debug/test/browser/repl.test.ts", + "src/vs/workbench/contrib/debug/test/common/debugModel.test.ts", + "src/vs/workbench/contrib/debug/test/node/debugger.test.ts", + "src/vs/workbench/contrib/debug/test/node/streamDebugAdapter.test.ts", + "src/vs/workbench/contrib/debug/test/node/terminals.test.ts", + "src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts", + "src/vs/workbench/contrib/extensions/test/common/extensionQuery.test.ts", + "src/vs/workbench/contrib/extensions/test/electron-sandbox/extension.test.ts", + "src/vs/workbench/contrib/files/test/browser/explorerFileNestingTrie.test.ts", + "src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts", + "src/vs/workbench/contrib/files/test/browser/explorerView.test.ts", + "src/vs/workbench/contrib/files/test/browser/fileActions.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/cellDnd.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/contrib/contributedStatusBarItemController.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/contrib/executionStatusBarItem.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/contrib/layoutActions.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/contrib/outputCopyTests.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/notebookBrowser.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/notebookExecutionService.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/notebookExecutionStateService.test.ts", + "src/vs/workbench/contrib/notebook/test/browser/notebookTextModel.test.ts", + "src/vs/workbench/contrib/search/test/common/cacheState.test.ts", + "src/vs/workbench/contrib/search/test/common/extractRange.test.ts", + "src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts", + "src/vs/workbench/contrib/snippets/test/browser/snippetsRegistry.test.ts", + "src/vs/workbench/contrib/snippets/test/browser/snippetsRewrite.test.ts", + "src/vs/workbench/contrib/tags/test/node/workspaceTags.test.ts", + "src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts", + "src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts", + "src/vs/workbench/contrib/terminal/test/browser/terminalActions.test.ts", + "src/vs/workbench/contrib/themes/test/node/colorRegistryExport.test.ts", + "src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts", + "src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts", + "src/vs/workbench/services/commands/test/common/commandService.test.ts", + "src/vs/workbench/services/configuration/test/common/configurationModels.test.ts", + "src/vs/workbench/services/configurationResolver/test/electron-sandbox/configurationResolverService.test.ts", + "src/vs/workbench/services/dialogs/test/electron-sandbox/fileDialogService.test.ts", + "src/vs/workbench/services/editor/test/browser/editorResolverService.test.ts", + "src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts", + "src/vs/workbench/services/keybinding/test/browser/keybindingIO.test.ts", + "src/vs/workbench/services/keybinding/test/node/fallbackKeyboardMapper.test.ts", + "src/vs/workbench/services/keybinding/test/node/macLinuxKeyboardMapper.test.ts", + "src/vs/workbench/services/keybinding/test/node/windowsKeyboardMapper.test.ts", + "src/vs/workbench/services/preferences/test/browser/preferencesService.test.ts", + "src/vs/workbench/services/preferences/test/common/preferencesValidation.test.ts", + "src/vs/workbench/services/search/test/browser/queryBuilder.test.ts", + "src/vs/workbench/services/search/test/common/ignoreFile.test.ts", + "src/vs/workbench/services/search/test/common/queryBuilder.test.ts", + "src/vs/workbench/services/search/test/common/replace.test.ts", + "src/vs/workbench/services/search/test/common/search.test.ts", + "src/vs/workbench/services/search/test/common/searchHelpers.test.ts", + "src/vs/workbench/services/search/test/node/ripgrepFileSearch.test.ts", + "src/vs/workbench/services/search/test/node/ripgrepTextSearchEngineUtils.test.ts", + "src/vs/workbench/services/search/test/node/textSearchManager.test.ts", + "src/vs/workbench/services/telemetry/test/browser/commonProperties.test.ts", + "src/vs/workbench/services/textfile/test/common/textFileService.io.test.ts", + "src/vs/workbench/services/textMate/test/browser/arrayOperation.test.ts", + "src/vs/workbench/services/themes/test/node/tokenStyleResolving.test.ts", + "src/vs/workbench/services/userActivity/test/browser/domActivityTracker.test.ts", + "src/vs/workbench/services/workspaces/test/browser/workspaces.test.ts", + "src/vs/workbench/services/workspaces/test/common/workspaceTrust.test.ts", + "src/vs/workbench/test/browser/quickAccess.test.ts", + "src/vs/workbench/test/browser/webview.test.ts" + ] + } + ] + } + }, { "files": [ "**/vscode.d.ts", diff --git a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts index 8255c780ccf..0e018300cea 100644 --- a/src/vs/base/parts/ipc/test/node/ipc.net.test.ts +++ b/src/vs/base/parts/ipc/test/node/ipc.net.test.ts @@ -571,6 +571,8 @@ flakySuite('IPC, create handle', () => { suite('WebSocketNodeSocket', () => { + const ds = ensureNoDisposablesAreLeakedInTestSuite(); + function toUint8Array(data: number[]): Uint8Array { const result = new Uint8Array(data.length); for (let i = 0; i < data.length; i++) { @@ -724,15 +726,15 @@ suite('WebSocketNodeSocket', () => { server.close(); const webSocketNodeSocket = new WebSocketNodeSocket(new NodeSocket(socket), true, null, false); - webSocketNodeSocket.onData((data) => { + ds.add(webSocketNodeSocket.onData((data) => { receivingSideOnDataCallCount++; receivingSideTotalBytes += data.byteLength; - }); + })); - webSocketNodeSocket.onClose(() => { + ds.add(webSocketNodeSocket.onClose(() => { webSocketNodeSocket.dispose(); receivingSideSocketClosedBarrier.open(); - }); + })); }); const socket = connect({ diff --git a/src/vs/base/test/browser/ui/list/rangeMap.test.ts b/src/vs/base/test/browser/ui/list/rangeMap.test.ts index 0171250324b..5b3b4a6c65f 100644 --- a/src/vs/base/test/browser/ui/list/rangeMap.test.ts +++ b/src/vs/base/test/browser/ui/list/rangeMap.test.ts @@ -361,6 +361,8 @@ suite('RangeMap', () => { suite('RangeMap with top padding', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('empty', () => { const rangeMap = new RangeMap(10); assert.strictEqual(rangeMap.size, 10); diff --git a/src/vs/base/test/browser/ui/tree/objectTree.test.ts b/src/vs/base/test/browser/ui/tree/objectTree.test.ts index a3e39846a5b..05594bf561a 100644 --- a/src/vs/base/test/browser/ui/tree/objectTree.test.ts +++ b/src/vs/base/test/browser/ui/tree/objectTree.test.ts @@ -250,12 +250,14 @@ suite('CompressibleObjectTree', function () { disposeTemplate(): void { } } + const ds = ensureNoDisposablesAreLeakedInTestSuite(); + test('empty', function () { const container = document.createElement('div'); container.style.width = '200px'; container.style.height = '200px'; - const tree = new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()]); + const tree = ds.add(new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()])); tree.layout(200); assert.strictEqual(getRowsTextContent(container).length, 0); @@ -266,7 +268,7 @@ suite('CompressibleObjectTree', function () { container.style.width = '200px'; container.style.height = '200px'; - const tree = new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()]); + const tree = ds.add(new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()])); tree.layout(200); tree.setChildren(null, [ @@ -289,7 +291,7 @@ suite('CompressibleObjectTree', function () { container.style.width = '200px'; container.style.height = '200px'; - const tree = new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()]); + const tree = ds.add(new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()])); tree.layout(200); tree.setChildren(null, [ @@ -341,7 +343,7 @@ suite('CompressibleObjectTree', function () { container.style.width = '200px'; container.style.height = '200px'; - const tree = new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()]); + const tree = ds.add(new CompressibleObjectTree('test', container, new Delegate(), [new Renderer()])); tree.layout(200); tree.setChildren(null, [ diff --git a/src/vs/base/test/common/event.test.ts b/src/vs/base/test/common/event.test.ts index 2231acac008..df7aac4363d 100644 --- a/src/vs/base/test/common/event.test.ts +++ b/src/vs/base/test/common/event.test.ts @@ -40,11 +40,17 @@ namespace Samples { this._onDidChange.fire(value); } + dispose() { + this._onDidChange.dispose(); + } + } } suite('Event utils dispose', function () { + const ds = ensureNoDisposablesAreLeakedInTestSuite(); + let tracker = new DisposableTracker(); function assertDisposablesCount(expected: number | Array) { @@ -75,7 +81,7 @@ suite('Event utils dispose', function () { test('no leak with snapshot-utils', function () { const store = new DisposableStore(); - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const evens = Event.filter(emitter.event, n => n % 2 === 0, store); assertDisposablesCount(1); // snaphot only listen when `evens` is being listened on @@ -91,7 +97,7 @@ suite('Event utils dispose', function () { test('no leak with debounce-util', function () { const store = new DisposableStore(); - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const debounced = Event.debounce(emitter.event, (l) => 0, undefined, undefined, undefined, undefined, store); assertDisposablesCount(1); // debounce only listens when `debounce` is being listened on @@ -109,13 +115,15 @@ suite('Event utils dispose', function () { suite('Event', function () { + const ds = ensureNoDisposablesAreLeakedInTestSuite(); + const counter = new Samples.EventCounter(); setup(() => counter.reset()); test('Emitter plain', function () { - const doc = new Samples.Document3(); + const doc = ds.add(new Samples.Document3()); const subscription = doc.onDidChange(counter.onEvent, counter); @@ -133,10 +141,10 @@ suite('Event', function () { const a = (v: string) => calls.push(`a${v}`); const b = (v: string) => calls.push(`b${v}`); - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); - emitter.event(a); - emitter.event(b); + ds.add(emitter.event(a)); + ds.add(emitter.event(b)); const s2 = emitter.event(a); emitter.fire('1'); @@ -150,14 +158,14 @@ suite('Event', function () { test('Emitter, dispose listener during emission', () => { for (let keepFirstMod = 1; keepFirstMod < 4; keepFirstMod++) { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const calls: number[] = []; - const disposables = Array.from({ length: 25 }, (_, n) => emitter.event(() => { + const disposables = Array.from({ length: 25 }, (_, n) => ds.add(emitter.event(() => { if (n % keepFirstMod === 0) { disposables[n].dispose(); } calls.push(n); - })); + }))); emitter.fire(); assert.deepStrictEqual(calls, Array.from({ length: 25 }, (_, n) => n)); @@ -165,14 +173,14 @@ suite('Event', function () { }); test('Emitter, dispose emitter during emission', () => { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const calls: number[] = []; - const disposables = Array.from({ length: 25 }, (_, n) => emitter.event(() => { + const disposables = Array.from({ length: 25 }, (_, n) => ds.add(emitter.event(() => { if (n === 10) { emitter.dispose(); } calls.push(n); - })); + }))); emitter.fire(); disposables.forEach(d => d.dispose()); @@ -181,15 +189,15 @@ suite('Event', function () { test('Emitter, shared delivery queue', () => { const deliveryQueue = createEventDeliveryQueue(); - const emitter1 = new Emitter({ deliveryQueue }); - const emitter2 = new Emitter({ deliveryQueue }); + const emitter1 = ds.add(new Emitter({ deliveryQueue })); + const emitter2 = ds.add(new Emitter({ deliveryQueue })); const calls: string[] = []; - emitter1.event(d => { calls.push(`${d}a`); if (d === 1) { emitter2.fire(2); } }); - emitter1.event(d => { calls.push(`${d}b`); }); + ds.add(emitter1.event(d => { calls.push(`${d}a`); if (d === 1) { emitter2.fire(2); } })); + ds.add(emitter1.event(d => { calls.push(`${d}b`); })); - emitter2.event(d => { calls.push(`${d}c`); emitter1.dispose(); }); - emitter2.event(d => { calls.push(`${d}d`); }); + ds.add(emitter2.event(d => { calls.push(`${d}c`); emitter1.dispose(); })); + ds.add(emitter2.event(d => { calls.push(`${d}d`); })); emitter1.fire(1); @@ -201,13 +209,13 @@ suite('Event', function () { test('Emitter, handles removal during 3', () => { const fn1 = stub(); const fn2 = stub(); - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); - emitter.event(fn1); + ds.add(emitter.event(fn1)); const h = emitter.event(() => { h.dispose(); }); - emitter.event(fn2); + ds.add(emitter.event(fn2)); emitter.fire('foo'); assert.deepStrictEqual(fn2.args, [['foo']]); @@ -216,9 +224,9 @@ suite('Event', function () { test('Emitter, handles removal during 2', () => { const fn1 = stub(); - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); - emitter.event(fn1); + ds.add(emitter.event(fn1)); const h = emitter.event(() => { h.dispose(); }); @@ -230,7 +238,7 @@ suite('Event', function () { test('Emitter, bucket', function () { const bucket: IDisposable[] = []; - const doc = new Samples.Document3(); + const doc = ds.add(new Samples.Document3()); const subscription = doc.onDidChange(counter.onEvent, counter, bucket); doc.setText('far'); @@ -251,8 +259,8 @@ suite('Event', function () { test('Emitter, store', function () { - const bucket = new DisposableStore(); - const doc = new Samples.Document3(); + const bucket = ds.add(new DisposableStore()); + const doc = ds.add(new Samples.Document3()); const subscription = doc.onDidChange(counter.onEvent, counter, bucket); doc.setText('far'); @@ -273,16 +281,16 @@ suite('Event', function () { let firstCount = 0; let lastCount = 0; - const a = new Emitter({ + const a = ds.add(new Emitter({ onWillAddFirstListener() { firstCount += 1; }, onDidRemoveLastListener() { lastCount += 1; } - }); + })); assert.strictEqual(firstCount, 0); assert.strictEqual(lastCount, 0); - let subscription1 = a.event(function () { }); - const subscription2 = a.event(function () { }); + let subscription1 = ds.add(a.event(function () { })); + const subscription2 = ds.add(a.event(function () { })); assert.strictEqual(firstCount, 1); assert.strictEqual(lastCount, 0); @@ -294,26 +302,26 @@ suite('Event', function () { assert.strictEqual(firstCount, 1); assert.strictEqual(lastCount, 1); - subscription1 = a.event(function () { }); + subscription1 = ds.add(a.event(function () { })); assert.strictEqual(firstCount, 2); assert.strictEqual(lastCount, 1); }); test('onWillRemoveListener', () => { let count = 0; - const a = new Emitter({ + const a = ds.add(new Emitter({ onWillRemoveListener() { count += 1; } - }); + })); assert.strictEqual(count, 0); - let subscription = a.event(function () { }); + let subscription = ds.add(a.event(function () { })); assert.strictEqual(count, 0); subscription.dispose(); assert.strictEqual(count, 1); - subscription = a.event(function () { }); + subscription = ds.add(a.event(function () { })); assert.strictEqual(count, 1); }); @@ -322,15 +330,15 @@ suite('Event', function () { setUnexpectedErrorHandler(() => null); try { - const a = new Emitter(); + const a = ds.add(new Emitter()); let hit = false; - a.event(function () { + ds.add(a.event(function () { // eslint-disable-next-line no-throw-literal throw 9; - }); - a.event(function () { + })); + ds.add(a.event(function () { hit = true; - }); + })); a.fire(undefined); assert.strictEqual(hit, true); @@ -343,17 +351,17 @@ suite('Event', function () { const allError: any[] = []; - const a = new Emitter({ + const a = ds.add(new Emitter({ onListenerError(e) { allError.push(e); } - }); + })); let hit = false; - a.event(function () { + ds.add(a.event(function () { // eslint-disable-next-line no-throw-literal throw 9; - }); - a.event(function () { + })); + ds.add(a.event(function () { hit = true; - }); + })); a.fire(undefined); assert.strictEqual(hit, true); assert.deepStrictEqual(allError, [9]); @@ -367,7 +375,7 @@ suite('Event', function () { } const context = {}; - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const reg1 = emitter.event(listener, context); const reg2 = emitter.event(listener, context); @@ -395,7 +403,7 @@ suite('Event', function () { } }); - emitter.event(e => { sum = e; }); + ds.add(emitter.event(e => { sum = e; })); const p = Event.toPromise(emitter.event); @@ -433,18 +441,18 @@ suite('Event', function () { }); test('Emitter - In Order Delivery', function () { - const a = new Emitter(); + const a = ds.add(new Emitter()); const listener2Events: string[] = []; - a.event(function listener1(event) { + ds.add(a.event(function listener1(event) { if (event === 'e1') { a.fire('e2'); // assert that all events are delivered at this point assert.deepStrictEqual(listener2Events, ['e1', 'e2']); } - }); - a.event(function listener2(event) { + })); + ds.add(a.event(function listener2(event) { listener2Events.push(event); - }); + })); a.fire('e1'); // assert that all events are delivered in order @@ -452,25 +460,25 @@ suite('Event', function () { }); test('Emitter, - In Order Delivery 3x', function () { - const a = new Emitter(); + const a = ds.add(new Emitter()); const listener2Events: string[] = []; - a.event(function listener1(event) { + ds.add(a.event(function listener1(event) { if (event === 'e2') { a.fire('e3'); // assert that all events are delivered at this point assert.deepStrictEqual(listener2Events, ['e1', 'e2', 'e3']); } - }); - a.event(function listener1(event) { + })); + ds.add(a.event(function listener1(event) { if (event === 'e1') { a.fire('e2'); // assert that all events are delivered at this point assert.deepStrictEqual(listener2Events, ['e1', 'e2', 'e3']); } - }); - a.event(function listener2(event) { + })); + ds.add(a.event(function listener2(event) { listener2Events.push(event); - }); + })); a.fire('e1'); // assert that all events are delivered in order @@ -478,7 +486,7 @@ suite('Event', function () { }); test('Cannot read property \'_actual\' of undefined #142204', function () { - const e = new Emitter(); + const e = ds.add(new Emitter()); const dispo = e.event(() => { }); dispo.dispose.call(undefined); // assert that disposable can be called with this }); @@ -486,6 +494,8 @@ suite('Event', function () { suite('AsyncEmitter', function () { + const ds = ensureNoDisposablesAreLeakedInTestSuite(); + test('event has waitUntil-function', async function () { interface E extends IWaitUntil { @@ -495,11 +505,11 @@ suite('AsyncEmitter', function () { const emitter = new AsyncEmitter(); - emitter.event(e => { + ds.add(emitter.event(e => { assert.strictEqual(e.foo, true); assert.strictEqual(e.bar, 1); assert.strictEqual(typeof e.waitUntil, 'function'); - }); + })); emitter.fireAsync({ foo: true, bar: 1, }, CancellationToken.None); emitter.dispose(); @@ -515,19 +525,19 @@ suite('AsyncEmitter', function () { let globalState = 0; const emitter = new AsyncEmitter(); - emitter.event(e => { + ds.add(emitter.event(e => { e.waitUntil(timeout(10).then(_ => { assert.strictEqual(globalState, 0); globalState += 1; })); - }); + })); - emitter.event(e => { + ds.add(emitter.event(e => { e.waitUntil(timeout(1).then(_ => { assert.strictEqual(globalState, 1); globalState += 1; })); - }); + })); await emitter.fireAsync({ foo: true }, CancellationToken.None); assert.strictEqual(globalState, 2); @@ -545,7 +555,7 @@ suite('AsyncEmitter', function () { const emitter = new AsyncEmitter(); // e1 - emitter.event(e => { + ds.add(emitter.event(e => { e.waitUntil(timeout(10).then(async _ => { if (e.foo === 1) { await emitter.fireAsync({ foo: 2 }, CancellationToken.None); @@ -553,13 +563,13 @@ suite('AsyncEmitter', function () { done = true; } })); - }); + })); // e2 - emitter.event(e => { + ds.add(emitter.event(e => { events.push(e.foo); e.waitUntil(timeout(7)); - }); + })); await emitter.fireAsync({ foo: 1 }, CancellationToken.None); assert.ok(done); @@ -577,16 +587,16 @@ suite('AsyncEmitter', function () { let globalState = 0; const emitter = new AsyncEmitter(); - emitter.event(e => { + ds.add(emitter.event(e => { globalState += 1; e.waitUntil(new Promise((_r, reject) => reject(new Error()))); - }); + })); - emitter.event(e => { + ds.add(emitter.event(e => { globalState += 1; e.waitUntil(timeout(10)); e.waitUntil(timeout(20).then(() => globalState++)); // multiple `waitUntil` are supported and awaited on - }); + })); await emitter.fireAsync({ foo: true }, CancellationToken.None).then(() => { assert.strictEqual(globalState, 3); @@ -601,11 +611,13 @@ suite('AsyncEmitter', function () { suite('PausableEmitter', function () { + const ds = ensureNoDisposablesAreLeakedInTestSuite(); + test('basic', function () { const data: number[] = []; - const emitter = new PauseableEmitter(); + const emitter = ds.add(new PauseableEmitter()); - emitter.event(e => data.push(e)); + ds.add(emitter.event(e => data.push(e))); emitter.fire(1); emitter.fire(2); @@ -614,9 +626,9 @@ suite('PausableEmitter', function () { test('pause/resume - no merge', function () { const data: number[] = []; - const emitter = new PauseableEmitter(); + const emitter = ds.add(new PauseableEmitter()); - emitter.event(e => data.push(e)); + ds.add(emitter.event(e => data.push(e))); emitter.fire(1); emitter.fire(2); assert.deepStrictEqual(data, [1, 2]); @@ -634,9 +646,9 @@ suite('PausableEmitter', function () { test('pause/resume - merge', function () { const data: number[] = []; - const emitter = new PauseableEmitter({ merge: (a) => a.reduce((p, c) => p + c, 0) }); + const emitter = ds.add(new PauseableEmitter({ merge: (a) => a.reduce((p, c) => p + c, 0) })); - emitter.event(e => data.push(e)); + ds.add(emitter.event(e => data.push(e))); emitter.fire(1); emitter.fire(2); assert.deepStrictEqual(data, [1, 2]); @@ -655,9 +667,9 @@ suite('PausableEmitter', function () { test('double pause/resume', function () { const data: number[] = []; - const emitter = new PauseableEmitter(); + const emitter = ds.add(new PauseableEmitter()); - emitter.event(e => data.push(e)); + ds.add(emitter.event(e => data.push(e))); emitter.fire(1); emitter.fire(2); assert.deepStrictEqual(data, [1, 2]); @@ -680,9 +692,9 @@ suite('PausableEmitter', function () { test('resume, no pause', function () { const data: number[] = []; - const emitter = new PauseableEmitter(); + const emitter = ds.add(new PauseableEmitter()); - emitter.event(e => data.push(e)); + ds.add(emitter.event(e => data.push(e))); emitter.fire(1); emitter.fire(2); assert.deepStrictEqual(data, [1, 2]); @@ -694,20 +706,20 @@ suite('PausableEmitter', function () { test('nested pause', function () { const data: number[] = []; - const emitter = new PauseableEmitter(); + const emitter = ds.add(new PauseableEmitter()); let once = true; - emitter.event(e => { + ds.add(emitter.event(e => { data.push(e); if (once) { emitter.pause(); once = false; } - }); - emitter.event(e => { + })); + ds.add(emitter.event(e => { data.push(e); - }); + })); emitter.pause(); emitter.fire(1); @@ -727,8 +739,8 @@ suite('PausableEmitter', function () { test('empty pause with merge', function () { const data: number[] = []; - const emitter = new PauseableEmitter({ merge: a => a[0] }); - emitter.event(e => data.push(1)); + const emitter = ds.add(new PauseableEmitter({ merge: a => a[0] })); + ds.add(emitter.event(e => data.push(1))); emitter.pause(); emitter.resume(); @@ -766,12 +778,14 @@ suite('Event utils - ensureNoDisposablesAreLeakedInTestSuite', function () { suite('Event utils', () => { + const ds = ensureNoDisposablesAreLeakedInTestSuite(); + suite('EventBufferer', () => { test('should not buffer when not wrapped', () => { const bufferer = new EventBufferer(); const counter = new Samples.EventCounter(); - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const event = bufferer.wrapEvent(emitter.event); const listener = event(counter.onEvent, counter); @@ -789,7 +803,7 @@ suite('Event utils', () => { test('should buffer when wrapped', () => { const bufferer = new EventBufferer(); const counter = new Samples.EventCounter(); - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const event = bufferer.wrapEvent(emitter.event); const listener = event(counter.onEvent, counter); @@ -812,7 +826,7 @@ suite('Event utils', () => { }); test('once', () => { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); let counter1 = 0, counter2 = 0, counter3 = 0; @@ -844,7 +858,7 @@ suite('Event utils', () => { test('should buffer events', () => { const result: number[] = []; - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const event = emitter.event; const bufferedEvent = Event.buffer(event); @@ -866,7 +880,7 @@ suite('Event utils', () => { test('should buffer events on next tick', async () => { const result: number[] = []; - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const event = emitter.event; const bufferedEvent = Event.buffer(event, true); @@ -888,7 +902,7 @@ suite('Event utils', () => { test('should fire initial buffer events', () => { const result: number[] = []; - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const event = emitter.event; const bufferedEvent = Event.buffer(event, false, [-2, -1, 0]); @@ -897,7 +911,7 @@ suite('Event utils', () => { emitter.fire(3); assert.deepStrictEqual(result, [] as number[]); - bufferedEvent(num => result.push(num)); + ds.add(bufferedEvent(num => result.push(num))); assert.deepStrictEqual(result, [-2, -1, 0, 1, 2, 3]); }); }); @@ -907,10 +921,10 @@ suite('Event utils', () => { test('works', () => { const result: number[] = []; const m = new EventMultiplexer(); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); - const e1 = new Emitter(); - m.add(e1.event); + const e1 = ds.add(new Emitter()); + ds.add(m.add(e1.event)); assert.deepStrictEqual(result, []); @@ -921,10 +935,10 @@ suite('Event utils', () => { test('multiplexer dispose works', () => { const result: number[] = []; const m = new EventMultiplexer(); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); - const e1 = new Emitter(); - m.add(e1.event); + const e1 = ds.add(new Emitter()); + ds.add(m.add(e1.event)); assert.deepStrictEqual(result, []); @@ -941,10 +955,10 @@ suite('Event utils', () => { test('event dispose works', () => { const result: number[] = []; const m = new EventMultiplexer(); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); - const e1 = new Emitter(); - m.add(e1.event); + const e1 = ds.add(new Emitter()); + ds.add(m.add(e1.event)); assert.deepStrictEqual(result, []); @@ -961,9 +975,9 @@ suite('Event utils', () => { test('mutliplexer event dispose works', () => { const result: number[] = []; const m = new EventMultiplexer(); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); - const e1 = new Emitter(); + const e1 = ds.add(new Emitter()); const l1 = m.add(e1.event); assert.deepStrictEqual(result, []); @@ -981,14 +995,14 @@ suite('Event utils', () => { test('hot start works', () => { const result: number[] = []; const m = new EventMultiplexer(); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); - const e1 = new Emitter(); - m.add(e1.event); - const e2 = new Emitter(); - m.add(e2.event); - const e3 = new Emitter(); - m.add(e3.event); + const e1 = ds.add(new Emitter()); + ds.add(m.add(e1.event)); + const e2 = ds.add(new Emitter()); + ds.add(m.add(e2.event)); + const e3 = ds.add(new Emitter()); + ds.add(m.add(e3.event)); e1.fire(1); e2.fire(2); @@ -1000,14 +1014,14 @@ suite('Event utils', () => { const result: number[] = []; const m = new EventMultiplexer(); - const e1 = new Emitter(); - m.add(e1.event); - const e2 = new Emitter(); - m.add(e2.event); - const e3 = new Emitter(); - m.add(e3.event); + const e1 = ds.add(new Emitter()); + ds.add(m.add(e1.event)); + const e2 = ds.add(new Emitter()); + ds.add(m.add(e2.event)); + const e3 = ds.add(new Emitter()); + ds.add(m.add(e3.event)); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); e1.fire(1); e2.fire(2); @@ -1019,18 +1033,18 @@ suite('Event utils', () => { const result: number[] = []; const m = new EventMultiplexer(); - const e1 = new Emitter(); - m.add(e1.event); - const e2 = new Emitter(); - m.add(e2.event); + const e1 = ds.add(new Emitter()); + ds.add(m.add(e1.event)); + const e2 = ds.add(new Emitter()); + ds.add(m.add(e2.event)); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); e1.fire(1); e2.fire(2); - const e3 = new Emitter(); - m.add(e3.event); + const e3 = ds.add(new Emitter()); + ds.add(m.add(e3.event)); e3.fire(3); assert.deepStrictEqual(result, [1, 2, 3]); @@ -1040,17 +1054,17 @@ suite('Event utils', () => { const result: number[] = []; const m = new EventMultiplexer(); - const e1 = new Emitter(); - m.add(e1.event); - const e2 = new Emitter(); - m.add(e2.event); + const e1 = ds.add(new Emitter()); + ds.add(m.add(e1.event)); + const e2 = ds.add(new Emitter()); + ds.add(m.add(e2.event)); - m.event(r => result.push(r)); + ds.add(m.event(r => result.push(r))); e1.fire(1); e2.fire(2); - const e3 = new Emitter(); + const e3 = ds.add(new Emitter()); const l3 = m.add(e3.event); e3.fire(3); assert.deepStrictEqual(result, [1, 2, 3]); @@ -1066,22 +1080,24 @@ suite('Event utils', () => { }); suite('DynamicListEventMultiplexer', () => { + let addEmitter: Emitter; + let removeEmitter: Emitter; const recordedEvents: number[] = []; - const addEmitter = new Emitter(); - const removeEmitter = new Emitter(); class TestItem { - readonly onTestEventEmitter = new Emitter(); + readonly onTestEventEmitter = ds.add(new Emitter()); readonly onTestEvent = this.onTestEventEmitter.event; } let items: TestItem[]; let m: DynamicListEventMultiplexer; setup(() => { + addEmitter = ds.add(new Emitter()); + removeEmitter = ds.add(new Emitter()); items = [new TestItem(), new TestItem()]; for (const [i, item] of items.entries()) { - item.onTestEvent(e => `${i}:${e}`); + ds.add(item.onTestEvent(e => `${i}:${e}`)); } m = new DynamicListEventMultiplexer(items, addEmitter.event, removeEmitter.event, e => e.onTestEvent); - m.event(e => recordedEvents.push(e)); + ds.add(m.event(e => recordedEvents.push(e))); recordedEvents.length = 0; }); teardown(() => m.dispose()); @@ -1112,11 +1128,11 @@ suite('Event utils', () => { }); test('latch', () => { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const event = Event.latch(emitter.event); const result: number[] = []; - const listener = event(num => result.push(num)); + const listener = ds.add(event(num => result.push(num))); assert.deepStrictEqual(result, []); @@ -1148,11 +1164,11 @@ suite('Event utils', () => { }); test('dispose is reentrant', () => { - const emitter = new Emitter({ + const emitter = ds.add(new Emitter({ onDidRemoveLastListener: () => { emitter.dispose(); } - }); + })); const listener = emitter.event(() => undefined); listener.dispose(); // should not crash @@ -1164,17 +1180,17 @@ suite('Event utils', () => { return new Promise(resolve => { let promise = new DeferredPromise(); - Event.fromPromise(promise.p)(e => { + ds.add(Event.fromPromise(promise.p)(e => { assert.strictEqual(e, 1); promise = new DeferredPromise(); - Event.fromPromise(promise.p)(() => { + ds.add(Event.fromPromise(promise.p)(() => { resolve(); - }); + })); promise.error(undefined); - }); + })); promise.complete(1); }); @@ -1185,16 +1201,16 @@ suite('Event utils', () => { let promise = new DeferredPromise(); promise.complete(1); - Event.fromPromise(promise.p)(e => { + ds.add(Event.fromPromise(promise.p)(e => { assert.strictEqual(e, 1); promise = new DeferredPromise(); promise.error(undefined); - Event.fromPromise(promise.p)(() => { + ds.add(Event.fromPromise(promise.p)(() => { resolve(); - }); - }); + })); + })); }); }); @@ -1202,8 +1218,8 @@ suite('Event utils', () => { suite('Relay', () => { test('should input work', () => { - const e1 = new Emitter(); - const e2 = new Emitter(); + const e1 = ds.add(new Emitter()); + const e2 = ds.add(new Emitter()); const relay = new Relay(); const result: number[] = []; @@ -1229,13 +1245,13 @@ suite('Event utils', () => { }); test('should Relay dispose work', () => { - const e1 = new Emitter(); - const e2 = new Emitter(); + const e1 = ds.add(new Emitter()); + const e2 = ds.add(new Emitter()); const relay = new Relay(); const result: number[] = []; const listener = (num: number) => result.push(num); - relay.event(listener); + ds.add(relay.event(listener)); e1.fire(1); assert.deepStrictEqual(result, []); @@ -1257,7 +1273,7 @@ suite('Event utils', () => { }); test('runAndSubscribeWithStore', () => { - const eventEmitter = new Emitter(); + const eventEmitter = ds.add(new Emitter()); const event = eventEmitter.event; let i = 0; @@ -1288,14 +1304,14 @@ suite('Event utils', () => { suite('accumulate', () => { test('should not fire after a listener is disposed with undefined or []', async () => { - const eventEmitter = new Emitter(); + const eventEmitter = ds.add(new Emitter()); const event = eventEmitter.event; const accumulated = Event.accumulate(event, 0); const calls1: number[][] = []; const calls2: number[][] = []; - const listener1 = accumulated((e) => calls1.push(e)); - accumulated((e) => calls2.push(e)); + const listener1 = ds.add(accumulated((e) => calls1.push(e))); + ds.add(accumulated((e) => calls2.push(e))); eventEmitter.fire(1); await timeout(1); @@ -1308,29 +1324,29 @@ suite('Event utils', () => { assert.deepStrictEqual(calls2, [[1]], 'should not fire after a listener is disposed with undefined or []'); }); test('should accumulate a single event', async () => { - const eventEmitter = new Emitter(); + const eventEmitter = ds.add(new Emitter()); const event = eventEmitter.event; const accumulated = Event.accumulate(event, 0); const results1 = await new Promise(r => { - accumulated(r); + ds.add(accumulated(r)); eventEmitter.fire(1); }); assert.deepStrictEqual(results1, [1]); const results2 = await new Promise(r => { - accumulated(r); + ds.add(accumulated(r)); eventEmitter.fire(2); }); assert.deepStrictEqual(results2, [2]); }); test('should accumulate multiple events', async () => { - const eventEmitter = new Emitter(); + const eventEmitter = ds.add(new Emitter()); const event = eventEmitter.event; const accumulated = Event.accumulate(event, 0); const results1 = await new Promise(r => { - accumulated(r); + ds.add(accumulated(r)); eventEmitter.fire(1); eventEmitter.fire(2); eventEmitter.fire(3); @@ -1338,7 +1354,7 @@ suite('Event utils', () => { assert.deepStrictEqual(results1, [1, 2, 3]); const results2 = await new Promise(r => { - accumulated(r); + ds.add(accumulated(r)); eventEmitter.fire(4); eventEmitter.fire(5); eventEmitter.fire(6); @@ -1351,7 +1367,7 @@ suite('Event utils', () => { suite('debounce', () => { test('simple', function (done: () => void) { - const doc = new Samples.Document3(); + const doc = ds.add(new Samples.Document3()); const onDocDidChange = Event.debounce(doc.onDidChange, (prev: string[] | undefined, cur) => { if (!prev) { @@ -1364,7 +1380,7 @@ suite('Event utils', () => { let count = 0; - onDocDidChange(keys => { + ds.add(onDocDidChange(keys => { count++; assert.ok(keys, 'was not expecting keys.'); if (count === 1) { @@ -1374,7 +1390,7 @@ suite('Event utils', () => { assert.deepStrictEqual(keys, ['4']); done(); } - }); + })); doc.setText('1'); doc.setText('2'); @@ -1383,7 +1399,7 @@ suite('Event utils', () => { test('microtask', function (done: () => void) { - const doc = new Samples.Document3(); + const doc = ds.add(new Samples.Document3()); const onDocDidChange = Event.debounce(doc.onDidChange, (prev: string[] | undefined, cur) => { if (!prev) { @@ -1396,7 +1412,7 @@ suite('Event utils', () => { let count = 0; - onDocDidChange(keys => { + ds.add(onDocDidChange(keys => { count++; assert.ok(keys, 'was not expecting keys.'); if (count === 1) { @@ -1406,7 +1422,7 @@ suite('Event utils', () => { assert.deepStrictEqual(keys, ['4']); done(); } - }); + })); doc.setText('1'); doc.setText('2'); @@ -1415,13 +1431,13 @@ suite('Event utils', () => { test('leading', async function () { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true); let calls = 0; - debounced(() => { + ds.add(debounced(() => { calls++; - }); + })); // If the source event is fired once, the debounced (on the leading edge) event should be fired only once emitter.fire(); @@ -1431,13 +1447,13 @@ suite('Event utils', () => { }); test('leading (2)', async function () { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true); let calls = 0; - debounced(() => { + ds.add(debounced(() => { calls++; - }); + })); // If the source event is fired multiple times, the debounced (on the leading edge) event should be fired twice emitter.fire(); @@ -1448,11 +1464,11 @@ suite('Event utils', () => { }); test('leading reset', async function () { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const debounced = Event.debounce(emitter.event, (l, e) => l ? l + 1 : 1, 0, /*leading=*/true); const calls: number[] = []; - debounced((e) => calls.push(e)); + ds.add(debounced((e) => calls.push(e))); emitter.fire(1); emitter.fire(1); @@ -1462,11 +1478,11 @@ suite('Event utils', () => { }); test('should not flush events when a listener is disposed', async () => { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const debounced = Event.debounce(emitter.event, (l, e) => l ? l + 1 : 1, 0); const calls: number[] = []; - const listener = debounced((e) => calls.push(e)); + const listener = ds.add(debounced((e) => calls.push(e))); emitter.fire(1); listener.dispose(); @@ -1478,11 +1494,11 @@ suite('Event utils', () => { }); test('flushOnListenerRemove - should flush events when a listener is disposed', async () => { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const debounced = Event.debounce(emitter.event, (l, e) => l ? l + 1 : 1, 0, undefined, true); const calls: number[] = []; - const listener = debounced((e) => calls.push(e)); + const listener = ds.add(debounced((e) => calls.push(e))); emitter.fire(1); listener.dispose(); @@ -1494,11 +1510,11 @@ suite('Event utils', () => { }); test('should flush events when the emitter is disposed', async () => { - const emitter = new Emitter(); + const emitter = ds.add(new Emitter()); const debounced = Event.debounce(emitter.event, (l, e) => l ? l + 1 : 1, 0); const calls: number[] = []; - debounced((e) => calls.push(e)); + ds.add(debounced((e) => calls.push(e))); emitter.fire(1); emitter.dispose(); @@ -1509,26 +1525,17 @@ suite('Event utils', () => { }); suite('chain2', () => { - let store: DisposableStore; let em: Emitter; let calls: number[]; - teardown(() => { - store.dispose(); - }); - - ensureNoDisposablesAreLeakedInTestSuite(); - setup(() => { - store = new DisposableStore(); - em = new Emitter(); - store.add(em); + em = ds.add(new Emitter()); calls = []; }); test('maps', () => { const ev = Event.chain(em.event, $ => $.map(v => v * 2)); - store.add(ev(v => calls.push(v))); + ds.add(ev(v => calls.push(v))); em.fire(1); em.fire(2); em.fire(3); @@ -1537,7 +1544,7 @@ suite('Event utils', () => { test('filters', () => { const ev = Event.chain(em.event, $ => $.filter(v => v % 2 === 0)); - store.add(ev(v => calls.push(v))); + ds.add(ev(v => calls.push(v))); em.fire(1); em.fire(2); em.fire(3); @@ -1547,7 +1554,7 @@ suite('Event utils', () => { test('reduces', () => { const ev = Event.chain(em.event, $ => $.reduce((acc, v) => acc + v, 0)); - store.add(ev(v => calls.push(v))); + ds.add(ev(v => calls.push(v))); em.fire(1); em.fire(2); em.fire(3); @@ -1557,7 +1564,7 @@ suite('Event utils', () => { test('latches', () => { const ev = Event.chain(em.event, $ => $.latch()); - store.add(ev(v => calls.push(v))); + ds.add(ev(v => calls.push(v))); em.fire(1); em.fire(1); em.fire(2); @@ -1576,7 +1583,7 @@ suite('Event utils', () => { .latch() ); - store.add(ev(v => calls.push(v))); + ds.add(ev(v => calls.push(v))); em.fire(1); em.fire(2); em.fire(3); diff --git a/src/vs/base/test/common/history.test.ts b/src/vs/base/test/common/history.test.ts index eae79bb5afa..39143609b88 100644 --- a/src/vs/base/test/common/history.test.ts +++ b/src/vs/base/test/common/history.test.ts @@ -184,6 +184,8 @@ suite('History Navigator', () => { suite('History Navigator 2', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('constructor', () => { const testObject = new HistoryNavigator2(['1', '2', '3', '4']); diff --git a/src/vs/base/test/common/lifecycle.test.ts b/src/vs/base/test/common/lifecycle.test.ts index 22e8ff77e0f..103009b5219 100644 --- a/src/vs/base/test/common/lifecycle.test.ts +++ b/src/vs/base/test/common/lifecycle.test.ts @@ -13,8 +13,9 @@ class Disposable implements IDisposable { dispose() { this.isDisposed = true; } } +// Leaks are allowed here since we test lifecycle stuff: +// eslint-disable-next-line local/code-ensure-no-disposables-leak-in-test suite('Lifecycle', () => { - test('dispose single disposable', () => { const disposable = new Disposable(); @@ -129,6 +130,8 @@ suite('Lifecycle', () => { }); suite('DisposableStore', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('dispose should call all child disposes even if a child throws on dispose', () => { const disposedValues = new Set(); @@ -221,6 +224,8 @@ suite('DisposableStore', () => { }); suite('Reference Collection', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + class Collection extends ReferenceCollection { private _count = 0; get count() { return this._count; } diff --git a/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts b/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts index 9d36f7ebfd8..64de23fce27 100644 --- a/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts +++ b/src/vs/editor/contrib/multicursor/test/browser/multicursor.test.ts @@ -83,6 +83,8 @@ function fromRange(rng: Range): number[] { } suite('Multicursor selection', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + const serviceCollection = new ServiceCollection(); serviceCollection.set(IStorageService, new InMemoryStorageService()); diff --git a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts index 8994ead0bf4..9e72c1c174a 100644 --- a/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts +++ b/src/vs/platform/extensionManagement/test/node/extensionsScannerService.test.ts @@ -348,6 +348,8 @@ suite('NativeExtensionsScanerService Test', () => { suite('ExtensionScannerInput', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('compare inputs - location', () => { const anInput = (location: URI, mtime: number | undefined) => new ExtensionScannerInput(location, mtime, undefined, undefined, false, undefined, ExtensionType.User, true, true, '1.1.1', undefined, undefined, true, undefined, {}); diff --git a/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts b/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts index ef65f7c57e5..eeeb2486c46 100644 --- a/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts +++ b/src/vs/platform/userData/test/browser/fileUserDataProvider.test.ts @@ -4,25 +4,25 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { IFileService, FileChangeType, IFileChange, IFileSystemProviderWithFileReadWriteCapability, IStat, FileType, FileSystemProviderCapabilities, IFileSystemProviderWithOpenReadWriteCloseCapability, IFileOpenOptions, IFileSystemProviderWithFileReadStreamCapability, IFileReadStreamOptions } from 'vs/platform/files/common/files'; -import { FileService } from 'vs/platform/files/common/fileService'; -import { NullLogService } from 'vs/platform/log/common/log'; -import { Schemas } from 'vs/base/common/network'; -import { URI } from 'vs/base/common/uri'; -import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; -import { dirname, isEqual, joinPath } from 'vs/base/common/resources'; import { VSBuffer } from 'vs/base/common/buffer'; -import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle'; -import { Emitter, Event } from 'vs/base/common/event'; -import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; -import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common/environmentService'; -import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import product from 'vs/platform/product/common/product'; -import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { CancellationToken } from 'vs/base/common/cancellation'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { Schemas } from 'vs/base/common/network'; +import { dirname, isEqual, joinPath } from 'vs/base/common/resources'; import { ReadableStreamEvents } from 'vs/base/common/stream'; +import { URI } from 'vs/base/common/uri'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { AbstractNativeEnvironmentService } from 'vs/platform/environment/common/environmentService'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { FileChangeType, FileSystemProviderCapabilities, FileType, IFileChange, IFileOpenOptions, IFileReadStreamOptions, IFileService, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, IStat } from 'vs/platform/files/common/files'; +import { InMemoryFileSystemProvider } from 'vs/platform/files/common/inMemoryFilesystemProvider'; +import { NullLogService } from 'vs/platform/log/common/log'; +import product from 'vs/platform/product/common/product'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; +import { FileUserDataProvider } from 'vs/platform/userData/common/fileUserDataProvider'; +import { IUserDataProfilesService, UserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; const ROOT = URI.file('tests').with({ scheme: 'vscode-tests' }); @@ -315,7 +315,7 @@ class TestFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapa suite('FileUserDataProvider - Watching', () => { let testObject: FileUserDataProvider; - const disposables = new DisposableStore(); + const disposables = ensureNoDisposablesAreLeakedInTestSuite(); const rootFileResource = joinPath(ROOT, 'User'); const rootUserDataResource = rootFileResource.with({ scheme: Schemas.vscodeUserData }); @@ -332,8 +332,6 @@ suite('FileUserDataProvider - Watching', () => { testObject = disposables.add(new FileUserDataProvider(rootFileResource.scheme, new TestFileSystemProvider(fileEventEmitter.event), Schemas.vscodeUserData, userDataProfilesService, uriIdentityService, new NullLogService())); }); - teardown(() => disposables.clear()); - test('file added change event', done => { disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false })); const expected = joinPath(rootUserDataResource, 'settings.json'); @@ -427,7 +425,7 @@ suite('FileUserDataProvider - Watching', () => { test('event is not triggered if not watched', async () => { const target = joinPath(rootFileResource, 'settings.json'); let triggered = false; - testObject.onDidChangeFile(() => triggered = true); + disposables.add(testObject.onDidChangeFile(() => triggered = true)); fileEventEmitter.fire([{ resource: target, type: FileChangeType.DELETED @@ -441,7 +439,7 @@ suite('FileUserDataProvider - Watching', () => { disposables.add(testObject.watch(rootUserDataResource, { excludes: [], recursive: false })); const target = joinPath(dirname(rootFileResource), 'settings.json'); let triggered = false; - testObject.onDidChangeFile(() => triggered = true); + disposables.add(testObject.onDidChangeFile(() => triggered = true)); fileEventEmitter.fire([{ resource: target, type: FileChangeType.DELETED diff --git a/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts b/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts index bc90fb28b24..db83d62e163 100644 --- a/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts +++ b/src/vs/platform/userDataSync/test/common/userDataSyncStoreService.test.ts @@ -417,6 +417,9 @@ suite('UserDataSyncRequestsSession', () => { async loadCertificates() { return []; } }; + + ensureNoDisposablesAreLeakedInTestSuite(); + test('too many requests are thrown when limit exceeded', async () => { const testObject = new RequestsSession(1, 500, requestService, new NullLogService()); await testObject.request('url', {}, CancellationToken.None); diff --git a/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts b/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts index b8912834f80..3f60f5ef898 100644 --- a/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts +++ b/src/vs/workbench/api/test/browser/extHostDocumentData.test.ts @@ -441,6 +441,8 @@ suite('ExtHostDocumentData updates line mapping', () => { testLineMappingDirectionAfterEvents(lines, '\r\n', AssertDocumentLineMappingDirection.OffsetToPosition, e); } + ensureNoDisposablesAreLeakedInTestSuite(); + test('line mapping', () => { testLineMappingAfterEvents([ 'This is line one', diff --git a/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts b/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts index 33f0e1d0a06..60197332945 100644 --- a/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts +++ b/src/vs/workbench/contrib/chat/test/common/chatModel.test.ts @@ -122,6 +122,8 @@ suite('ChatModel', () => { }); suite('Response', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('content, markdown', async () => { const response = new Response([]); response.updateContent({ content: 'text', kind: 'content' }); diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts index 83d0164b035..476c7aa5327 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookCommon.test.ts @@ -305,6 +305,8 @@ suite('NotebookCommon', () => { suite('CellUri', function () { + ensureNoDisposablesAreLeakedInTestSuite(); + test('parse, generate (file-scheme)', function () { const nb = URI.parse('file:///bar/følder/file.nb'); @@ -348,6 +350,8 @@ suite('CellUri', function () { suite('CellRange', function () { + ensureNoDisposablesAreLeakedInTestSuite(); + test('Cell range to index', function () { assert.deepStrictEqual(cellRangesToIndexes([]), []); assert.deepStrictEqual(cellRangesToIndexes([{ start: 0, end: 0 }]), []); @@ -398,6 +402,7 @@ suite('CellRange', function () { }); suite('NotebookWorkingCopyTypeIdentifier', function () { + ensureNoDisposablesAreLeakedInTestSuite(); test('works', function () { const viewType = 'testViewType'; diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookSelection.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookSelection.test.ts index b1aa61118fd..a45fd46828f 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookSelection.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookSelection.test.ts @@ -15,12 +15,15 @@ import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/uti import { DisposableStore } from 'vs/base/common/lifecycle'; suite('NotebookSelection', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('focus is never empty', function () { const selectionCollection = new NotebookCellSelectionCollection(); assert.deepStrictEqual(selectionCollection.focus, { start: 0, end: 0 }); selectionCollection.setState(null, [], true, 'model'); assert.deepStrictEqual(selectionCollection.focus, { start: 0, end: 0 }); + selectionCollection.dispose(); }); }); diff --git a/src/vs/workbench/services/label/test/browser/label.test.ts b/src/vs/workbench/services/label/test/browser/label.test.ts index 520ed89e35d..f5098c5df72 100644 --- a/src/vs/workbench/services/label/test/browser/label.test.ts +++ b/src/vs/workbench/services/label/test/browser/label.test.ts @@ -28,6 +28,8 @@ suite('URI Label', () => { labelService = new LabelService(TestEnvironmentService, new TestContextService(), new TestPathService(URI.file('/foobar')), new TestRemoteAgentService(), storageService, new TestLifecycleService()); }); + ensureNoDisposablesAreLeakedInTestSuite(); + test('custom scheme', function () { labelService.registerFormatter({ scheme: 'vscode', From 6605df0f116425196f2ebfb77bdb6557bd9fa946 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 5 Dec 2023 14:54:52 -0800 Subject: [PATCH 25/37] debug: fix toolbar min y position (#200090) This was inverted a couple iterations ago during a refactor it looks like. Fixes #200005 --- src/vs/workbench/contrib/debug/browser/debugToolBar.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts index b9327dbdced..88e597e76be 100644 --- a/src/vs/workbench/contrib/debug/browser/debugToolBar.ts +++ b/src/vs/workbench/contrib/debug/browser/debugToolBar.ts @@ -281,7 +281,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution { private get yRange(): [number, number] { if (!this._yRange) { const isTitleBarVisible = this.layoutService.isVisible(Parts.TITLEBAR_PART, dom.getWindow(this.layoutService.activeContainer)); - const yMin = isTitleBarVisible ? 0 : this.layoutService.mainContainerOffset.top; + const yMin = isTitleBarVisible ? this.layoutService.mainContainerOffset.top : 0; let yMax = 0; if (isTitleBarVisible) { From 2ee5518dec8d675ca9f5a74147eb7a222a8dab71 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 5 Dec 2023 15:21:08 -0800 Subject: [PATCH 26/37] debug: fix incomplete range in disassembly goToInstructionAndOffset (#200093) Fixes #197770 --- src/vs/workbench/contrib/debug/browser/disassemblyView.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/debug/browser/disassemblyView.ts b/src/vs/workbench/contrib/debug/browser/disassemblyView.ts index cfef6373c3e..618aa8994d8 100644 --- a/src/vs/workbench/contrib/debug/browser/disassemblyView.ts +++ b/src/vs/workbench/contrib/debug/browser/disassemblyView.ts @@ -339,7 +339,7 @@ export class DisassemblyView extends EditorPane { async goToInstructionAndOffset(instructionReference: string, offset: number, focus?: boolean) { let addr = this._referenceToMemoryAddress.get(instructionReference); if (addr === undefined) { - await this.loadDisassembledInstructions(instructionReference, 0, -DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD, DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD); + await this.loadDisassembledInstructions(instructionReference, 0, -DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD, DisassemblyView.NUM_INSTRUCTIONS_TO_LOAD * 2); addr = this._referenceToMemoryAddress.get(instructionReference); } From 42b9e864678e6d0250edaa7c25c17e1cdf3d04bf Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Tue, 5 Dec 2023 15:34:58 -0800 Subject: [PATCH 27/37] Add quick-chat to grooming notebook (#200094) --- .vscode/notebooks/grooming.github-issues | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.vscode/notebooks/grooming.github-issues b/.vscode/notebooks/grooming.github-issues index cb32618ede6..ed6b0552fa5 100644 --- a/.vscode/notebooks/grooming.github-issues +++ b/.vscode/notebooks/grooming.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "// list of repos we work in\r\n$repos=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\r\n" + "value": "// list of repos we work in\n$repos=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n" }, { "kind": 1, @@ -17,7 +17,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos assignee:@me is:open type:issue -label:bug -label:\"info-needed\" -label:feature-request -label:under-discussion -label:debt -label:plan-item -label:upstream -label:polish -label:testplan-item -label:error-telemetry -label:engineering -label:endgame-plan\r\n" + "value": "$repos assignee:@me is:open type:issue -label:bug -label:\"info-needed\" -label:feature-request -label:under-discussion -label:debt -label:plan-item -label:upstream -label:polish -label:testplan-item -label:error-telemetry -label:engineering -label:endgame-plan\n" }, { "kind": 1, @@ -27,7 +27,7 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode assignee:@me is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:cloud-changes -label:code-lens -label:command-center -label:comments -label:config -label:containers -label:context-keys -label:continue-working-on -label:css-less-scss -label:custom-editors -label:debug -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-widgets -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet -label:emmet-parse -label:error-list -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:html -label:icon-brand -label:icons-product -label:image-preview -label:inlay-hints -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:issue-bot -label:issue-reporter -label:javascript -label:json -label:keybindings -label:keybindings-editor -label:keyboard-layout -label:L10N -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:native-file-dialog -label:network -label:notebook -label:notebook-api -label:notebook-builtin-renderers -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-commenting -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-math -label:notebook-minimap -label:notebook-multiselect -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-rendering -label:notebook-serialization -label:notebook-serverless-web -label:notebook-statusbar -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-tabs -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:inline-chat -label:panel-chat -label:audio-cue -label:tasks -label:error-list -label:winget\r\n" + "value": "repo:microsoft/vscode assignee:@me is:open type:issue -label:\"info-needed\" -label:api -label:api-finalization -label:api-proposal -label:authentication -label:bisect-ext -label:bracket-pair-colorization -label:bracket-pair-guides -label:breadcrumbs -label:callhierarchy -label:chrome-devtools -label:cloud-changes -label:code-lens -label:command-center -label:comments -label:config -label:containers -label:context-keys -label:continue-working-on -label:css-less-scss -label:custom-editors -label:debug -label:debug-disassembly -label:dialogs -label:diff-editor -label:dropdown -label:editor-api -label:editor-autoclosing -label:editor-autoindent -label:editor-bracket-matching -label:editor-clipboard -label:editor-code-actions -label:editor-color-picker -label:editor-columnselect -label:editor-commands -label:editor-comments -label:editor-contrib -label:editor-core -label:editor-drag-and-drop -label:editor-error-widget -label:editor-find -label:editor-folding -label:editor-highlight -label:editor-hover -label:editor-indent-detection -label:editor-indent-guides -label:editor-input -label:editor-input-IME -label:editor-insets -label:editor-minimap -label:editor-multicursor -label:editor-parameter-hints -label:editor-render-whitespace -label:editor-rendering -label:editor-widgets -label:editor-RTL -label:editor-scrollbar -label:editor-sorting -label:editor-sticky-scroll -label:editor-symbols -label:editor-synced-region -label:editor-textbuffer -label:editor-theming -label:editor-wordnav -label:editor-wrapping -label:emmet -label:emmet-parse -label:error-list -label:extension-activation -label:extension-host -label:extension-prerelease -label:extension-recommendations -label:extensions -label:extensions-development -label:file-decorations -label:file-encoding -label:file-explorer -label:file-glob -label:file-io -label:file-nesting -label:file-watcher -label:font-rendering -label:formatting -label:getting-started -label:ghost-text -label:git -label:github -label:github-repositories -label:gpu -label:grammar -label:grid-widget -label:html -label:icon-brand -label:icons-product -label:image-preview -label:inlay-hints -label:inline-completions -label:install-update -label:intellisense-config -label:interactive-playground -label:interactive-window -label:issue-bot -label:issue-reporter -label:javascript -label:json -label:keybindings -label:keybindings-editor -label:keyboard-layout -label:L10N -label:l10n-platform -label:label-provider -label:languages-basic -label:languages-diagnostics -label:languages-guessing -label:layout -label:lcd-text-rendering -label:list-widget -label:live-preview -label:log -label:markdown -label:marketplace -label:menus -label:merge-conflict -label:merge-editor -label:merge-editor-workbench -label:monaco-editor -label:native-file-dialog -label:network -label:notebook -label:notebook-api -label:notebook-builtin-renderers -label:notebook-cell-editor -label:notebook-celltoolbar -label:notebook-clipboard -label:notebook-commenting -label:notebook-debugging -label:notebook-diff -label:notebook-dnd -label:notebook-execution -label:notebook-find -label:notebook-folding -label:notebook-getting-started -label:notebook-globaltoolbar -label:notebook-ipynb -label:notebook-kernel -label:notebook-kernel-picker -label:notebook-language -label:notebook-layout -label:notebook-markdown -label:notebook-math -label:notebook-minimap -label:notebook-multiselect -label:notebook-output -label:notebook-perf -label:notebook-remote -label:notebook-rendering -label:notebook-serialization -label:notebook-serverless-web -label:notebook-statusbar -label:notebook-toc-outline -label:notebook-undo-redo -label:notebook-variables -label:notebook-workbench-integration -label:notebook-workflow -label:open-editors -label:opener -label:outline -label:output -label:packaging -label:perf -label:perf-bloat -label:perf-startup -label:php -label:portable-mode -label:proxy -label:quick-open -label:quick-pick -label:references-viewlet -label:release-notes -label:remote -label:remote-connection -label:remote-explorer -label:remote-tunnel -label:rename -label:runCommands -label:sandbox -label:sash-widget -label:scm -label:screencast-mode -label:search -label:search-api -label:search-editor -label:search-replace -label:semantic-tokens -label:server -label:settings-editor -label:settings-sync -label:settings-sync-server -label:shared-process -label:simple-file-dialog -label:smart-select -label:snap -label:snippets -label:splitview-widget -label:ssh -label:suggest -label:table-widget -label:tasks -label:telemetry -label:terminal -label:terminal-accessibility -label:terminal-conpty -label:terminal-editors -label:terminal-external -label:terminal-find -label:terminal-input -label:terminal-layout -label:terminal-links -label:terminal-local-echo -label:terminal-persistence -label:terminal-process -label:terminal-profiles -label:terminal-quick-fix -label:terminal-rendering -label:terminal-shell-bash -label:terminal-shell-cmd -label:terminal-shell-fish -label:terminal-shell-git-bash -label:terminal-shell-integration -label:terminal-shell-pwsh -label:terminal-shell-zsh -label:terminal-tabs -label:testing -label:themes -label:timeline -label:timeline-git -label:timeline-local-history -label:titlebar -label:tokenization -label:touch/pointer -label:trackpad/scroll -label:tree-views -label:tree-widget -label:typescript -label:undo-redo -label:unicode-highlight -label:uri -label:user-profiles -label:ux -label:variable-resolving -label:VIM -label:virtual-workspaces -label:vscode-website -label:vscode.dev -label:web -label:webview -label:webview-views -label:workbench-actions -label:workbench-banner -label:workbench-cli -label:workbench-diagnostics -label:workbench-dnd -label:workbench-editor-grid -label:workbench-editor-groups -label:workbench-editor-resolver -label:workbench-editors -label:workbench-electron -label:workbench-fonts -label:workbench-history -label:workbench-hot-exit -label:workbench-hover -label:workbench-launch -label:workbench-link -label:workbench-multiroot -label:workbench-notifications -label:workbench-os-integration -label:workbench-rapid-render -label:workbench-run-as-admin -label:workbench-state -label:workbench-status -label:workbench-tabs -label:workbench-touchbar -label:workbench-untitled-editors -label:workbench-views -label:workbench-welcome -label:workbench-window -label:workbench-workspace -label:workbench-zen -label:workspace-edit -label:workspace-symbols -label:workspace-trust -label:zoom -label:inline-chat -label:panel-chat -label:quick-chat -label:audio-cue -label:tasks -label:error-list -label:winget\n" }, { "kind": 1, @@ -37,7 +37,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos assignee:@me is:open type:issue no:milestone -label:info-needed -label:triage-needed\r\n" + "value": "$repos assignee:@me is:open type:issue no:milestone -label:info-needed -label:triage-needed\n" }, { "kind": 1, @@ -47,6 +47,6 @@ { "kind": 2, "language": "github-issues", - "value": "$repos assignee:@me is:open label:\"info-needed\"\r\n" + "value": "$repos assignee:@me is:open label:\"info-needed\"\n" } ] \ No newline at end of file From 5196dddde0fcf73ec8334aab51cfb9b567824f6d Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Tue, 5 Dec 2023 21:53:40 -0800 Subject: [PATCH 28/37] Low hanging fruit of onboarding to `ensureNoDisposablesAreLeakedInTestSuite` (#200100) ref https://github.com/microsoft/vscode/issues/200091 --- .eslintrc.json | 3 --- src/vs/base/test/common/tfIdf.test.ts | 2 ++ src/vs/base/test/node/powershell.test.ts | 3 ++- .../workbench/contrib/url/test/browser/trustedDomains.test.ts | 3 +++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index d6d14e5d43b..73fa13c05ff 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -199,7 +199,6 @@ "src/vs/base/test/common/strings.test.ts", "src/vs/base/test/common/stripComments.test.ts", "src/vs/base/test/common/ternarySearchtree.test.ts", - "src/vs/base/test/common/tfIdf.test.ts", "src/vs/base/test/common/types.test.ts", "src/vs/base/test/common/uri.test.ts", "src/vs/base/test/common/uuid.test.ts", @@ -208,7 +207,6 @@ "src/vs/base/test/node/id.test.ts", "src/vs/base/test/node/nodeStreams.test.ts", "src/vs/base/test/node/port.test.ts", - "src/vs/base/test/node/powershell.test.ts", "src/vs/base/test/node/snapshot.test.ts", "src/vs/base/test/node/unc.test.ts", "src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts", @@ -319,7 +317,6 @@ "src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts", "src/vs/workbench/contrib/terminal/test/browser/terminalActions.test.ts", "src/vs/workbench/contrib/themes/test/node/colorRegistryExport.test.ts", - "src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts", "src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts", "src/vs/workbench/services/commands/test/common/commandService.test.ts", "src/vs/workbench/services/configuration/test/common/configurationModels.test.ts", diff --git a/src/vs/base/test/common/tfIdf.test.ts b/src/vs/base/test/common/tfIdf.test.ts index 69c094759eb..3a423f253a3 100644 --- a/src/vs/base/test/common/tfIdf.test.ts +++ b/src/vs/base/test/common/tfIdf.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { CancellationToken } from 'vs/base/common/cancellation'; import { TfIdfCalculator, TfIdfDocument, TfIdfScore } from 'vs/base/common/tfIdf'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; /** * Generates all permutations of an array. @@ -39,6 +40,7 @@ function assertScoreOrdersEqual(actualScores: TfIdfScore[], expectedScoreKeys: s } suite('TF-IDF Calculator', function () { + ensureNoDisposablesAreLeakedInTestSuite(); test('Should return no scores when no documents are given', () => { const tfidf = new TfIdfCalculator(); const scores = tfidf.calculateScores('something', CancellationToken.None); diff --git a/src/vs/base/test/node/powershell.test.ts b/src/vs/base/test/node/powershell.test.ts index a93a88fc746..a710bb80c46 100644 --- a/src/vs/base/test/node/powershell.test.ts +++ b/src/vs/base/test/node/powershell.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import * as fs from 'fs'; import * as platform from 'vs/base/common/platform'; import { enumeratePowerShellInstallations, getFirstAvailablePowerShellInstallation, IPowerShellExeDetails } from 'vs/base/node/powershell'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; function checkPath(exePath: string) { // Check to see if the path exists @@ -28,7 +29,7 @@ function checkPath(exePath: string) { if (platform.isWindows) { suite('PowerShell finder', () => { - + ensureNoDisposablesAreLeakedInTestSuite(); test('Can find first available PowerShell', async () => { const pwshExe = await getFirstAvailablePowerShellInstallation(); const exePath = pwshExe?.exePath; diff --git a/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts b/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts index 898f6af547d..2d34fee58f6 100644 --- a/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts +++ b/src/vs/workbench/contrib/url/test/browser/trustedDomains.test.ts @@ -8,6 +8,7 @@ import * as assert from 'assert'; import { isURLDomainTrusted } from 'vs/workbench/contrib/url/browser/trustedDomainsValidator'; import { URI } from 'vs/base/common/uri'; import { extractGitHubRemotesFromGitConfig } from 'vs/workbench/contrib/url/browser/trustedDomains'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; function linkAllowedByRules(link: string, rules: string[]) { assert.ok(isURLDomainTrusted(URI.parse(link), rules), `Link\n${link}\n should be allowed by rules\n${JSON.stringify(rules)}`); @@ -17,6 +18,7 @@ function linkNotAllowedByRules(link: string, rules: string[]) { } suite('GitHub remote extraction', () => { + ensureNoDisposablesAreLeakedInTestSuite(); test('All known formats', () => { assert.deepStrictEqual( extractGitHubRemotesFromGitConfig( @@ -39,6 +41,7 @@ suite('GitHub remote extraction', () => { }); suite('Link protection domain matching', () => { + ensureNoDisposablesAreLeakedInTestSuite(); test('simple', () => { linkNotAllowedByRules('https://x.org', []); From 38267ff79727a6d220b2435fd919c50420e29c3e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 6 Dec 2023 11:08:16 +0100 Subject: [PATCH 29/37] Add the option to skip the prompt to save the workspace config (fix #187794) (#200114) * wip * . * . --- .../mainThreadFileSystemEventService.ts | 2 +- .../browser/mergeEditorInputModel.ts | 2 +- .../electron-sandbox/desktop.contribution.ts | 5 +++++ .../extensions/browser/extensionUrlHandler.ts | 2 +- .../abstractWorkspaceEditingService.ts | 2 +- .../workspaceEditingService.ts | 22 +++++++++++++++++-- 6 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts index cefca23c785..c6bea307e34 100644 --- a/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts +++ b/src/vs/workbench/api/browser/mainThreadFileSystemEventService.ts @@ -168,7 +168,7 @@ export class MainThreadFileSystemEventService implements MainThreadFileSystemEve label: localize('cancel', "Skip Changes"), run: () => Choice.Cancel }, - checkbox: { label: localize('again', "Don't ask again") } + checkbox: { label: localize('again', "Do not ask me again") } }); if (result === Choice.Cancel) { // no changes wanted, don't persist cancel option diff --git a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts index 9b3f245a2dd..b043f0840a1 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInputModel.ts @@ -473,7 +473,7 @@ class WorkspaceMergeEditorInputModel extends EditorModel implements IMergeEditor primaryButton: someUnhandledConflicts ? localize({ key: 'workspace.closeWithConflicts', comment: ['&& denotes a mnemonic'] }, '&&Close with Conflicts') : localize({ key: 'workspace.close', comment: ['&& denotes a mnemonic'] }, '&&Close'), - checkbox: { label: localize('noMoreWarn', "Don't ask again") } + checkbox: { label: localize('noMoreWarn', "Do not ask me again") } }); if (checkboxChecked) { diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index f904efaafae..4a7fe629e12 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -151,6 +151,11 @@ import { applicationConfigurationNodeBase, securityConfigurationNodeBase } from 'title': localize('windowConfigurationTitle', "Window"), 'type': 'object', 'properties': { + 'window.confirmSaveUntitledWorkspace': { + 'type': 'boolean', + 'default': true, + 'description': localize('confirmSaveUntitledWorkspace', "Controls whether a confirmation dialog shows asking to save or discard an opened untitled workspace in the window when switching to another workspace."), + }, 'window.openWithoutArgumentsInNewWindow': { 'type': 'string', 'enum': ['on', 'off'], diff --git a/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts b/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts index e3c810e97a2..db455b09007 100644 --- a/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts +++ b/src/vs/workbench/services/extensions/browser/extensionUrlHandler.ts @@ -180,7 +180,7 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler { const result = await this.dialogService.confirm({ message: localize('confirmUrl', "Allow '{0}' extension to open this URI?", extensionDisplayName), checkbox: { - label: localize('rememberConfirmUrl', "Don't ask again for this extension."), + label: localize('rememberConfirmUrl', "Do not ask me again for this extension"), }, detail: uriString, primaryButton: localize({ key: 'open', comment: ['&& denotes a mnemonic'] }, "&&Open") diff --git a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts b/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts index 4653e395be9..21312c7e76c 100644 --- a/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts +++ b/src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts @@ -37,7 +37,7 @@ export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditi constructor( @IJSONEditingService private readonly jsonEditingService: IJSONEditingService, @IWorkspaceContextService protected readonly contextService: WorkspaceService, - @IWorkbenchConfigurationService private readonly configurationService: IWorkbenchConfigurationService, + @IWorkbenchConfigurationService protected readonly configurationService: IWorkbenchConfigurationService, @INotificationService private readonly notificationService: INotificationService, @ICommandService private readonly commandService: ICommandService, @IFileService private readonly fileService: IFileService, diff --git a/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts b/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts index ad00669d146..63dd1b18ad3 100644 --- a/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts +++ b/src/vs/workbench/services/workspaces/electron-sandbox/workspaceEditingService.ts @@ -33,6 +33,7 @@ import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/w import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile'; +import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration'; export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingService { @@ -87,7 +88,13 @@ export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingServi return false; // Windows/Linux: quits when last window is closed, so do not ask then } - const { result } = await this.dialogService.prompt({ + const confirmSaveUntitledWorkspace = this.configurationService.getValue('window.confirmSaveUntitledWorkspace') !== false; + if (!confirmSaveUntitledWorkspace) { + return false; // no confirmation configured + } + + let canceled = false; + const { result, checkboxChecked } = await this.dialogService.prompt({ type: Severity.Warning, message: localize('saveWorkspaceMessage', "Do you want to save your workspace configuration as a file?"), detail: localize('saveWorkspaceDetail', "Save your workspace if you plan to open it again."), @@ -130,10 +137,21 @@ export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingServi } ], cancelButton: { - run: () => true // veto + run: () => { + canceled = true; + + return true; // veto + } + }, + checkbox: { + label: localize('doNotAskAgain', "Do not ask me again") } }); + if (!canceled && checkboxChecked) { + await this.configurationService.updateValue('window.confirmSaveUntitledWorkspace', false, ConfigurationTarget.USER); + } + return result; } From 4693a093c7ea89f073e571155b234178b059d32a Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Wed, 6 Dec 2023 02:13:08 -0800 Subject: [PATCH 30/37] Revert: Allow non-AI actions on empty lines (#200097) reverting ai only code actions on empty lines --- src/vs/editor/contrib/codeAction/common/types.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/common/types.ts b/src/vs/editor/contrib/codeAction/common/types.ts index 4f0d8e0f171..f0f753f38d6 100644 --- a/src/vs/editor/contrib/codeAction/common/types.ts +++ b/src/vs/editor/contrib/codeAction/common/types.ts @@ -127,11 +127,6 @@ export function filtersAction(filter: CodeActionFilter, action: languages.CodeAc } } - // On empty lines and selections, show only code AI code actions - if (rangeOrSelection.isEmpty() && model.getLineContent(rangeOrSelection.startLineNumber).length === 0) { - return !!action.isAI; - } - return true; } From 7ef3fef40271115a78b1690c5cc0312b7339d524 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 6 Dec 2023 11:35:51 +0100 Subject: [PATCH 31/37] debt - relax `product.json` type (#200122) --- src/vs/base/common/product.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index 3cdab02a17b..cbd573fdc72 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -40,7 +40,7 @@ export type ConfigurationSyncStore = { url: string; insidersUrl: string; stableUrl: string; - canSwitch: boolean; + canSwitch?: boolean; authenticationProviders: IStringDictionary<{ scopes: string[] }>; }; @@ -203,7 +203,7 @@ export interface IExtensionRecommendations { } export interface ISettingsEditorOpenCondition { - readonly prerelease: boolean | string; + readonly prerelease?: boolean | string; } export interface IExtensionRecommendationCondition { From 52ca689ee7ec9d7c8d75868530b4f8131303f0e1 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Wed, 6 Dec 2023 11:51:56 +0100 Subject: [PATCH 32/37] ensureNoDisposablesAreLeakedInTestSuite (#200115) * ensureNoDisposablesAreLeakedInTestSuite * :lipstick: --- .eslintrc.json | 1 - src/vs/base/test/common/objects.test.ts | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 73fa13c05ff..e3140e7e818 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -188,7 +188,6 @@ "src/vs/base/test/common/naturalLanguage/korean.test.ts", "src/vs/base/test/common/network.test.ts", "src/vs/base/test/common/normalization.test.ts", - "src/vs/base/test/common/objects.test.ts", "src/vs/base/test/common/observable.test.ts", "src/vs/base/test/common/path.test.ts", "src/vs/base/test/common/prefixTree.test.ts", diff --git a/src/vs/base/test/common/objects.test.ts b/src/vs/base/test/common/objects.test.ts index 867615abce6..2b98c775baa 100644 --- a/src/vs/base/test/common/objects.test.ts +++ b/src/vs/base/test/common/objects.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as objects from 'vs/base/common/objects'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; const check = (one: any, other: any, msg: string) => { assert(objects.equals(one, other), msg); @@ -17,6 +18,8 @@ const checkNot = (one: any, other: any, msg: string) => { suite('Objects', () => { + ensureNoDisposablesAreLeakedInTestSuite(); + test('equals', () => { check(null, null, 'null'); check(undefined, undefined, 'undefined'); From 5455d20ce15b337021a5504cbe7509cc51d20445 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 6 Dec 2023 12:09:11 +0100 Subject: [PATCH 33/37] debt - adopt `ensureNoDisposablesAreLeakedInTestSuite` in more tests (#200116) * debt - adopt `ensureNoDisposablesAreLeakedInTestSuite` in more tests * . * . * . --- .eslintrc.json | 30 +------------------ .github/classifier.json | 2 ++ src/vs/base/test/browser/dom.test.ts | 3 ++ .../browser/formattedTextRenderer.test.ts | 3 ++ src/vs/base/test/browser/iconLabels.test.ts | 3 ++ .../ui/contextview/contextview.test.ts | 3 ++ src/vs/base/test/common/assert.test.ts | 3 ++ src/vs/base/test/common/iconLabels.test.ts | 3 ++ src/vs/base/test/common/lazy.test.ts | 3 ++ src/vs/base/test/common/mime.test.ts | 3 ++ src/vs/base/test/common/strings.test.ts | 3 ++ src/vs/base/test/node/port.test.ts | 3 ++ src/vs/base/test/node/unc.test.ts | 3 ++ .../dialogs/test/common/dialog.test.ts | 3 ++ .../environment/test/node/argv.test.ts | 5 ++++ .../test/node/userDataPath.test.ts | 3 ++ .../test/common/configRemotes.test.ts | 3 ++ .../test/browser/telemetryService.test.ts | 3 ++ .../test/common/undoRedoService.test.ts | 2 ++ .../workspaces/test/common/workspaces.test.ts | 3 ++ .../test/electron-main/workspaces.test.ts | 3 ++ .../api/test/browser/extHost.api.impl.test.ts | 3 ++ .../browser/extHostMessagerService.test.ts | 3 ++ .../files/test/browser/explorerModel.test.ts | 4 ++- .../files/test/browser/fileActions.test.ts | 3 ++ .../tags/test/node/workspaceTags.test.ts | 3 ++ .../test/node/colorRegistryExport.test.ts | 3 ++ .../configurationResolverService.test.ts | 3 ++ .../test/node/textSearchManager.test.ts | 3 ++ .../test/browser/arrayOperation.test.ts | 3 ++ src/vs/workbench/test/browser/webview.test.ts | 3 ++ 31 files changed, 91 insertions(+), 30 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index e3140e7e818..34be9c82c21 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -149,18 +149,13 @@ "src/vs/base/parts/sandbox/test/electron-sandbox/globals.test.ts", "src/vs/base/test/browser/browser.test.ts", "src/vs/base/test/browser/comparers.test.ts", - "src/vs/base/test/browser/dom.test.ts", - "src/vs/base/test/browser/formattedTextRenderer.test.ts", "src/vs/base/test/browser/hash.test.ts", - "src/vs/base/test/browser/iconLabels.test.ts", "src/vs/base/test/browser/indexedDB.test.ts", - "src/vs/base/test/browser/ui/contextview/contextview.test.ts", "src/vs/base/test/browser/ui/menu/menubar.test.ts", "src/vs/base/test/browser/ui/scrollbar/scrollableElement.test.ts", "src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts", "src/vs/base/test/common/arrays.test.ts", "src/vs/base/test/common/arraysFind.test.ts", - "src/vs/base/test/common/assert.test.ts", "src/vs/base/test/common/cache.test.ts", "src/vs/base/test/common/charCode.test.ts", "src/vs/base/test/common/collections.test.ts", @@ -178,13 +173,11 @@ "src/vs/base/test/common/jsonFormatter.test.ts", "src/vs/base/test/common/keybindings.test.ts", "src/vs/base/test/common/keyCodes.test.ts", - "src/vs/base/test/common/lazy.test.ts", "src/vs/base/test/common/linkedList.test.ts", "src/vs/base/test/common/linkedText.test.ts", "src/vs/base/test/common/map.test.ts", "src/vs/base/test/common/markdownString.test.ts", "src/vs/base/test/common/marshalling.test.ts", - "src/vs/base/test/common/mime.test.ts", "src/vs/base/test/common/naturalLanguage/korean.test.ts", "src/vs/base/test/common/network.test.ts", "src/vs/base/test/common/normalization.test.ts", @@ -195,7 +188,6 @@ "src/vs/base/test/common/resourceTree.test.ts", "src/vs/base/test/common/scrollable.test.ts", "src/vs/base/test/common/skipList.test.ts", - "src/vs/base/test/common/strings.test.ts", "src/vs/base/test/common/stripComments.test.ts", "src/vs/base/test/common/ternarySearchtree.test.ts", "src/vs/base/test/common/types.test.ts", @@ -205,9 +197,7 @@ "src/vs/base/test/node/css.build.test.ts", "src/vs/base/test/node/id.test.ts", "src/vs/base/test/node/nodeStreams.test.ts", - "src/vs/base/test/node/port.test.ts", "src/vs/base/test/node/snapshot.test.ts", - "src/vs/base/test/node/unc.test.ts", "src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts", "src/vs/editor/contrib/codeAction/test/browser/codeActionKeybindingResolver.test.ts", "src/vs/editor/contrib/codeAction/test/browser/codeActionModel.test.ts", @@ -233,10 +223,6 @@ "src/vs/platform/contextkey/test/common/contextkey.test.ts", "src/vs/platform/contextkey/test/common/parser.test.ts", "src/vs/platform/contextkey/test/common/scanner.test.ts", - "src/vs/platform/dialogs/test/common/dialog.test.ts", - "src/vs/platform/environment/test/node/argv.test.ts", - "src/vs/platform/environment/test/node/userDataPath.test.ts", - "src/vs/platform/extensionManagement/test/common/configRemotes.test.ts", "src/vs/platform/extensionManagement/test/common/extensionManagement.test.ts", "src/vs/platform/extensions/test/common/extensionValidator.test.ts", "src/vs/platform/externalTerminal/electron-main/externalTerminalService.test.ts", @@ -251,24 +237,19 @@ "src/vs/platform/registry/test/common/platform.test.ts", "src/vs/platform/remote/test/common/remoteHosts.test.ts", "src/vs/platform/telemetry/test/browser/1dsAppender.test.ts", - "src/vs/platform/telemetry/test/browser/telemetryService.test.ts", "src/vs/platform/telemetry/test/common/telemetryLogAppender.test.ts", - "src/vs/platform/undoRedo/test/common/undoRedoService.test.ts", "src/vs/platform/userDataSync/test/common/extensionsMerge.test.ts", "src/vs/platform/userDataSync/test/common/globalStateMerge.test.ts", "src/vs/platform/userDataSync/test/common/settingsMerge.test.ts", "src/vs/platform/userDataSync/test/common/snippetsMerge.test.ts", "src/vs/platform/userDataSync/test/common/userDataProfilesManifestMerge.test.ts", "src/vs/platform/workspace/test/common/workspace.test.ts", - "src/vs/platform/workspaces/test/common/workspaces.test.ts", "src/vs/platform/workspaces/test/electron-main/workspaces.test.ts", "src/vs/server/test/node/serverConnectionToken.test.ts", - "src/vs/workbench/api/test/browser/extHost.api.impl.test.ts", "src/vs/workbench/api/test/browser/extHostApiCommands.test.ts", "src/vs/workbench/api/test/browser/extHostBulkEdits.test.ts", "src/vs/workbench/api/test/browser/extHostCommands.test.ts", "src/vs/workbench/api/test/browser/extHostDocumentSaveParticipant.test.ts", - "src/vs/workbench/api/test/browser/extHostMessagerService.test.ts", "src/vs/workbench/api/test/browser/extHostTelemetry.test.ts", "src/vs/workbench/api/test/browser/extHostTextEditor.test.ts", "src/vs/workbench/api/test/browser/extHostTypeConverter.test.ts", @@ -294,9 +275,7 @@ "src/vs/workbench/contrib/extensions/test/common/extensionQuery.test.ts", "src/vs/workbench/contrib/extensions/test/electron-sandbox/extension.test.ts", "src/vs/workbench/contrib/files/test/browser/explorerFileNestingTrie.test.ts", - "src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts", "src/vs/workbench/contrib/files/test/browser/explorerView.test.ts", - "src/vs/workbench/contrib/files/test/browser/fileActions.test.ts", "src/vs/workbench/contrib/notebook/test/browser/cellDnd.test.ts", "src/vs/workbench/contrib/notebook/test/browser/contrib/contributedStatusBarItemController.test.ts", "src/vs/workbench/contrib/notebook/test/browser/contrib/executionStatusBarItem.test.ts", @@ -311,15 +290,12 @@ "src/vs/workbench/contrib/snippets/test/browser/snippetFile.test.ts", "src/vs/workbench/contrib/snippets/test/browser/snippetsRegistry.test.ts", "src/vs/workbench/contrib/snippets/test/browser/snippetsRewrite.test.ts", - "src/vs/workbench/contrib/tags/test/node/workspaceTags.test.ts", "src/vs/workbench/contrib/tasks/test/common/problemMatcher.test.ts", "src/vs/workbench/contrib/tasks/test/common/taskConfiguration.test.ts", "src/vs/workbench/contrib/terminal/test/browser/terminalActions.test.ts", - "src/vs/workbench/contrib/themes/test/node/colorRegistryExport.test.ts", "src/vs/workbench/contrib/welcomeGettingStarted/test/browser/gettingStartedMarkdownRenderer.test.ts", "src/vs/workbench/services/commands/test/common/commandService.test.ts", "src/vs/workbench/services/configuration/test/common/configurationModels.test.ts", - "src/vs/workbench/services/configurationResolver/test/electron-sandbox/configurationResolverService.test.ts", "src/vs/workbench/services/dialogs/test/electron-sandbox/fileDialogService.test.ts", "src/vs/workbench/services/editor/test/browser/editorResolverService.test.ts", "src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts", @@ -337,16 +313,12 @@ "src/vs/workbench/services/search/test/common/searchHelpers.test.ts", "src/vs/workbench/services/search/test/node/ripgrepFileSearch.test.ts", "src/vs/workbench/services/search/test/node/ripgrepTextSearchEngineUtils.test.ts", - "src/vs/workbench/services/search/test/node/textSearchManager.test.ts", "src/vs/workbench/services/telemetry/test/browser/commonProperties.test.ts", - "src/vs/workbench/services/textfile/test/common/textFileService.io.test.ts", - "src/vs/workbench/services/textMate/test/browser/arrayOperation.test.ts", "src/vs/workbench/services/themes/test/node/tokenStyleResolving.test.ts", "src/vs/workbench/services/userActivity/test/browser/domActivityTracker.test.ts", "src/vs/workbench/services/workspaces/test/browser/workspaces.test.ts", "src/vs/workbench/services/workspaces/test/common/workspaceTrust.test.ts", - "src/vs/workbench/test/browser/quickAccess.test.ts", - "src/vs/workbench/test/browser/webview.test.ts" + "src/vs/workbench/test/browser/quickAccess.test.ts" ] } ] diff --git a/.github/classifier.json b/.github/classifier.json index 21b8d51cd6c..992354698ce 100644 --- a/.github/classifier.json +++ b/.github/classifier.json @@ -253,6 +253,7 @@ "tokenization": {"assign": ["alexdima"]}, "touch/pointer": {"assign": []}, "trackpad/scroll": {"assign": []}, + "tree-sticky-scroll": {"assign": ["benibenj"]}, "tree-views": {"assign": ["alexr00"]}, "tree-widget": {"assign": ["joaomoreno"]}, "typehierarchy": {"assign": ["jrieken"]}, @@ -272,6 +273,7 @@ "webview": {"assign": ["mjbvz"]}, "webview-views": {"assign": ["mjbvz"]}, "workbench-actions": {"assign": ["bpasero"]}, + "workbench-auxwindow": {"assign": ["bpasero"]}, "workbench-banner": {"assign": ["lszomoru", "sbatten"]}, "workbench-cli": {"assign": ["bpasero"]}, "workbench-diagnostics": {"assign": ["Tyriar"]}, diff --git a/src/vs/base/test/browser/dom.test.ts b/src/vs/base/test/browser/dom.test.ts index 8e22994c7da..601f75d3523 100644 --- a/src/vs/base/test/browser/dom.test.ts +++ b/src/vs/base/test/browser/dom.test.ts @@ -8,6 +8,7 @@ import { $, asCssValueWithDefault, h, multibyteAwareBtoa, trackAttributes, copyA import { ensureCodeWindow, isAuxiliaryWindow, mainWindow } from 'vs/base/browser/window'; import { DeferredPromise, timeout } from 'vs/base/common/async'; import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('dom', () => { test('hasClass', () => { @@ -404,4 +405,6 @@ suite('dom', () => { assert.strictEqual(count, 0); }); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/browser/formattedTextRenderer.test.ts b/src/vs/base/test/browser/formattedTextRenderer.test.ts index f5bcc1b2d5d..12acef6e7b8 100644 --- a/src/vs/base/test/browser/formattedTextRenderer.test.ts +++ b/src/vs/base/test/browser/formattedTextRenderer.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { renderFormattedText, renderText } from 'vs/base/browser/formattedTextRenderer'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('FormattedTextRenderer', () => { const store = new DisposableStore(); @@ -127,4 +128,6 @@ suite('FormattedTextRenderer', () => { assert.strictEqual(result.children.length, 0); assert.strictEqual(result.innerHTML, '**bold**'); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/browser/iconLabels.test.ts b/src/vs/base/test/browser/iconLabels.test.ts index 292ec6b0bf8..c076d4ec38e 100644 --- a/src/vs/base/test/browser/iconLabels.test.ts +++ b/src/vs/base/test/browser/iconLabels.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('renderLabelWithIcons', () => { @@ -49,4 +50,6 @@ suite('renderLabelWithIcons', () => { .map(elem => elem instanceof HTMLElement ? elem.outerHTML : elem) .reduce((a, b) => a + b, ''); }; + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/browser/ui/contextview/contextview.test.ts b/src/vs/base/test/browser/ui/contextview/contextview.test.ts index 4b49df18555..c302c358937 100644 --- a/src/vs/base/test/browser/ui/contextview/contextview.test.ts +++ b/src/vs/base/test/browser/ui/contextview/contextview.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { layout, LayoutAnchorPosition } from 'vs/base/browser/ui/contextview/contextview'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('Contextview', function () { @@ -25,4 +26,6 @@ suite('Contextview', function () { assert.strictEqual(layout(200, 20, { offset: 50, size: 50, position: LayoutAnchorPosition.After }), 30); assert.strictEqual(layout(200, 20, { offset: 150, size: 50, position: LayoutAnchorPosition.After }), 130); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/common/assert.test.ts b/src/vs/base/test/common/assert.test.ts index a925cd0437a..ed4e60e8222 100644 --- a/src/vs/base/test/common/assert.test.ts +++ b/src/vs/base/test/common/assert.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { ok } from 'vs/base/common/assert'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('Assert', () => { test('ok', () => { @@ -31,4 +32,6 @@ suite('Assert', () => { ok({}); ok(5); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/common/iconLabels.test.ts b/src/vs/base/test/common/iconLabels.test.ts index 33aee64d860..b8352069e1c 100644 --- a/src/vs/base/test/common/iconLabels.test.ts +++ b/src/vs/base/test/common/iconLabels.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { IMatch } from 'vs/base/common/filters'; import { escapeIcons, getCodiconAriaLabel, IParsedLabelWithIcons, markdownEscapeEscapedIcons, matchesFuzzyIconAware, parseLabelWithIcons, stripIcons } from 'vs/base/common/iconLabels'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; interface IIconFilter { // Returns null if word doesn't match. @@ -110,4 +111,6 @@ suite('Icon Labels', () => { assert.strictEqual(markdownEscapeEscapedIcons('$(Hello) World'), '$(Hello) World'); assert.strictEqual(markdownEscapeEscapedIcons('\\$(Hello) World'), '\\\\$(Hello) World'); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/common/lazy.test.ts b/src/vs/base/test/common/lazy.test.ts index e3a8d66459c..361e3305d43 100644 --- a/src/vs/base/test/common/lazy.test.ts +++ b/src/vs/base/test/common/lazy.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { Lazy } from 'vs/base/common/lazy'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('Lazy', () => { @@ -27,4 +28,6 @@ suite('Lazy', () => { assert.strictEqual(value.hasValue, true); assert.throws(() => value.value, /\b1\b/); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/common/mime.test.ts b/src/vs/base/test/common/mime.test.ts index f403db8a960..fce56646ff8 100644 --- a/src/vs/base/test/common/mime.test.ts +++ b/src/vs/base/test/common/mime.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { normalizeMimeType } from 'vs/base/common/mime'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('Mime', () => { @@ -16,4 +17,6 @@ suite('Mime', () => { assert.strictEqual(normalizeMimeType('Text/plain;UPPER'), 'text/plain;UPPER'); assert.strictEqual(normalizeMimeType('Text/plain;lower'), 'text/plain;lower'); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/common/strings.test.ts b/src/vs/base/test/common/strings.test.ts index ad8655b153c..e986069c888 100644 --- a/src/vs/base/test/common/strings.test.ts +++ b/src/vs/base/test/common/strings.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as strings from 'vs/base/common/strings'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('Strings', () => { test('equalsIgnoreCase', () => { @@ -510,4 +511,6 @@ suite('Strings', () => { assert.strictEqual(strings.removeAnsiEscapeCodes(`hello${sequence}world`), 'helloworld', `expect to remove ${JSON.stringify(sequence)}`); } }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/node/port.test.ts b/src/vs/base/test/node/port.test.ts index 120044651b5..9230dc84684 100644 --- a/src/vs/base/test/node/port.test.ts +++ b/src/vs/base/test/node/port.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import * as net from 'net'; import * as ports from 'vs/base/node/ports'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { flakySuite } from 'vs/base/test/node/testUtils'; flakySuite('Ports', () => { @@ -29,4 +30,6 @@ flakySuite('Ports', () => { }); }, err => done(err)); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/base/test/node/unc.test.ts b/src/vs/base/test/node/unc.test.ts index 82eaf25860d..acbc3203536 100644 --- a/src/vs/base/test/node/unc.test.ts +++ b/src/vs/base/test/node/unc.test.ts @@ -5,6 +5,7 @@ import { strictEqual } from 'assert'; import { getUNCHost } from 'vs/base/node/unc'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('UNC', () => { @@ -43,4 +44,6 @@ suite('UNC', () => { strictEqual(getUNCHost('\\\\.\\UNC\\localhost\\a'), 'localhost'); strictEqual(getUNCHost('\\\\?\\UNC\\localhost\\a'), 'localhost'); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/dialogs/test/common/dialog.test.ts b/src/vs/platform/dialogs/test/common/dialog.test.ts index 4455350a45d..1c5db7e80b8 100644 --- a/src/vs/platform/dialogs/test/common/dialog.test.ts +++ b/src/vs/platform/dialogs/test/common/dialog.test.ts @@ -5,6 +5,7 @@ import { deepEqual } from 'assert'; import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { IMassagedMessageBoxOptions, massageMessageBoxOptions } from 'vs/platform/dialogs/common/dialogs'; import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; @@ -139,4 +140,6 @@ suite('Dialog', () => { assertOptions(fourButtonNegativeCancel, ['4', '3', '2', '1'], 3, -1, [3, 2, 1, 0]); } }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/environment/test/node/argv.test.ts b/src/vs/platform/environment/test/node/argv.test.ts index e3f75f2cde3..a188b52b711 100644 --- a/src/vs/platform/environment/test/node/argv.test.ts +++ b/src/vs/platform/environment/test/node/argv.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { formatOptions, Option, OptionDescriptions, Subcommand, parseArgs, ErrorReporter } from 'vs/platform/environment/node/argv'; import { addArg } from 'vs/platform/environment/node/argvHelper'; @@ -81,6 +82,8 @@ suite('formatOptions', () => { ' A test command' ]); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); suite('parseArgs', () => { @@ -156,4 +159,6 @@ suite('parseArgs', () => { [] ); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/environment/test/node/userDataPath.test.ts b/src/vs/platform/environment/test/node/userDataPath.test.ts index f92f1808481..644260cff8f 100644 --- a/src/vs/platform/environment/test/node/userDataPath.test.ts +++ b/src/vs/platform/environment/test/node/userDataPath.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { OPTIONS, parseArgs } from 'vs/platform/environment/node/argv'; import { getUserDataPath } from 'vs/platform/environment/node/userDataPath'; import product from 'vs/platform/product/common/product'; @@ -57,4 +58,6 @@ suite('User data path', () => { } } }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/extensionManagement/test/common/configRemotes.test.ts b/src/vs/platform/extensionManagement/test/common/configRemotes.test.ts index c5ed11d8e1b..e27bb5a488a 100644 --- a/src/vs/platform/extensionManagement/test/common/configRemotes.test.ts +++ b/src/vs/platform/extensionManagement/test/common/configRemotes.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { getDomainsOfRemotes, getRemotes } from 'vs/platform/extensionManagement/common/configRemotes'; suite('Config Remotes', () => { @@ -127,4 +128,6 @@ suite('Config Remotes', () => { fetch = +refs/heads/*:refs/remotes/origin/* `; } + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts index f20eb00d58a..8524e9a6996 100644 --- a/src/vs/platform/telemetry/test/browser/telemetryService.test.ts +++ b/src/vs/platform/telemetry/test/browser/telemetryService.test.ts @@ -8,6 +8,7 @@ import * as sinonTest from 'sinon-test'; import { mainWindow } from 'vs/base/browser/window'; import * as Errors from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; @@ -741,4 +742,6 @@ suite('TelemetryService', () => { service.dispose(); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/undoRedo/test/common/undoRedoService.test.ts b/src/vs/platform/undoRedo/test/common/undoRedoService.test.ts index 88fa11a3a87..27d69e4e5ac 100644 --- a/src/vs/platform/undoRedo/test/common/undoRedoService.test.ts +++ b/src/vs/platform/undoRedo/test/common/undoRedoService.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; import { mock } from 'vs/base/test/common/mock'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { IDialogService, IPrompt } from 'vs/platform/dialogs/common/dialogs'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; @@ -226,4 +227,5 @@ suite('UndoRedoService', () => { assert.strictEqual(UndoRedoGroup.None.nextOrder(), 0); }); + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/workspaces/test/common/workspaces.test.ts b/src/vs/platform/workspaces/test/common/workspaces.test.ts index 374ac0657f2..a1f2f262d00 100644 --- a/src/vs/platform/workspaces/test/common/workspaces.test.ts +++ b/src/vs/platform/workspaces/test/common/workspaces.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { ISerializedSingleFolderWorkspaceIdentifier, ISerializedWorkspaceIdentifier, reviveIdentifier, hasWorkspaceFileExtension, isWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IEmptyWorkspaceIdentifier, toWorkspaceIdentifier, isEmptyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; suite('Workspaces', () => { @@ -46,4 +47,6 @@ suite('Workspaces', () => { assert.ok(!isSingleFolderWorkspaceIdentifier(identifier)); assert.ok(isWorkspaceIdentifier(identifier)); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/platform/workspaces/test/electron-main/workspaces.test.ts b/src/vs/platform/workspaces/test/electron-main/workspaces.test.ts index 42427b5ea6d..56e4d92fdc9 100644 --- a/src/vs/platform/workspaces/test/electron-main/workspaces.test.ts +++ b/src/vs/platform/workspaces/test/electron-main/workspaces.test.ts @@ -10,6 +10,7 @@ import * as path from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { flakySuite, getRandomTestPath } from 'vs/base/test/node/testUtils'; import { getSingleFolderWorkspaceIdentifier, getWorkspaceIdentifier } from 'vs/platform/workspaces/node/workspaces'; @@ -64,4 +65,6 @@ flakySuite('Workspaces', () => { // single folder identifier (remote) assert.strictEqual(getSingleFolderWorkspaceIdentifier(URI.parse('vscode-remote:/hello/test'))?.id, '786de4f224d57691f218dc7f31ee2ee3'); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/api/test/browser/extHost.api.impl.test.ts b/src/vs/workbench/api/test/browser/extHost.api.impl.test.ts index 2709cfda696..35e7ff35360 100644 --- a/src/vs/workbench/api/test/browser/extHost.api.impl.test.ts +++ b/src/vs/workbench/api/test/browser/extHost.api.impl.test.ts @@ -7,6 +7,7 @@ import * as assert from 'assert'; import { URI } from 'vs/base/common/uri'; import { originalFSPath } from 'vs/base/common/resources'; import { isWindows } from 'vs/base/common/platform'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('ExtHost API', function () { test('issue #51387: originalFSPath', function () { @@ -18,4 +19,6 @@ suite('ExtHost API', function () { assert.strictEqual(originalFSPath(URI.revive(JSON.parse(JSON.stringify(URI.file('c:\\test'))))).charAt(0), 'c'); } }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/api/test/browser/extHostMessagerService.test.ts b/src/vs/workbench/api/test/browser/extHostMessagerService.test.ts index c65fe797901..a5c89dd257f 100644 --- a/src/vs/workbench/api/test/browser/extHostMessagerService.test.ts +++ b/src/vs/workbench/api/test/browser/extHostMessagerService.test.ts @@ -12,6 +12,7 @@ import { mock } from 'vs/base/test/common/mock'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; const emptyCommandService: ICommandService = { _serviceBrand: undefined, @@ -132,4 +133,6 @@ suite('ExtHostMessageService', function () { assert.strictEqual(handle, 42); }); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts b/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts index 9aa3627dbaa..938fed848a2 100644 --- a/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/explorerModel.test.ts @@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri'; import { join } from 'vs/base/common/path'; import { validateFileName } from 'vs/workbench/contrib/files/browser/fileActions'; import { ExplorerItem } from 'vs/workbench/contrib/files/common/explorerModel'; -import { toResource } from 'vs/base/test/common/utils'; +import { ensureNoDisposablesAreLeakedInTestSuite, toResource } from 'vs/base/test/common/utils'; import { TestFileService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { NullFilesConfigurationService } from 'vs/workbench/test/common/workbenchTestServices'; @@ -277,4 +277,6 @@ suite('Files - View Model', function () { ExplorerItem.mergeLocalWithDisk(merge2, merge1); assert.ok(existingChild === merge1.getChild(existingChild!.name)); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/contrib/files/test/browser/fileActions.test.ts b/src/vs/workbench/contrib/files/test/browser/fileActions.test.ts index bfa18a3b7a4..e1e8db24108 100644 --- a/src/vs/workbench/contrib/files/test/browser/fileActions.test.ts +++ b/src/vs/workbench/contrib/files/test/browser/fileActions.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { incrementFileName } from 'vs/workbench/contrib/files/browser/fileActions'; suite('Files - Increment file name simple', () => { @@ -134,6 +135,7 @@ suite('Files - Increment file name simple', () => { assert.strictEqual(result, 'test copy 2'); }); + ensureNoDisposablesAreLeakedInTestSuite(); }); suite('Files - Increment file name smart', () => { @@ -324,4 +326,5 @@ suite('Files - Increment file name smart', () => { assert.strictEqual(result, '2-test'); }); + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/contrib/tags/test/node/workspaceTags.test.ts b/src/vs/workbench/contrib/tags/test/node/workspaceTags.test.ts index ff3d16fd312..7f58ae8e9e1 100644 --- a/src/vs/workbench/contrib/tags/test/node/workspaceTags.test.ts +++ b/src/vs/workbench/contrib/tags/test/node/workspaceTags.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import * as crypto from 'crypto'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { getHashedRemotesFromConfig as baseGetHashedRemotesFromConfig } from 'vs/workbench/contrib/tags/common/workspaceTags'; function hash(value: string): string { @@ -58,4 +59,6 @@ suite('Telemetry - WorkspaceTags', () => { fetch = +refs/heads/*:refs/remotes/origin/* `; } + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/contrib/themes/test/node/colorRegistryExport.test.ts b/src/vs/workbench/contrib/themes/test/node/colorRegistryExport.test.ts index a051fa3ae71..ccd7af54f75 100644 --- a/src/vs/workbench/contrib/themes/test/node/colorRegistryExport.test.ts +++ b/src/vs/workbench/contrib/themes/test/node/colorRegistryExport.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Color } from 'vs/base/common/color'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { Registry } from 'vs/platform/registry/common/platform'; import { Extensions, IColorRegistry } from 'vs/platform/theme/common/colorRegistry'; @@ -17,4 +18,6 @@ suite('ColorRegistry', () => { console.log(`#colors:${JSON.stringify(colors, replacer)}\n`); }); } + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/services/configurationResolver/test/electron-sandbox/configurationResolverService.test.ts b/src/vs/workbench/services/configurationResolver/test/electron-sandbox/configurationResolverService.test.ts index a2d2aa43af0..7357382e7a3 100644 --- a/src/vs/workbench/services/configurationResolver/test/electron-sandbox/configurationResolverService.test.ts +++ b/src/vs/workbench/services/configurationResolver/test/electron-sandbox/configurationResolverService.test.ts @@ -12,6 +12,7 @@ import { IPath, normalize } from 'vs/base/common/path'; import * as platform from 'vs/base/common/platform'; import { isObject } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { Selection } from 'vs/editor/common/core/selection'; import { EditorType } from 'vs/editor/common/editorCommon'; import { ICommandService } from 'vs/platform/commands/common/commands'; @@ -645,6 +646,8 @@ suite('Configuration Resolver Service', () => { const resolvedResult = await configurationResolverService!.resolveWithEnvironment({ ...env }, undefined, configuration); assert.deepStrictEqual(resolvedResult, 'echo VAL_1VAL_2'); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); 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 fec67730fa0..f4203933951 100644 --- a/src/vs/workbench/services/search/test/node/textSearchManager.test.ts +++ b/src/vs/workbench/services/search/test/node/textSearchManager.test.ts @@ -6,6 +6,7 @@ import * as assert from 'assert'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import { URI } from 'vs/base/common/uri'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; 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'; @@ -38,4 +39,6 @@ suite('NativeTextSearchManager', () => { assert.ok(correctEncoding); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/services/textMate/test/browser/arrayOperation.test.ts b/src/vs/workbench/services/textMate/test/browser/arrayOperation.test.ts index d51b85c57b6..917849e3b57 100644 --- a/src/vs/workbench/services/textMate/test/browser/arrayOperation.test.ts +++ b/src/vs/workbench/services/textMate/test/browser/arrayOperation.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { ArrayEdit, MonotonousIndexTransformer, SingleArrayEdit } from 'vs/workbench/services/textMate/browser/arrayOperation'; suite('array operation', () => { @@ -74,4 +75,6 @@ suite('array operation', () => { ] ); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); diff --git a/src/vs/workbench/test/browser/webview.test.ts b/src/vs/workbench/test/browser/webview.test.ts index 484be00a657..3d0c3701f14 100644 --- a/src/vs/workbench/test/browser/webview.test.ts +++ b/src/vs/workbench/test/browser/webview.test.ts @@ -5,6 +5,7 @@ import * as assert from 'assert'; import { parentOriginHash } from 'vs/base/browser/iframe'; +import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; suite('parentOriginHash', () => { @@ -22,4 +23,6 @@ suite('parentOriginHash', () => { const hash = await parentOriginHash('http://localhost:9887', '123456'); assert.strictEqual(hash, '1v1128i162q0nee9l89360sqan26u3pdnjrkke5ijd0sel8sbtqf'); }); + + ensureNoDisposablesAreLeakedInTestSuite(); }); From 3056f52f92b6b208b44d6c3249dac1fe69e06607 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Dec 2023 12:16:49 +0100 Subject: [PATCH 34/37] add failing/skipped test for https://github.com/microsoft/vscode/issues/191070 (#200125) * fix --dev option of unit tests fyi @joaomoreno * fix timing issue when getting line, add failing/skipped test for https://github.com/microsoft/vscode/issues/191070 --- .../browser/snippetCompletionProvider.ts | 6 ++-- .../test/browser/snippetsService.test.ts | 32 +++++++++++++++++++ test/unit/electron/index.js | 4 +-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts index c3b6b486a9f..17dc94277d9 100644 --- a/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts +++ b/src/vs/workbench/contrib/snippets/browser/snippetCompletionProvider.ts @@ -85,13 +85,13 @@ export class SnippetCompletionProvider implements CompletionItemProvider { async provideCompletionItems(model: ITextModel, position: Position, context: CompletionContext): Promise { const sw = new StopWatch(); + const lineContentLow = model.getLineContent(position.lineNumber).toLowerCase(); + const wordUntil = model.getWordUntilPosition(position).word.toLowerCase(); + const languageId = this._getLanguageIdAtPosition(model, position); const languageConfig = this._languageConfigurationService.getLanguageConfiguration(languageId); const snippets = new Set(await this._snippets.getSnippets(languageId)); - const lineContentLow = model.getLineContent(position.lineNumber).toLowerCase(); - const wordUntil = model.getWordUntilPosition(position).word.toLowerCase(); - const suggestions: SnippetCompletion[] = []; const columnOffset = position.column - 1; diff --git a/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts b/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts index e74a499f9c0..084a9b64dde 100644 --- a/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts +++ b/src/vs/workbench/contrib/snippets/test/browser/snippetsService.test.ts @@ -819,4 +819,36 @@ suite('SnippetsService', function () { const first = result.suggestions[0]; assert.strictEqual((first.range).insert.startColumn, 5); }); + + test.skip('Autocomplete suggests based on the last letter of a word and it depends on the typing speed #191070', async function () { + snippetService = new SimpleSnippetService([ + new Snippet(false, ['fooLang'], '/whiletrue', '/whiletrue', '', 'one', '', SnippetSource.User, generateUuid()), + new Snippet(false, ['fooLang'], '/sc not expanding', '/sc not expanding', '', 'two', '', SnippetSource.User, generateUuid()), + ]); + + const provider = new SnippetCompletionProvider(languageService, snippetService, disposables.add(new TestLanguageConfigurationService())); + const model = disposables.add(instantiateTextModel(instantiationService, '', 'fooLang')); + + { // PREFIX: w + model.setValue('w'); + const result1 = await provider.provideCompletionItems( + model, + new Position(1, 2), + { triggerKind: CompletionTriggerKind.Invoke } + ); + assert.strictEqual(result1.suggestions.length, 1); + assert.strictEqual(result1.suggestions[0].insertText, 'one'); + } + + { // PREFIX: where + model.setValue('where'); + const result2 = await provider.provideCompletionItems( + model, + new Position(1, 6), + { triggerKind: CompletionTriggerKind.Invoke } + ); + assert.strictEqual(result2.suggestions.length, 1); + assert.strictEqual(result2.suggestions[1].insertText, 'one'); // /whiletrue matches where (WHilEtRuE) + } + }); }); diff --git a/test/unit/electron/index.js b/test/unit/electron/index.js index 81c5752111d..a02bce4999c 100644 --- a/test/unit/electron/index.js +++ b/test/unit/electron/index.js @@ -43,8 +43,8 @@ const minimist = require('minimist'); * }} */ const args = minimist(process.argv.slice(2), { - string: ['grep', 'run', 'runGlob', 'dev', 'reporter', 'reporter-options', 'wait-server', 'timeout', 'crash-reporter-directory', 'tfs'], - boolean: ['build', 'coverage', 'help'], + string: ['grep', 'run', 'runGlob', 'reporter', 'reporter-options', 'wait-server', 'timeout', 'crash-reporter-directory', 'tfs'], + boolean: ['build', 'coverage', 'help', 'dev'], alias: { 'grep': ['g', 'f'], 'runGlob': ['glob', 'runGrep'], From cffff4c0da1b920e6324dafb71674d0773e55e83 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:23:18 +0100 Subject: [PATCH 35/37] Fix locking groups with aux windows (#200039) * Aux Locking * :lipstick: * :lipstick: * unlock last group * :lipstick: * :lipstick: * unlock from editor parts * :lipstick: * . --------- Co-authored-by: Benjamin Pasero --- .../parts/editor/auxiliaryEditorPart.ts | 28 +++++++++++++++++-- .../browser/parts/editor/editorGroupView.ts | 6 +--- .../browser/parts/editor/editorPart.ts | 8 +----- .../browser/parts/editor/editorParts.ts | 15 ++++++++-- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts b/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts index f803e7dfd68..72b84741e46 100644 --- a/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts +++ b/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.ts @@ -19,7 +19,7 @@ import { EditorPart } from 'vs/workbench/browser/parts/editor/editorPart'; import { IAuxiliaryTitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart'; import { WindowTitle } from 'vs/workbench/browser/parts/titlebar/windowTitle'; import { IAuxiliaryWindowOpenOptions, IAuxiliaryWindowService } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService'; -import { GroupsOrder, IAuxiliaryEditorPart } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { GroupDirection, GroupsOrder, IAuxiliaryEditorPart } 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 { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; @@ -220,10 +220,32 @@ class AuxiliaryEditorPartImpl extends EditorPart implements IAuxiliaryEditorPart } private doClose(mergeGroupsToMainPart: boolean): void { - if (mergeGroupsToMainPart && this.groups.some(group => group.count > 0)) { - this.mergeAllGroups(this.editorPartsView.mainPart.activeGroup); + if (mergeGroupsToMainPart) { + this.mergeGroupsToMainPart(); } this._onWillClose.fire(); } + + private mergeGroupsToMainPart(): void { + if (!this.groups.some(group => group.count > 0)) { + return; // skip if we have no editors opened + } + + // Find the most recent group that is not locked + let targetGroup: IEditorGroupView | undefined = undefined; + for (const group of this.editorPartsView.mainPart.getGroups(GroupsOrder.MOST_RECENTLY_ACTIVE)) { + if (!group.isLocked) { + targetGroup = group; + break; + } + } + + if (!targetGroup) { + targetGroup = this.editorPartsView.mainPart.addGroup(this.editorPartsView.mainPart.activeGroup, this.partOptions.openSideBySideDirection === 'right' ? GroupDirection.RIGHT : GroupDirection.DOWN); + } + + this.mergeAllGroups(targetGroup); + targetGroup.focus(); + } } diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 3281151bed1..8cf0c73d078 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1900,11 +1900,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView { } private canLock(): boolean { - if (this.groupsView.isAuxiliary) { - return true; // always allow locking in auxiliary parts, even single groups - } - - return this.groupsView.groups.length > 1; // only allow locking if more than 1 group is opened + return this.editorPartsView.groups.length > 1; // only allow locking if more than 1 group is opened } //#endregion diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index e87d98624fc..55cc970ef96 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -13,7 +13,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { IView, orthogonal, LayoutPriority, IViewSize, Direction, SerializableGrid, Sizing, ISerializedGrid, ISerializedNode, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid'; import { GroupIdentifier, EditorInputWithOptions, IEditorPartOptions, IEditorPartOptionsChangeEvent, GroupModelChangeKind } from 'vs/workbench/common/editor'; import { EDITOR_GROUP_BORDER, EDITOR_PANE_BACKGROUND } from 'vs/workbench/common/theme'; -import { distinct, coalesce, firstOrDefault } from 'vs/base/common/arrays'; +import { distinct, coalesce } from 'vs/base/common/arrays'; import { IEditorGroupView, getEditorPartOptions, impactsEditorPartOptions, IEditorPartCreationOptions, IEditorPartsView, IEditorGroupsView } from 'vs/workbench/browser/parts/editor/editor'; import { EditorGroupView } from 'vs/workbench/browser/parts/editor/editorGroupView'; import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration'; @@ -811,12 +811,6 @@ export class EditorPart extends Part implements IEditorPart, IEditorGroupsView { // Update container this.updateContainer(); - // Update locked state: clear when we are at just 1 group - // in case we are in the main editor part - if (this.count === 1 && !this.isAuxiliary) { - firstOrDefault(this.groups)?.lock(false); - } - // Event this._onDidRemoveGroup.fire(groupView); } diff --git a/src/vs/workbench/browser/parts/editor/editorParts.ts b/src/vs/workbench/browser/parts/editor/editorParts.ts index 155d6d153d2..deb9c9aedfa 100644 --- a/src/vs/workbench/browser/parts/editor/editorParts.ts +++ b/src/vs/workbench/browser/parts/editor/editorParts.ts @@ -13,7 +13,7 @@ import { IEditorGroupView, IEditorPartsView } from 'vs/workbench/browser/parts/e import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IAuxiliaryWindowOpenOptions } from 'vs/workbench/services/auxiliaryWindow/browser/auxiliaryWindowService'; -import { distinct } from 'vs/base/common/arrays'; +import { distinct, firstOrDefault } from 'vs/base/common/arrays'; import { AuxiliaryEditorPart } from 'vs/workbench/browser/parts/editor/auxiliaryEditorPart'; import { MultiWindowParts } from 'vs/workbench/browser/part'; @@ -94,7 +94,7 @@ export class EditorParts extends MultiWindowParts implements IEditor disposables.add(part.onDidChangeActiveGroup(group => this._onDidActiveGroupChange.fire(group))); disposables.add(part.onDidAddGroup(group => this._onDidAddGroup.fire(group))); - disposables.add(part.onDidRemoveGroup(group => this._onDidRemoveGroup.fire(group))); + disposables.add(part.onDidRemoveGroup(group => this.handleOnDidRemoveGroup(group))); disposables.add(part.onDidMoveGroup(group => this._onDidMoveGroup.fire(group))); disposables.add(part.onDidActivateGroup(group => this._onDidActivateGroup.fire(group))); disposables.add(part.onDidChangeGroupMaximized(maximized => this._onDidChangeGroupMaximized.fire(maximized))); @@ -103,6 +103,17 @@ export class EditorParts extends MultiWindowParts implements IEditor disposables.add(part.onDidChangeGroupLocked(group => this._onDidChangeGroupLocked.fire(group))); } + private handleOnDidRemoveGroup(group: IEditorGroupView): void { + + // Reset locked state when only one group is remaining + if (this.count === 1) { + firstOrDefault(this.mainPart.groups)?.lock(false); + } + + // Events + this._onDidRemoveGroup.fire(group); + } + private doUpdateMostRecentActive(part: EditorPart, makeMostRecentlyActive?: boolean): void { const index = this.mostRecentActiveParts.indexOf(part); From acf3fc61ea4dd693d557cd3774278589e81ebdda Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 6 Dec 2023 12:29:05 +0100 Subject: [PATCH 36/37] delay _savePartSplash further, fixes https://github.com/microsoft/vscode/issues/170825 (#200126) --- .../contrib/splash/browser/partsSplash.ts | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/splash/browser/partsSplash.ts b/src/vs/workbench/contrib/splash/browser/partsSplash.ts index 60b8ea9abe1..1007270a967 100644 --- a/src/vs/workbench/contrib/splash/browser/partsSplash.ts +++ b/src/vs/workbench/contrib/splash/browser/partsSplash.ts @@ -7,7 +7,7 @@ import { onDidChangeFullscreen, isFullscreen } from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; import { Color } from 'vs/base/common/color'; import { Event } from 'vs/base/common/event'; -import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { editorBackground, foreground } from 'vs/platform/theme/common/colorRegistry'; import { getThemeTypeSelector, IThemeService } from 'vs/platform/theme/common/themeService'; import { DEFAULT_EDITOR_MIN_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor'; @@ -20,6 +20,7 @@ import * as perf from 'vs/base/common/performance'; import { assertIsDefined } from 'vs/base/common/types'; import { ISplashStorageService } from 'vs/workbench/contrib/splash/browser/splash'; import { mainWindow } from 'vs/base/browser/window'; +import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; export class PartsSplash { @@ -33,20 +34,24 @@ export class PartsSplash { @IThemeService private readonly _themeService: IThemeService, @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService, @IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService, - @IEditorGroupsService editorGroupsService: IEditorGroupsService, @IConfigurationService private readonly _configService: IConfigurationService, - @ISplashStorageService private readonly _partSplashService: ISplashStorageService + @ISplashStorageService private readonly _partSplashService: ISplashStorageService, + @IEditorGroupsService editorGroupsService: IEditorGroupsService, + @ILifecycleService lifecycleService: ILifecycleService, ) { Event.once(_layoutService.onDidLayoutMainContainer)(() => { this._removePartsSplash(); perf.mark('code/didRemovePartsSplash'); }, undefined, this._disposables); - let lastIdleSchedule: IDisposable | undefined; - Event.any(onDidChangeFullscreen, editorGroupsService.mainPart.onDidLayout, _themeService.onDidColorThemeChange)(() => { - lastIdleSchedule?.dispose(); - lastIdleSchedule = dom.runWhenWindowIdle(mainWindow, () => this._savePartsSplash(), 800); - }, undefined, this._disposables); + const lastIdleSchedule = this._disposables.add(new MutableDisposable()); + const savePartsSplashSoon = () => { + lastIdleSchedule.value = dom.runWhenWindowIdle(mainWindow, () => this._savePartsSplash(), 2500); + }; + lifecycleService.when(LifecyclePhase.Restored).then(() => { + Event.any(onDidChangeFullscreen, editorGroupsService.mainPart.onDidLayout, _themeService.onDidColorThemeChange)(savePartsSplashSoon, undefined, this._disposables); + savePartsSplashSoon(); + }); _configService.onDidChangeConfiguration(e => { if (e.affectsConfiguration('window.titleBarStyle')) { From 6d1f607c6db3c6d9c842f77a12375ce9900ed53c Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 6 Dec 2023 12:31:39 +0100 Subject: [PATCH 37/37] Fixes #178259 --- src/vs/editor/common/core/offsetRange.ts | 6 + .../algorithms/diffAlgorithm.ts | 7 ++ .../heuristicSequenceOptimizations.ts | 104 +++++++++--------- .../advanced.expected.diff.json | 4 +- .../advanced.expected.diff.json | 4 +- .../advanced.expected.diff.json | 6 +- .../ts-confusing/advanced.expected.diff.json | 4 +- .../advanced.expected.diff.json | 10 +- 8 files changed, 82 insertions(+), 63 deletions(-) diff --git a/src/vs/editor/common/core/offsetRange.ts b/src/vs/editor/common/core/offsetRange.ts index 5efa09faecc..e35a27c56bc 100644 --- a/src/vs/editor/common/core/offsetRange.ts +++ b/src/vs/editor/common/core/offsetRange.ts @@ -112,6 +112,12 @@ export class OffsetRange implements IOffsetRange { return undefined; } + public intersects(other: OffsetRange): boolean { + const start = Math.max(this.start, other.start); + const end = Math.min(this.endExclusive, other.endExclusive); + return start < end; + } + public intersectsOrTouches(other: OffsetRange): boolean { const start = Math.max(this.start, other.start); const end = Math.min(this.endExclusive, other.endExclusive); diff --git a/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts b/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts index 95cc0f22054..2e0840de625 100644 --- a/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts +++ b/src/vs/editor/common/diff/defaultLinesDiffComputer/algorithms/diffAlgorithm.ts @@ -125,6 +125,13 @@ export class OffsetPair { public toString(): string { return `${this.offset1} <-> ${this.offset2}`; } + + public delta(offset: number): OffsetPair { + if (offset === 0) { + return this; + } + return new OffsetPair(this.offset1 + offset, this.offset2 + offset); + } } export interface ISequence { diff --git a/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts b/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts index da23e59f332..21eebfa8e07 100644 --- a/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts +++ b/src/vs/editor/common/diff/defaultLinesDiffComputer/heuristicSequenceOptimizations.ts @@ -220,72 +220,74 @@ export function removeShortMatches(sequence1: ISequence, sequence2: ISequence, s } export function extendDiffsToEntireWordIfAppropriate(sequence1: LinesSliceCharSequence, sequence2: LinesSliceCharSequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { + const equalMappings = SequenceDiff.invert(sequenceDiffs, sequence1.length); + const additional: SequenceDiff[] = []; - let lastModifiedWord: { added: number; deleted: number; count: number; s1Range: OffsetRange; s2Range: OffsetRange } | undefined = undefined; + let lastPoint = new OffsetPair(0, 0); - function maybePushWordToAdditional() { - if (!lastModifiedWord) { + function scanWord(pair: OffsetPair, equalMapping: SequenceDiff) { + if (pair.offset1 < lastPoint.offset1 || pair.offset2 < lastPoint.offset2) { return; } - const originalLength1 = lastModifiedWord.s1Range.length - lastModifiedWord.deleted; - const originalLength2 = lastModifiedWord.s2Range.length - lastModifiedWord.added; - if (originalLength1 !== originalLength2) { - // TODO figure out why this happens + const w1 = sequence1.findWordContaining(pair.offset1); + const w2 = sequence2.findWordContaining(pair.offset2); + if (!w1 || !w2) { + return; + } + let w = new SequenceDiff(w1, w2); + const equalPart = w.intersect(equalMapping)!; + + let equalChars1 = equalPart.seq1Range.length; + let equalChars2 = equalPart.seq2Range.length; + + // The words do not touch previous equals mappings, as we would have processed them already. + // But they might touch the next ones. + + while (equalMappings.length > 0) { + const next = equalMappings[0]; + const intersects = next.seq1Range.intersects(w1) || next.seq2Range.intersects(w2); + if (!intersects) { + break; + } + + const v1 = sequence1.findWordContaining(next.seq1Range.start); + const v2 = sequence2.findWordContaining(next.seq2Range.start); + // Because there is an intersection, we know that the words are not empty. + const v = new SequenceDiff(v1!, v2!); + const equalPart = v.intersect(next)!; + + equalChars1 += equalPart.seq1Range.length; + equalChars2 += equalPart.seq2Range.length; + + w = w.join(v); + + if (w.seq1Range.endExclusive >= next.seq1Range.endExclusive) { + // The word extends beyond the next equal mapping. + equalMappings.shift(); + } else { + break; + } } - if (Math.max(lastModifiedWord.deleted, lastModifiedWord.added) + (lastModifiedWord.count - 1) > originalLength1) { - additional.push(new SequenceDiff(lastModifiedWord.s1Range, lastModifiedWord.s2Range)); + if (equalChars1 + equalChars2 < (w.seq1Range.length + w.seq2Range.length) * 2 / 3) { + additional.push(new SequenceDiff(w1, w2)); } - lastModifiedWord = undefined; + lastPoint = w.getEndExclusives(); } - for (const s of sequenceDiffs) { - function processWord(s1Range: OffsetRange, s2Range: OffsetRange) { - if (!lastModifiedWord || !lastModifiedWord.s1Range.containsRange(s1Range) || !lastModifiedWord.s2Range.containsRange(s2Range)) { - if (lastModifiedWord && !(lastModifiedWord.s1Range.endExclusive < s1Range.start && lastModifiedWord.s2Range.endExclusive < s2Range.start)) { - const s1Added = OffsetRange.tryCreate(lastModifiedWord.s1Range.endExclusive, s1Range.start); - const s2Added = OffsetRange.tryCreate(lastModifiedWord.s2Range.endExclusive, s2Range.start); - lastModifiedWord.deleted += s1Added?.length ?? 0; - lastModifiedWord.added += s2Added?.length ?? 0; - - lastModifiedWord.s1Range = lastModifiedWord.s1Range.join(s1Range); - lastModifiedWord.s2Range = lastModifiedWord.s2Range.join(s2Range); - } else { - maybePushWordToAdditional(); - lastModifiedWord = { added: 0, deleted: 0, count: 0, s1Range: s1Range, s2Range: s2Range }; - } - } - - const changedS1 = s1Range.intersect(s.seq1Range); - const changedS2 = s2Range.intersect(s.seq2Range); - lastModifiedWord.count++; - lastModifiedWord.deleted += changedS1?.length ?? 0; - lastModifiedWord.added += changedS2?.length ?? 0; - } - - const w1Before = sequence1.findWordContaining(s.seq1Range.start - 1); - const w2Before = sequence2.findWordContaining(s.seq2Range.start - 1); - - const w1After = sequence1.findWordContaining(s.seq1Range.endExclusive); - const w2After = sequence2.findWordContaining(s.seq2Range.endExclusive); - - if (w1Before && w1After && w2Before && w2After && w1Before.equals(w1After) && w2Before.equals(w2After)) { - processWord(w1Before, w2Before); - } else { - if (w1Before && w2Before) { - processWord(w1Before, w2Before); - } - if (w1After && w2After) { - processWord(w1After, w2After); - } + while (equalMappings.length > 0) { + const next = equalMappings.shift()!; + if (next.seq1Range.isEmpty) { + continue; } + scanWord(next.getStarts(), next); + // The equal parts are not empty, so -1 gives us a character that is equal in both parts. + scanWord(next.getEndExclusives().delta(-1), next); } - maybePushWordToAdditional(); - const merged = mergeSequenceDiffs(sequenceDiffs, additional); return merged; } diff --git a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json index 5cbd3c45666..3e4c772917f 100644 --- a/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/class-replacement/advanced.expected.diff.json @@ -23,8 +23,8 @@ "modifiedRange": "[39,40)", "innerChanges": [ { - "originalRange": "[63,9 -> 63,43]", - "modifiedRange": "[39,9 -> 39,38]" + "originalRange": "[63,9 -> 63,48]", + "modifiedRange": "[39,9 -> 39,43]" }, { "originalRange": "[64,1 -> 72,1]", diff --git a/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/advanced.expected.diff.json index 7fee9a6d76d..bf0c792814a 100644 --- a/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/penalize-fragmentation/advanced.expected.diff.json @@ -21,8 +21,8 @@ "modifiedRange": "[2,17 -> 2,17]" }, { - "originalRange": "[1,72 -> 1,73]", - "modifiedRange": "[2,48 -> 2,59]" + "originalRange": "[1,72 -> 1,84]", + "modifiedRange": "[2,48 -> 2,70]" } ] } diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json index dea51256ca6..e5ad584f33e 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing-2/advanced.expected.diff.json @@ -75,12 +75,12 @@ "modifiedRange": "[23,25)", "innerChanges": [ { - "originalRange": "[25,9 -> 26,18]", + "originalRange": "[25,9 -> 26,13]", "modifiedRange": "[23,9 -> 23,18]" }, { - "originalRange": "[26,22 -> 26,27]", - "modifiedRange": "[23,22 -> 23,23]" + "originalRange": "[26,22 -> 26,32]", + "modifiedRange": "[23,22 -> 23,28]" }, { "originalRange": "[27,1 -> 27,1]", diff --git a/src/vs/editor/test/node/diffing/fixtures/ts-confusing/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/ts-confusing/advanced.expected.diff.json index ae0eb5c7342..e9ee88d0a75 100644 --- a/src/vs/editor/test/node/diffing/fixtures/ts-confusing/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/ts-confusing/advanced.expected.diff.json @@ -31,8 +31,8 @@ "modifiedRange": "[11,17 -> 11,17]" }, { - "originalRange": "[10,72 -> 10,73]", - "modifiedRange": "[11,48 -> 11,59]" + "originalRange": "[10,72 -> 10,84]", + "modifiedRange": "[11,48 -> 11,70]" } ] }, diff --git a/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/advanced.expected.diff.json b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/advanced.expected.diff.json index 23feeaa2119..7d964a94419 100644 --- a/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/advanced.expected.diff.json +++ b/src/vs/editor/test/node/diffing/fixtures/word-shared-letters/advanced.expected.diff.json @@ -83,8 +83,12 @@ "modifiedRange": "[43,44)", "innerChanges": [ { - "originalRange": "[43,5 -> 43,16 EOL]", - "modifiedRange": "[43,5 -> 43,11 EOL]" + "originalRange": "[43,8 -> 43,11]", + "modifiedRange": "[43,8 -> 43,8]" + }, + { + "originalRange": "[43,14 -> 43,16 EOL]", + "modifiedRange": "[43,11 -> 43,11 EOL]" } ] }, @@ -108,7 +112,7 @@ "innerChanges": [ { "originalRange": "[53,8 -> 53,17]", - "modifiedRange": "[53,8 -> 53,31]" + "modifiedRange": "[53,8 -> 53,28]" } ] }