From 6b0ef76e677f9add1b35929566941070a4dcbc4d Mon Sep 17 00:00:00 2001 From: Logan Rosen Date: Mon, 14 Jun 2021 00:22:06 -0400 Subject: [PATCH 01/80] Update Stack Overflow tag in CONTRIBUTING.md The Stack Overflow tag has been updated from `vscode` to `visual-studio-code`. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5d547535187..d197d42a083 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,7 +6,7 @@ There are many ways in which you can contribute, beyond writing code. The goal o ## Asking Questions -Have a question? Rather than opening an issue, please ask away on [Stack Overflow](https://stackoverflow.com/questions/tagged/vscode) using the tag `vscode`. +Have a question? Rather than opening an issue, please ask away on [Stack Overflow](https://stackoverflow.com/questions/tagged/visual-studio-code) using the tag `visual-studio-code`. The active community will be eager to assist you. Your well-worded question will serve as a resource to others searching for help. From 712137c205a778cf51835051a3d882ed0d1b7275 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 5 Dec 2023 16:15:00 +0100 Subject: [PATCH 02/80] checking the effective line count is valid before accessing the line content --- src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index 478f3ccd1fc..74405cf62fb 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -211,7 +211,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget { } this.state = new LightBulbState.Showing(actions, trigger, atPosition, { - position: { lineNumber: effectiveLineNumber, column: !!model.getLineContent(effectiveLineNumber).match(/^\S\s*$/) ? 2 : 1 }, + position: { lineNumber: effectiveLineNumber, column: effectiveLineNumber <= model.getLineCount() && !!model.getLineContent(effectiveLineNumber).match(/^\S\s*$/) ? 2 : 1 }, preference: LightBulbWidget._posPref }); this._editor.layoutContentWidget(this); From 4654615a98e386b34330842437756157f91effff Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Dec 2023 12:39:26 +0100 Subject: [PATCH 03/80] placing the check before the effective line number is increased --- src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index 74405cf62fb..7e3350ed2ad 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -201,7 +201,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget { if (!lineHasSpace) { if (lineNumber > 1 && !isFolded(lineNumber - 1)) { effectiveLineNumber -= 1; - } else if (!isFolded(lineNumber + 1)) { + } else if (!isFolded(lineNumber + 1) && lineNumber + 1 <= model.getLineCount()) { effectiveLineNumber += 1; } else if (column * fontInfo.spaceWidth < 22) { // cannot show lightbulb above/below and showing @@ -211,7 +211,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget { } this.state = new LightBulbState.Showing(actions, trigger, atPosition, { - position: { lineNumber: effectiveLineNumber, column: effectiveLineNumber <= model.getLineCount() && !!model.getLineContent(effectiveLineNumber).match(/^\S\s*$/) ? 2 : 1 }, + position: { lineNumber: effectiveLineNumber, column: !!model.getLineContent(effectiveLineNumber).match(/^\S\s*$/) ? 2 : 1 }, preference: LightBulbWidget._posPref }); this._editor.layoutContentWidget(this); From 88e857430c5be0f9ff764c2a499fc67ceac9f11d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Dec 2023 13:43:10 +0100 Subject: [PATCH 04/80] refactoring the content hover ts file --- .../contrib/hover/browser/contentHover.ts | 305 +++++++++++------- src/vs/editor/contrib/hover/browser/hover.ts | 16 +- .../hover/test/browser/contentHover.test.ts | 6 +- 3 files changed, 192 insertions(+), 135 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index c361be19543..f5630ea7fc2 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -29,25 +29,15 @@ import { IAccessibilityService } from 'vs/platform/accessibility/common/accessib const $ = dom.$; -export class ContentHoverController extends Disposable { - - private readonly _participants: IEditorHoverParticipant[]; - - private readonly _widget: ContentHoverWidget; - - getWidgetContent(): string | undefined { - const node = this._widget.getDomNode(); - if (!node.textContent) { - return undefined; - } - return node.textContent; - } - - private readonly _computer: ContentHoverComputer; - private readonly _hoverOperation: HoverOperation; +export class ContentHoverWidget extends Disposable { private _currentResult: HoverResult | null = null; + private readonly _computer: ContentHoverComputer; + private readonly _widget: ResizableContentHoverWidget; + private readonly _participants: IEditorHoverParticipant[]; + private readonly _hoverOperation: HoverOperation; + constructor( private readonly _editor: ICodeEditor, @IInstantiationService private readonly _instantiationService: IInstantiationService, @@ -55,7 +45,7 @@ export class ContentHoverController extends Disposable { ) { super(); - this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); + this._widget = this._register(this._instantiationService.createInstance(ResizableContentHoverWidget, this._editor)); // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; @@ -87,58 +77,17 @@ export class ContentHoverController extends Disposable { })); } - get widget() { - return this._widget; - } - /** * Returns true if the hover shows now or will show. */ - public maybeShowAt(mouseEvent: IEditorMouseEvent): boolean { - if (this._widget.isResizing) { - return true; - } - const anchorCandidates: HoverAnchor[] = []; + private _startShowingOrUpdateHover( + anchor: HoverAnchor | null, + mode: HoverStartMode, + source: HoverStartSource, + focus: boolean, + mouseEvent: IEditorMouseEvent | null + ): boolean { - for (const participant of this._participants) { - if (participant.suggestHoverAnchor) { - const anchor = participant.suggestHoverAnchor(mouseEvent); - if (anchor) { - anchorCandidates.push(anchor); - } - } - } - - const target = mouseEvent.target; - - if (target.type === MouseTargetType.CONTENT_TEXT) { - anchorCandidates.push(new HoverRangeAnchor(0, target.range, mouseEvent.event.posx, mouseEvent.event.posy)); - } - - if (target.type === MouseTargetType.CONTENT_EMPTY) { - const epsilon = this._editor.getOption(EditorOption.fontInfo).typicalHalfwidthCharacterWidth / 2; - if (!target.detail.isAfterLines && typeof target.detail.horizontalDistanceToText === 'number' && target.detail.horizontalDistanceToText < epsilon) { - // Let hover kick in even when the mouse is technically in the empty area after a line, given the distance is small enough - anchorCandidates.push(new HoverRangeAnchor(0, target.range, mouseEvent.event.posx, mouseEvent.event.posy)); - } - } - - if (anchorCandidates.length === 0) { - return this._startShowingOrUpdateHover(null, HoverStartMode.Delayed, HoverStartSource.Mouse, false, mouseEvent); - } - - anchorCandidates.sort((a, b) => b.priority - a.priority); - return this._startShowingOrUpdateHover(anchorCandidates[0], HoverStartMode.Delayed, HoverStartSource.Mouse, false, mouseEvent); - } - - public startShowingAtRange(range: Range, mode: HoverStartMode, source: HoverStartSource, focus: boolean): void { - this._startShowingOrUpdateHover(new HoverRangeAnchor(0, range, undefined, undefined), mode, source, focus, null); - } - - /** - * Returns true if the hover shows now or will show. - */ - private _startShowingOrUpdateHover(anchor: HoverAnchor | null, mode: HoverStartMode, source: HoverStartSource, focus: boolean, mouseEvent: IEditorMouseEvent | null): boolean { if (!this._widget.position || !this._currentResult) { // The hover is not visible if (anchor) { @@ -149,8 +98,13 @@ export class ContentHoverController extends Disposable { } // The hover is currently visible - const hoverIsSticky = this._editor.getOption(EditorOption.hover).sticky; - const isGettingCloser = (hoverIsSticky && mouseEvent && this._widget.isMouseGettingCloser(mouseEvent.event.posx, mouseEvent.event.posy)); + const isHoverSticky = this._editor.getOption(EditorOption.hover).sticky; + const isGettingCloser = ( + isHoverSticky + && mouseEvent + && this._widget.isMouseGettingCloser(mouseEvent.event.posx, mouseEvent.event.posy) + ); + if (isGettingCloser) { // The mouse is getting closer to the hover, so we will keep the hover untouched // But we will kick off a hover update at the new anchor, insisting on keeping the hover visible. @@ -185,11 +139,11 @@ export class ContentHoverController extends Disposable { } private _startHoverOperationIfNecessary(anchor: HoverAnchor, mode: HoverStartMode, source: HoverStartSource, focus: boolean, insistOnKeepingHoverVisible: boolean): void { + if (this._computer.anchor && this._computer.anchor.equals(anchor)) { // We have to start a hover operation at the exact same anchor as before, so no work is needed return; } - this._hoverOperation.cancel(); this._computer.anchor = anchor; this._computer.shouldFocus = focus; @@ -199,6 +153,7 @@ export class ContentHoverController extends Disposable { } private _setCurrentResult(hoverResult: HoverResult | null): void { + if (this._currentResult === hoverResult) { // avoid updating the DOM to avoid resetting the user selection return; @@ -214,36 +169,6 @@ export class ContentHoverController extends Disposable { } } - public hide(): void { - this._computer.anchor = null; - this._hoverOperation.cancel(); - this._setCurrentResult(null); - } - - public get isColorPickerVisible(): boolean { - return this._widget.isColorPickerVisible; - } - - public get isVisibleFromKeyboard(): boolean { - return this._widget.isVisibleFromKeyboard; - } - - public get isVisible(): boolean { - return this._widget.isVisible; - } - - public get isFocused(): boolean { - return this._widget.isFocused; - } - - public get isResizing(): boolean { - return this._widget.isResizing; - } - - public containsNode(node: Node | null | undefined): boolean { - return (node ? this._widget.getDomNode().contains(node) : false); - } - private _addLoadingMessage(result: IHoverPart[]): IHoverPart[] { if (this._computer.anchor) { for (const participant of this._participants) { @@ -277,7 +202,7 @@ export class ContentHoverController extends Disposable { } private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[]): void { - const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverController.computeHoverRanges(this._editor, anchor.range, messages); + const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverWidget.computeHoverRanges(this._editor, anchor.range, messages); const disposables = new DisposableStore(); const statusBar = disposables.add(new EditorHoverStatusBar(this._keybindingService)); @@ -311,7 +236,7 @@ export class ContentHoverController extends Disposable { const highlightDecoration = this._editor.createDecorationsCollection(); highlightDecoration.set([{ range: highlightRange, - options: ContentHoverController._DECORATION_OPTIONS + options: ContentHoverWidget._DECORATION_OPTIONS }]); disposables.add(toDisposable(() => { highlightDecoration.clear(); @@ -319,6 +244,8 @@ export class ContentHoverController extends Disposable { } this._widget.showAt(fragment, new ContentHoverVisibleData( + anchor.initialMousePosX, + anchor.initialMousePosY, colorPicker, showAtPosition, showAtSecondaryPosition, @@ -326,8 +253,6 @@ export class ContentHoverController extends Disposable { this._computer.shouldFocus, this._computer.source, isBeforeContent, - anchor.initialMousePosX, - anchor.initialMousePosY, disposables )); } else { @@ -341,6 +266,7 @@ export class ContentHoverController extends Disposable { }); public static computeHoverRanges(editor: ICodeEditor, anchorRange: Range, messages: IHoverPart[]) { + let startColumnBoundary = 1; if (editor.hasModel()) { // Ensure the range is on the current view line @@ -350,11 +276,12 @@ export class ContentHoverController extends Disposable { const anchorViewRangeStart = new Position(anchorViewRange.startLineNumber, viewModel.getLineMinColumn(anchorViewRange.startLineNumber)); startColumnBoundary = coordinatesConverter.convertViewPositionToModelPosition(anchorViewRangeStart).column; } + // The anchor range is always on a single line const anchorLineNumber = anchorRange.startLineNumber; let renderStartColumn = anchorRange.startColumn; - let highlightRange: Range = messages[0].range; - let forceShowAtRange: Range | null = null; + let highlightRange = messages[0].range; + let forceShowAtRange = null; for (const msg of messages) { highlightRange = Range.plusRange(highlightRange, msg.range); @@ -367,13 +294,77 @@ export class ContentHoverController extends Disposable { } } + const showAtPosition = forceShowAtRange ? forceShowAtRange.getStartPosition() : new Position(anchorLineNumber, anchorRange.startColumn); + const showAtSecondaryPosition = forceShowAtRange ? forceShowAtRange.getStartPosition() : new Position(anchorLineNumber, renderStartColumn); + return { - showAtPosition: forceShowAtRange ? forceShowAtRange.getStartPosition() : new Position(anchorLineNumber, anchorRange.startColumn), - showAtSecondaryPosition: forceShowAtRange ? forceShowAtRange.getStartPosition() : new Position(anchorLineNumber, renderStartColumn), + showAtPosition, + showAtSecondaryPosition, highlightRange }; } + /** + * Returns true if the hover shows now or will show. + */ + public showsOrWillShow(mouseEvent: IEditorMouseEvent): boolean { + + if (this._widget.isResizing) { + return true; + } + + const anchorCandidates: HoverAnchor[] = []; + for (const participant of this._participants) { + if (participant.suggestHoverAnchor) { + const anchor = participant.suggestHoverAnchor(mouseEvent); + if (anchor) { + anchorCandidates.push(anchor); + } + } + } + + const target = mouseEvent.target; + + if (target.type === MouseTargetType.CONTENT_TEXT) { + anchorCandidates.push(new HoverRangeAnchor(0, target.range, mouseEvent.event.posx, mouseEvent.event.posy)); + } + + if (target.type === MouseTargetType.CONTENT_EMPTY) { + const epsilon = this._editor.getOption(EditorOption.fontInfo).typicalHalfwidthCharacterWidth / 2; + if ( + !target.detail.isAfterLines + && typeof target.detail.horizontalDistanceToText === 'number' + && target.detail.horizontalDistanceToText < epsilon + ) { + // Let hover kick in even when the mouse is technically in the empty area after a line, given the distance is small enough + anchorCandidates.push(new HoverRangeAnchor(0, target.range, mouseEvent.event.posx, mouseEvent.event.posy)); + } + } + + if (anchorCandidates.length === 0) { + return this._startShowingOrUpdateHover(null, HoverStartMode.Delayed, HoverStartSource.Mouse, false, mouseEvent); + } + + anchorCandidates.sort((a, b) => b.priority - a.priority); + return this._startShowingOrUpdateHover(anchorCandidates[0], HoverStartMode.Delayed, HoverStartSource.Mouse, false, mouseEvent); + } + + public startShowingAtRange(range: Range, mode: HoverStartMode, source: HoverStartSource, focus: boolean): void { + this._startShowingOrUpdateHover(new HoverRangeAnchor(0, range, undefined, undefined), mode, source, focus, null); + } + + public getWidgetContent(): string | undefined { + const node = this._widget.getDomNode(); + if (!node.textContent) { + return undefined; + } + return node.textContent; + } + + public containsNode(node: Node | null | undefined): boolean { + return (node ? this._widget.getDomNode().contains(node) : false); + } + public focus(): void { this._widget.focus(); } @@ -409,6 +400,36 @@ export class ContentHoverController extends Disposable { public goToBottom(): void { this._widget.goToBottom(); } + + public hide(): void { + this._computer.anchor = null; + this._hoverOperation.cancel(); + this._setCurrentResult(null); + } + + public get isColorPickerVisible(): boolean { + return this._widget.isColorPickerVisible; + } + + public get isVisibleFromKeyboard(): boolean { + return this._widget.isVisibleFromKeyboard; + } + + public get isVisible(): boolean { + return this._widget.isVisible; + } + + public get isFocused(): boolean { + return this._widget.isFocused; + } + + public get isResizing(): boolean { + return this._widget.isResizing; + } + + public get widget() { + return this._widget; + } } class HoverResult { @@ -449,6 +470,8 @@ class ContentHoverVisibleData { public closestMouseDistance: number | undefined = undefined; constructor( + public initialMousePosX: number | undefined, + public initialMousePosY: number | undefined, public readonly colorPicker: IEditorHoverColorPickerWidget | null, public readonly showAtPosition: Position, public readonly showAtSecondaryPosition: Position, @@ -456,8 +479,6 @@ class ContentHoverVisibleData { public readonly stoleFocus: boolean, public readonly source: HoverStartSource, public readonly isBeforeContent: boolean, - public initialMousePosX: number | undefined, - public initialMousePosY: number | undefined, public readonly disposables: DisposableStore ) { } } @@ -466,7 +487,7 @@ const HORIZONTAL_SCROLLING_BY = 30; const SCROLLBAR_WIDTH = 10; const CONTAINER_HEIGHT_PADDING = 6; -export class ContentHoverWidget extends ResizableContentWidget { +export class ResizableContentHoverWidget extends ResizableContentWidget { public static ID = 'editor.contrib.resizableContentHoverWidget'; private static _lastDimensions: dom.Dimension = new dom.Dimension(0, 0); @@ -507,6 +528,7 @@ export class ContentHoverWidget extends ResizableContentWidget { const minimumWidth = 150; const minimumSize = new dom.Dimension(minimumWidth, minimumHeight); super(editor, minimumSize); + this._minimumSize = minimumSize; this._hoverVisibleKey = EditorContextKeys.hoverVisible.bindTo(contextKeyService); this._hoverFocusedKey = EditorContextKeys.hoverFocused.bindTo(contextKeyService); @@ -542,7 +564,7 @@ export class ContentHoverWidget extends ResizableContentWidget { } public getId(): string { - return ContentHoverWidget.ID; + return ResizableContentHoverWidget.ID; } private static _applyDimensions(container: HTMLElement, width: number | string, height: number | string): void { @@ -554,12 +576,12 @@ export class ContentHoverWidget extends ResizableContentWidget { private _setContentsDomNodeDimensions(width: number | string, height: number | string): void { const contentsDomNode = this._hover.contentsDomNode; - return ContentHoverWidget._applyDimensions(contentsDomNode, width, height); + return ResizableContentHoverWidget._applyDimensions(contentsDomNode, width, height); } private _setContainerDomNodeDimensions(width: number | string, height: number | string): void { const containerDomNode = this._hover.containerDomNode; - return ContentHoverWidget._applyDimensions(containerDomNode, width, height); + return ResizableContentHoverWidget._applyDimensions(containerDomNode, width, height); } private _setHoverWidgetDimensions(width: number | string, height: number | string): void { @@ -576,8 +598,8 @@ export class ContentHoverWidget extends ResizableContentWidget { } private _setHoverWidgetMaxDimensions(width: number | string, height: number | string): void { - ContentHoverWidget._applyMaxDimensions(this._hover.contentsDomNode, width, height); - ContentHoverWidget._applyMaxDimensions(this._hover.containerDomNode, width, height); + ResizableContentHoverWidget._applyMaxDimensions(this._hover.contentsDomNode, width, height); + ResizableContentHoverWidget._applyMaxDimensions(this._hover.containerDomNode, width, height); this._hover.containerDomNode.style.setProperty('--vscode-hover-maxWidth', typeof width === 'number' ? `${width}px` : width); this._layoutContentWidget(); } @@ -616,7 +638,7 @@ export class ContentHoverWidget extends ResizableContentWidget { } protected override _resize(size: dom.Dimension): void { - ContentHoverWidget._lastDimensions = new dom.Dimension(size.width, size.height); + ResizableContentHoverWidget._lastDimensions = new dom.Dimension(size.width, size.height); this._setAdjustedHoverWidgetDimensions(size); this._resizableNode.layout(size.height, size.width); this._updateResizableNodeMaxDimensions(); @@ -630,7 +652,9 @@ export class ContentHoverWidget extends ResizableContentWidget { if (!position) { return; } - return this._positionPreference === ContentWidgetPositionPreference.ABOVE ? this._availableVerticalSpaceAbove(position) : this._availableVerticalSpaceBelow(position); + return this._positionPreference === ContentWidgetPositionPreference.ABOVE ? + this._availableVerticalSpaceAbove(position) + : this._availableVerticalSpaceBelow(position); } private _findMaximumRenderingHeight(): number | undefined { @@ -643,6 +667,7 @@ export class ContentHoverWidget extends ResizableContentWidget { Array.from(this._hover.contentsDomNode.children).forEach((hoverPart) => { maximumHeight += hoverPart.clientHeight; }); + if (this._hasHorizontalScrollbar()) { maximumHeight += SCROLLBAR_WIDTH; } @@ -670,7 +695,6 @@ export class ContentHoverWidget extends ResizableContentWidget { } const overflowing = this._isHoverTextOverflowing(); - const initialWidth = ( typeof this._contentWidth === 'undefined' ? 0 @@ -687,10 +711,14 @@ export class ContentHoverWidget extends ResizableContentWidget { } public isMouseGettingCloser(posx: number, posy: number): boolean { + if (!this._visibleData) { return false; } - if (typeof this._visibleData.initialMousePosX === 'undefined' || typeof this._visibleData.initialMousePosY === 'undefined') { + if ( + typeof this._visibleData.initialMousePosX === 'undefined' + || typeof this._visibleData.initialMousePosY === 'undefined' + ) { this._visibleData.initialMousePosX = posx; this._visibleData.initialMousePosY = posy; return false; @@ -698,13 +726,29 @@ export class ContentHoverWidget extends ResizableContentWidget { const widgetRect = dom.getDomNodePagePosition(this.getDomNode()); if (typeof this._visibleData.closestMouseDistance === 'undefined') { - this._visibleData.closestMouseDistance = computeDistanceFromPointToRectangle(this._visibleData.initialMousePosX, this._visibleData.initialMousePosY, widgetRect.left, widgetRect.top, widgetRect.width, widgetRect.height); + this._visibleData.closestMouseDistance = computeDistanceFromPointToRectangle( + this._visibleData.initialMousePosX, + this._visibleData.initialMousePosY, + widgetRect.left, + widgetRect.top, + widgetRect.width, + widgetRect.height + ); } - const distance = computeDistanceFromPointToRectangle(posx, posy, widgetRect.left, widgetRect.top, widgetRect.width, widgetRect.height); + + const distance = computeDistanceFromPointToRectangle( + posx, + posy, + widgetRect.left, + widgetRect.top, + widgetRect.width, + widgetRect.height + ); if (distance > this._visibleData.closestMouseDistance + 4 /* tolerance of 4 pixels */) { // The mouse is getting farther away return false; } + this._visibleData.closestMouseDistance = Math.min(this._visibleData.closestMouseDistance, distance); return true; } @@ -738,8 +782,8 @@ export class ContentHoverWidget extends ResizableContentWidget { } private _updateMaxDimensions() { - const height = Math.max(this._editor.getLayoutInfo().height / 4, 250, ContentHoverWidget._lastDimensions.height); - const width = Math.max(this._editor.getLayoutInfo().width * 0.66, 500, ContentHoverWidget._lastDimensions.width); + const height = Math.max(this._editor.getLayoutInfo().height / 4, 250, ResizableContentHoverWidget._lastDimensions.height); + const width = Math.max(this._editor.getLayoutInfo().width * 0.66, 500, ResizableContentHoverWidget._lastDimensions.width); this._setHoverWidgetMaxDimensions(width, height); } @@ -784,7 +828,11 @@ export class ContentHoverWidget extends ResizableContentWidget { hoverData.colorPicker?.layout(); // The aria label overrides the label, so if we add to it, add the contents of the hover const hoverFocused = this._hover.containerDomNode.ownerDocument.activeElement === this._hover.containerDomNode; - const accessibleViewHint = hoverFocused && getHoverAccessibleViewHint(this._configurationService.getValue('accessibility.verbosity.hover') === true && this._accessibilityService.isScreenReaderOptimized(), this._keybindingService.lookupKeybinding('editor.action.accessibleView')?.getAriaLabel() ?? ''); + const accessibleViewHint = hoverFocused && getHoverAccessibleViewHint( + this._configurationService.getValue('accessibility.verbosity.hover') === true && this._accessibilityService.isScreenReaderOptimized(), + this._keybindingService.lookupKeybinding('editor.action.accessibleView')?.getAriaLabel() ?? '' + ); + if (accessibleViewHint) { this._hover.contentsDomNode.ariaLabel = this._hover.contentsDomNode.textContent + ', ' + accessibleViewHint; } @@ -935,7 +983,13 @@ export class EditorHoverStatusBar extends Disposable implements IEditorHoverStat this.actionsElement = dom.append(this.hoverElement, $('div.actions')); } - public addAction(actionOptions: { label: string; iconClass?: string; run: (target: HTMLElement) => void; commandId: string }): IEditorHoverAction { + public addAction( + actionOptions: { + label: string; + iconClass?: string; run: (target: HTMLElement) => void; + commandId: string; + }): IEditorHoverAction { + const keybinding = this._keybindingService.lookupKeybinding(actionOptions.commandId); const keybindingLabel = keybinding ? keybinding.getLabel() : null; this._hasContent = true; @@ -987,6 +1041,7 @@ class ContentHoverComputer implements IHoverComputer { } const maxColumn = model.getLineMaxColumn(lineNumber); + return editor.getLineDecorations(lineNumber).filter((d) => { if (d.options.isWholeLine) { return true; @@ -994,6 +1049,7 @@ class ContentHoverComputer implements IHoverComputer { const startColumn = (d.range.startLineNumber === lineNumber) ? d.range.startColumn : 1; const endColumn = (d.range.endLineNumber === lineNumber) ? d.range.endColumn : maxColumn; + if (d.options.showIfCollapsed) { // Relax check around `showIfCollapsed` decorations to also include +/- 1 character if (startColumn > anchor.range.startColumn + 1 || anchor.range.endColumn - 1 > endColumn) { @@ -1017,6 +1073,7 @@ class ContentHoverComputer implements IHoverComputer { } const lineDecorations = ContentHoverComputer._getLineDecorations(this._editor, anchor); + return AsyncIterableObject.merge( this._participants.map((participant) => { if (!participant.computeAsync) { diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index f9d1c44c10e..44b953a191c 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -15,7 +15,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { GotoDefinitionAtPositionEditorContribution } from 'vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition'; import { HoverStartMode, HoverStartSource } from 'vs/editor/contrib/hover/browser/hoverOperation'; -import { ContentHoverWidget, ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHover'; +import { ResizableContentHoverWidget, ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover'; import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHover'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -44,7 +44,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut private readonly _toUnhook = new DisposableStore(); - private _contentWidget: ContentHoverController | null; + private _contentWidget: ContentHoverWidget | null; getWidgetContent(): string | undefined { return this._contentWidget?.getWidgetContent(); } @@ -132,7 +132,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut const target = mouseEvent.target; - if (target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID) { + if (target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ResizableContentHoverWidget.ID) { this._hoverClicked = true; // mouse down on top of content hover widget return; @@ -173,7 +173,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut if ( this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET - && target.detail === ContentHoverWidget.ID + && target.detail === ResizableContentHoverWidget.ID ) { // mouse moved on top of content hover widget return true; @@ -189,7 +189,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut if ( !this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET - && target.detail === ContentHoverWidget.ID + && target.detail === ResizableContentHoverWidget.ID && this._contentWidget?.isColorPickerVisible ) { // though the hover is not sticky, the color picker needs to. @@ -264,7 +264,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut const contentWidget = this._getOrCreateContentWidget(); - if (contentWidget.maybeShowAt(mouseEvent)) { + if (contentWidget.showsOrWillShow(mouseEvent)) { this._glyphWidget?.hide(); return; } @@ -324,9 +324,9 @@ export class ModesHoverController extends Disposable implements IEditorContribut this._contentWidget?.hide(); } - private _getOrCreateContentWidget(): ContentHoverController { + private _getOrCreateContentWidget(): ContentHoverWidget { if (!this._contentWidget) { - this._contentWidget = this._instantiationService.createInstance(ContentHoverController, this._editor); + this._contentWidget = this._instantiationService.createInstance(ContentHoverWidget, this._editor); } return this._contentWidget; } diff --git a/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts b/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts index cf05d439031..74140abdea8 100644 --- a/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts +++ b/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHover'; +import { ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover'; import { IHoverPart } from 'vs/editor/contrib/hover/browser/hoverTypes'; import { TestCodeEditorInstantiationOptions, withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; @@ -18,7 +18,7 @@ suite('Content Hover', () => { test('issue #151235: Gitlens hover shows up in the wrong place', () => { const text = 'just some text'; withTestCodeEditor(text, {}, (editor) => { - const actual = ContentHoverController.computeHoverRanges( + const actual = ContentHoverWidget.computeHoverRanges( editor, new Range(5, 5, 5, 5), [{ range: new Range(4, 1, 5, 6) }] @@ -38,7 +38,7 @@ suite('Content Hover', () => { const text = 'just some text'; const opts: TestCodeEditorInstantiationOptions = { wordWrap: 'wordWrapColumn', wordWrapColumn: 6 }; withTestCodeEditor(text, opts, (editor) => { - const actual = ContentHoverController.computeHoverRanges( + const actual = ContentHoverWidget.computeHoverRanges( editor, new Range(1, 8, 1, 8), [{ range: new Range(1, 1, 1, 15) }] From 74177787a4a20ea62b40a39a84a7832acb29f324 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Dec 2023 14:17:37 +0100 Subject: [PATCH 05/80] adding parentheses --- src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index 7e3350ed2ad..eae6dc512d4 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -201,7 +201,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget { if (!lineHasSpace) { if (lineNumber > 1 && !isFolded(lineNumber - 1)) { effectiveLineNumber -= 1; - } else if (!isFolded(lineNumber + 1) && lineNumber + 1 <= model.getLineCount()) { + } else if (!isFolded(lineNumber + 1) && (lineNumber + 1 <= model.getLineCount())) { effectiveLineNumber += 1; } else if (column * fontInfo.spaceWidth < 22) { // cannot show lightbulb above/below and showing From 29d7057198d2cc47cfea416c3c3c454b672a87f1 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Dec 2023 15:49:39 +0100 Subject: [PATCH 06/80] review changes --- .../src/languageFeatures/quickFix.ts | 3 +++ src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts index b37b1cdf7da..9d3ab7fe844 100644 --- a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts +++ b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts @@ -262,6 +262,8 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider 1 && !isFolded(lineNumber - 1)) { effectiveLineNumber -= 1; - } else if (!isFolded(lineNumber + 1) && (lineNumber + 1 <= model.getLineCount())) { + } else if ((lineNumber < model.getLineCount()) && !isFolded(lineNumber + 1)) { effectiveLineNumber += 1; } else if (column * fontInfo.spaceWidth < 22) { // cannot show lightbulb above/below and showing From bc286f4913804c9d7a37df524145ba8c289a4f72 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 6 Dec 2023 16:42:50 +0100 Subject: [PATCH 07/80] removing logs --- .../src/languageFeatures/quickFix.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts index 9d3ab7fe844..b37b1cdf7da 100644 --- a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts +++ b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts @@ -262,8 +262,6 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider Date: Fri, 8 Dec 2023 11:33:50 +0100 Subject: [PATCH 08/80] Added support for custom icons in various editor inputs --- src/vs/base/browser/ui/iconLabel/iconlabel.css | 5 +++++ src/vs/workbench/browser/labels.ts | 12 +++++++++++- .../browser/parts/editor/multiEditorTabsControl.ts | 3 ++- .../browser/parts/editor/singleEditorTabsControl.ts | 1 + src/vs/workbench/common/editor/editorInput.ts | 9 +++++++++ .../contrib/files/browser/views/openEditorsView.ts | 3 ++- .../multiDiffEditor/browser/multiDiffEditorInput.ts | 6 ++++++ .../searchEditor/browser/searchEditorInput.ts | 6 ++++++ .../preferences/browser/keybindingsEditorInput.ts | 6 ++++++ .../preferences/common/preferencesEditorInput.ts | 6 ++++++ 10 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index 47f8891703c..a9f5a4e432f 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -31,6 +31,11 @@ flex-shrink: 0; /* fix for https://github.com/microsoft/vscode/issues/13787 */ } +.monaco-icon-label.product-icon::before{ + font-family: 'codicon'; + font-size: 16px; +} + .monaco-icon-label-container.disabled { color: var(--vscode-disabledForeground); } diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 7fe92930a83..87b5b094c88 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -23,6 +23,7 @@ import { Disposable, dispose, IDisposable, MutableDisposable } from 'vs/base/com import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { normalizeDriveLetter } from 'vs/base/common/labels'; import { IRange } from 'vs/editor/common/core/range'; +import { ThemeIcon } from 'vs/base/common/themables'; export interface IResourceLabelProps { resource?: URI | { primary?: URI; secondary?: URI }; @@ -59,6 +60,11 @@ export interface IResourceLabelOptions extends IIconLabelValueOptions { * Will take the provided label as is and e.g. not override it for untitled files. */ readonly forceLabel?: boolean; + + /** + * Uses the provided icon instead of deriving a resource icon. + */ + readonly codIcon?: ThemeIcon; } export interface IFileLabelOptions extends IResourceLabelOptions { @@ -573,7 +579,11 @@ class ResourceLabelWidget extends IconLabel { if (this.options && !this.options.hideIcon) { if (!this.computedIconClasses) { - this.computedIconClasses = getIconClasses(this.modelService, this.languageService, resource, this.options.fileKind); + if (this.options.codIcon) { + this.computedIconClasses = ['codicon-' + this.options.codIcon.id, 'product-icon']; + } else { + this.computedIconClasses = getIconClasses(this.modelService, this.languageService, resource, this.options.fileKind); + } } iconLabelOptions.extraClasses = this.computedIconClasses.slice(0); diff --git a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts index cd7b815c811..e548cb378a6 100644 --- a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts @@ -1462,7 +1462,8 @@ export class MultiEditorTabsControl extends EditorTabsControl { fileDecorations: { colors: fileDecorationColors, badges: fileDecorationBadges - } + }, + codIcon: editor.getIcon(), } ); diff --git a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts index c28fde093e8..377fac7a22c 100644 --- a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts @@ -323,6 +323,7 @@ export class SingleEditorTabsControl extends EditorTabsControl { colors: Boolean(options.decorations?.colors), badges: Boolean(options.decorations?.badges) }, + codIcon: editor.getIcon(), } ); diff --git a/src/vs/workbench/common/editor/editorInput.ts b/src/vs/workbench/common/editor/editorInput.ts index 556042ce89e..3aa427413f9 100644 --- a/src/vs/workbench/common/editor/editorInput.ts +++ b/src/vs/workbench/common/editor/editorInput.ts @@ -12,6 +12,7 @@ import { isEqual } from 'vs/base/common/resources'; import { ConfirmResult } from 'vs/platform/dialogs/common/dialogs'; import { IMarkdownString } from 'vs/base/common/htmlContent'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { ThemeIcon } from 'vs/base/common/themables'; export interface IEditorCloseHandler { @@ -163,6 +164,14 @@ export abstract class EditorInput extends AbstractEditorInput { return this.getTitle(Verbosity.SHORT); } + /** + * Returns the icon which represents this editor input. + * If undefined, the default icon will be used. + */ + getIcon(): ThemeIcon | undefined { + return undefined; + } + /** * Returns a descriptor suitable for telemetry events. * diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index 61a31c7f638..11c59fb5315 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -650,7 +650,8 @@ class OpenEditorRenderer implements IListRenderer().explorer.decorations, - title: editor.getTitle(Verbosity.LONG) + title: editor.getTitle(Verbosity.LONG), + codIcon: editor.getIcon() }); const editorAction = openedEditor.isSticky() ? this.unpinEditorAction : this.closeEditorAction; if (!templateData.actionBar.hasAction(editorAction)) { diff --git a/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts index 0821f0eba81..1b47ff79835 100644 --- a/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts +++ b/src/vs/workbench/contrib/multiDiffEditor/browser/multiDiffEditorInput.ts @@ -4,10 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import { LazyStatefulPromise, raceTimeout } from 'vs/base/common/async'; +import { Codicon } from 'vs/base/common/codicons'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IMarkdownString } from 'vs/base/common/htmlContent'; import { IDisposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { deepClone } from 'vs/base/common/objects'; +import { ThemeIcon } from 'vs/base/common/themables'; import { isDefined, isObject } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { ConstLazyPromise, IDocumentDiffItem, IMultiDiffEditorModel } from 'vs/editor/browser/widget/multiDiffEditorWidget/model'; @@ -49,6 +51,10 @@ export class MultiDiffEditorInput extends EditorInput implements ILanguageSuppor return DEFAULT_EDITOR_ASSOCIATION.id; } + override getIcon(): ThemeIcon { + return Codicon.diffMultiple; + } + constructor( readonly label: string | undefined, readonly resources: readonly MultiDiffEditorInputData[], diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts index a1511370fa3..be531967ff3 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditorInput.ts @@ -32,6 +32,8 @@ import { bufferToReadable, VSBuffer } from 'vs/base/common/buffer'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IResourceEditorInput } from 'vs/platform/editor/common/editor'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { Codicon } from 'vs/base/common/codicons'; +import { ThemeIcon } from 'vs/base/common/themables'; export type SearchConfiguration = { query: string; @@ -65,6 +67,10 @@ export class SearchEditorInput extends EditorInput { return this.typeId; } + override getIcon(): ThemeIcon { + return Codicon.search; + } + override get capabilities(): EditorInputCapabilities { let capabilities = EditorInputCapabilities.Singleton; if (!this.backingUri) { diff --git a/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts b/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts index 8987b464b18..6cc85208a71 100644 --- a/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts +++ b/src/vs/workbench/services/preferences/browser/keybindingsEditorInput.ts @@ -3,7 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Codicon } from 'vs/base/common/codicons'; import { OS } from 'vs/base/common/platform'; +import { ThemeIcon } from 'vs/base/common/themables'; import * as nls from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IUntypedEditorInput } from 'vs/workbench/common/editor'; @@ -39,6 +41,10 @@ export class KeybindingsEditorInput extends EditorInput { return nls.localize('keybindingsInputName', "Keyboard Shortcuts"); } + override getIcon(): ThemeIcon { + return Codicon.keyboard; + } + override async resolve(): Promise { return this.keybindingsModel; } diff --git a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts index da248022929..6341ccc7e13 100644 --- a/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts +++ b/src/vs/workbench/services/preferences/common/preferencesEditorInput.ts @@ -3,7 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Codicon } from 'vs/base/common/codicons'; import { Schemas } from 'vs/base/common/network'; +import { ThemeIcon } from 'vs/base/common/themables'; import { URI } from 'vs/base/common/uri'; import * as nls from 'vs/nls'; import { IUntypedEditorInput } from 'vs/workbench/common/editor'; @@ -41,6 +43,10 @@ export class SettingsEditor2Input extends EditorInput { return nls.localize('settingsEditor2InputName', "Settings"); } + override getIcon(): ThemeIcon { + return Codicon.settings; + } + override async resolve(): Promise { return this._settingsModel; } From b861c3a6242c97910a80657e5f2966e7f4f4eec4 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Fri, 8 Dec 2023 12:30:23 +0100 Subject: [PATCH 09/80] adapt size --- src/vs/base/browser/ui/iconLabel/iconlabel.css | 3 ++- .../workbench/contrib/extensions/common/extensionsInput.ts | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index a9f5a4e432f..20257d7b41f 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -33,7 +33,8 @@ .monaco-icon-label.product-icon::before{ font-family: 'codicon'; - font-size: 16px; + padding-left: 3px; /* width (16px) - font-size (13px) = padding-left (3px) */ + padding-right: 3px; } .monaco-icon-label-container.disabled { diff --git a/src/vs/workbench/contrib/extensions/common/extensionsInput.ts b/src/vs/workbench/contrib/extensions/common/extensionsInput.ts index 180c12ab35b..ba8664c12d7 100644 --- a/src/vs/workbench/contrib/extensions/common/extensionsInput.ts +++ b/src/vs/workbench/contrib/extensions/common/extensionsInput.ts @@ -12,6 +12,8 @@ import { ExtensionEditorTab, IExtension } from 'vs/workbench/contrib/extensions/ import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { join } from 'vs/base/common/path'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; +import { ThemeIcon } from 'vs/base/common/themables'; +import { Codicon } from 'vs/base/common/codicons'; export interface IExtensionEditorOptions extends IEditorOptions { showPreReleaseVersion?: boolean; @@ -48,6 +50,10 @@ export class ExtensionsInput extends EditorInput { return localize('extensionsInputName', "Extension: {0}", this._extension.displayName); } + override getIcon(): ThemeIcon | undefined { + return Codicon.extensions; + } + override matches(other: EditorInput | IUntypedEditorInput): boolean { if (super.matches(other)) { return true; From 7c732be46685e332f358d5111e018b1dd4208964 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 8 Dec 2023 14:25:30 +0100 Subject: [PATCH 10/80] changing the color of the sparkle to be yellow --- 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 303c4577fa6..6360d9a579b 100644 --- a/src/vs/platform/theme/common/colorRegistry.ts +++ b/src/vs/platform/theme/common/colorRegistry.ts @@ -405,7 +405,7 @@ export const editorInlayHintParameterBackground = registerColor('editorInlayHint */ export const editorLightBulbForeground = registerColor('editorLightBulb.foreground', { dark: '#FFCC00', light: '#DDB100', hcDark: '#FFCC00', hcLight: '#007ACC' }, nls.localize('editorLightBulbForeground', "The color used for the lightbulb actions icon.")); export const editorLightBulbAutoFixForeground = registerColor('editorLightBulbAutoFix.foreground', { dark: '#75BEFF', light: '#007ACC', hcDark: '#75BEFF', hcLight: '#007ACC' }, nls.localize('editorLightBulbAutoFixForeground', "The color used for the lightbulb auto fix actions icon.")); -export const editorLightBulbAiForeground = registerColor('editorLightBulbAi.foreground', { dark: darken(iconForeground, 0.4), light: lighten(iconForeground, 1), hcDark: iconForeground, hcLight: iconForeground }, nls.localize('editorLightBulbAiForeground', "The color used for the lightbulb AI icon.")); +export const editorLightBulbAiForeground = registerColor('editorLightBulbAi.foreground', { dark: editorLightBulbForeground, light: editorLightBulbForeground, hcDark: editorLightBulbForeground, hcLight: editorLightBulbForeground }, nls.localize('editorLightBulbAiForeground', "The color used for the lightbulb AI icon.")); /** * Diff Editor Colors From 287d9ab0e1437b5b514092bc32762272412ed06f Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 8 Dec 2023 15:55:23 +0100 Subject: [PATCH 11/80] undoing the rename --- .../contrib/hover/browser/contentHover.ts | 28 +++++++++---------- src/vs/editor/contrib/hover/browser/hover.ts | 14 +++++----- .../hover/test/browser/contentHover.test.ts | 6 ++-- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHover.ts b/src/vs/editor/contrib/hover/browser/contentHover.ts index f5630ea7fc2..5572e8f5b3d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHover.ts +++ b/src/vs/editor/contrib/hover/browser/contentHover.ts @@ -29,12 +29,12 @@ import { IAccessibilityService } from 'vs/platform/accessibility/common/accessib const $ = dom.$; -export class ContentHoverWidget extends Disposable { +export class ContentHoverController extends Disposable { private _currentResult: HoverResult | null = null; private readonly _computer: ContentHoverComputer; - private readonly _widget: ResizableContentHoverWidget; + private readonly _widget: ContentHoverWidget; private readonly _participants: IEditorHoverParticipant[]; private readonly _hoverOperation: HoverOperation; @@ -45,7 +45,7 @@ export class ContentHoverWidget extends Disposable { ) { super(); - this._widget = this._register(this._instantiationService.createInstance(ResizableContentHoverWidget, this._editor)); + this._widget = this._register(this._instantiationService.createInstance(ContentHoverWidget, this._editor)); // Instantiate participants and sort them by `hoverOrdinal` which is relevant for rendering order. this._participants = []; @@ -202,7 +202,7 @@ export class ContentHoverWidget extends Disposable { } private _renderMessages(anchor: HoverAnchor, messages: IHoverPart[]): void { - const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverWidget.computeHoverRanges(this._editor, anchor.range, messages); + const { showAtPosition, showAtSecondaryPosition, highlightRange } = ContentHoverController.computeHoverRanges(this._editor, anchor.range, messages); const disposables = new DisposableStore(); const statusBar = disposables.add(new EditorHoverStatusBar(this._keybindingService)); @@ -236,7 +236,7 @@ export class ContentHoverWidget extends Disposable { const highlightDecoration = this._editor.createDecorationsCollection(); highlightDecoration.set([{ range: highlightRange, - options: ContentHoverWidget._DECORATION_OPTIONS + options: ContentHoverController._DECORATION_OPTIONS }]); disposables.add(toDisposable(() => { highlightDecoration.clear(); @@ -487,7 +487,7 @@ const HORIZONTAL_SCROLLING_BY = 30; const SCROLLBAR_WIDTH = 10; const CONTAINER_HEIGHT_PADDING = 6; -export class ResizableContentHoverWidget extends ResizableContentWidget { +export class ContentHoverWidget extends ResizableContentWidget { public static ID = 'editor.contrib.resizableContentHoverWidget'; private static _lastDimensions: dom.Dimension = new dom.Dimension(0, 0); @@ -564,7 +564,7 @@ export class ResizableContentHoverWidget extends ResizableContentWidget { } public getId(): string { - return ResizableContentHoverWidget.ID; + return ContentHoverWidget.ID; } private static _applyDimensions(container: HTMLElement, width: number | string, height: number | string): void { @@ -576,12 +576,12 @@ export class ResizableContentHoverWidget extends ResizableContentWidget { private _setContentsDomNodeDimensions(width: number | string, height: number | string): void { const contentsDomNode = this._hover.contentsDomNode; - return ResizableContentHoverWidget._applyDimensions(contentsDomNode, width, height); + return ContentHoverWidget._applyDimensions(contentsDomNode, width, height); } private _setContainerDomNodeDimensions(width: number | string, height: number | string): void { const containerDomNode = this._hover.containerDomNode; - return ResizableContentHoverWidget._applyDimensions(containerDomNode, width, height); + return ContentHoverWidget._applyDimensions(containerDomNode, width, height); } private _setHoverWidgetDimensions(width: number | string, height: number | string): void { @@ -598,8 +598,8 @@ export class ResizableContentHoverWidget extends ResizableContentWidget { } private _setHoverWidgetMaxDimensions(width: number | string, height: number | string): void { - ResizableContentHoverWidget._applyMaxDimensions(this._hover.contentsDomNode, width, height); - ResizableContentHoverWidget._applyMaxDimensions(this._hover.containerDomNode, width, height); + ContentHoverWidget._applyMaxDimensions(this._hover.contentsDomNode, width, height); + ContentHoverWidget._applyMaxDimensions(this._hover.containerDomNode, width, height); this._hover.containerDomNode.style.setProperty('--vscode-hover-maxWidth', typeof width === 'number' ? `${width}px` : width); this._layoutContentWidget(); } @@ -638,7 +638,7 @@ export class ResizableContentHoverWidget extends ResizableContentWidget { } protected override _resize(size: dom.Dimension): void { - ResizableContentHoverWidget._lastDimensions = new dom.Dimension(size.width, size.height); + ContentHoverWidget._lastDimensions = new dom.Dimension(size.width, size.height); this._setAdjustedHoverWidgetDimensions(size); this._resizableNode.layout(size.height, size.width); this._updateResizableNodeMaxDimensions(); @@ -782,8 +782,8 @@ export class ResizableContentHoverWidget extends ResizableContentWidget { } private _updateMaxDimensions() { - const height = Math.max(this._editor.getLayoutInfo().height / 4, 250, ResizableContentHoverWidget._lastDimensions.height); - const width = Math.max(this._editor.getLayoutInfo().width * 0.66, 500, ResizableContentHoverWidget._lastDimensions.width); + const height = Math.max(this._editor.getLayoutInfo().height / 4, 250, ContentHoverWidget._lastDimensions.height); + const width = Math.max(this._editor.getLayoutInfo().width * 0.66, 500, ContentHoverWidget._lastDimensions.width); this._setHoverWidgetMaxDimensions(width, height); } diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index 44b953a191c..f4fb86e9868 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -15,7 +15,7 @@ import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { GotoDefinitionAtPositionEditorContribution } from 'vs/editor/contrib/gotoSymbol/browser/link/goToDefinitionAtPosition'; import { HoverStartMode, HoverStartSource } from 'vs/editor/contrib/hover/browser/hoverOperation'; -import { ResizableContentHoverWidget, ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover'; +import { ContentHoverWidget, ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHover'; import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHover'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -44,7 +44,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut private readonly _toUnhook = new DisposableStore(); - private _contentWidget: ContentHoverWidget | null; + private _contentWidget: ContentHoverController | null; getWidgetContent(): string | undefined { return this._contentWidget?.getWidgetContent(); } @@ -132,7 +132,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut const target = mouseEvent.target; - if (target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ResizableContentHoverWidget.ID) { + if (target.type === MouseTargetType.CONTENT_WIDGET && target.detail === ContentHoverWidget.ID) { this._hoverClicked = true; // mouse down on top of content hover widget return; @@ -173,7 +173,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut if ( this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET - && target.detail === ResizableContentHoverWidget.ID + && target.detail === ContentHoverWidget.ID ) { // mouse moved on top of content hover widget return true; @@ -189,7 +189,7 @@ export class ModesHoverController extends Disposable implements IEditorContribut if ( !this._isHoverSticky && target.type === MouseTargetType.CONTENT_WIDGET - && target.detail === ResizableContentHoverWidget.ID + && target.detail === ContentHoverWidget.ID && this._contentWidget?.isColorPickerVisible ) { // though the hover is not sticky, the color picker needs to. @@ -324,9 +324,9 @@ export class ModesHoverController extends Disposable implements IEditorContribut this._contentWidget?.hide(); } - private _getOrCreateContentWidget(): ContentHoverWidget { + private _getOrCreateContentWidget(): ContentHoverController { if (!this._contentWidget) { - this._contentWidget = this._instantiationService.createInstance(ContentHoverWidget, this._editor); + this._contentWidget = this._instantiationService.createInstance(ContentHoverController, this._editor); } return this._contentWidget; } diff --git a/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts b/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts index 74140abdea8..cf05d439031 100644 --- a/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts +++ b/src/vs/editor/contrib/hover/test/browser/contentHover.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover'; +import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHover'; import { IHoverPart } from 'vs/editor/contrib/hover/browser/hoverTypes'; import { TestCodeEditorInstantiationOptions, withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; @@ -18,7 +18,7 @@ suite('Content Hover', () => { test('issue #151235: Gitlens hover shows up in the wrong place', () => { const text = 'just some text'; withTestCodeEditor(text, {}, (editor) => { - const actual = ContentHoverWidget.computeHoverRanges( + const actual = ContentHoverController.computeHoverRanges( editor, new Range(5, 5, 5, 5), [{ range: new Range(4, 1, 5, 6) }] @@ -38,7 +38,7 @@ suite('Content Hover', () => { const text = 'just some text'; const opts: TestCodeEditorInstantiationOptions = { wordWrap: 'wordWrapColumn', wordWrapColumn: 6 }; withTestCodeEditor(text, opts, (editor) => { - const actual = ContentHoverWidget.computeHoverRanges( + const actual = ContentHoverController.computeHoverRanges( editor, new Range(1, 8, 1, 8), [{ range: new Range(1, 1, 1, 15) }] From d45c2c27ebb0f3dee7c8350495aed6108737aaae Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Fri, 8 Dec 2023 16:05:26 +0100 Subject: [PATCH 12/80] :lipstick: --- src/vs/workbench/browser/labels.ts | 6 +++--- .../browser/parts/editor/multiEditorTabsControl.ts | 2 +- .../browser/parts/editor/singleEditorTabsControl.ts | 2 +- .../contrib/files/browser/views/openEditorsView.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 87b5b094c88..0c1df0ae564 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -64,7 +64,7 @@ export interface IResourceLabelOptions extends IIconLabelValueOptions { /** * Uses the provided icon instead of deriving a resource icon. */ - readonly codIcon?: ThemeIcon; + readonly icon?: ThemeIcon; } export interface IFileLabelOptions extends IResourceLabelOptions { @@ -579,8 +579,8 @@ class ResourceLabelWidget extends IconLabel { if (this.options && !this.options.hideIcon) { if (!this.computedIconClasses) { - if (this.options.codIcon) { - this.computedIconClasses = ['codicon-' + this.options.codIcon.id, 'product-icon']; + if (this.options.icon) { + this.computedIconClasses = ['codicon-' + this.options.icon.id, 'product-icon']; } else { this.computedIconClasses = getIconClasses(this.modelService, this.languageService, resource, this.options.fileKind); } diff --git a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts index e548cb378a6..44b78688c4a 100644 --- a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts @@ -1463,7 +1463,7 @@ export class MultiEditorTabsControl extends EditorTabsControl { colors: fileDecorationColors, badges: fileDecorationBadges }, - codIcon: editor.getIcon(), + icon: editor.getIcon(), } ); diff --git a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts index 377fac7a22c..e0e5bbc9c7e 100644 --- a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts @@ -323,7 +323,7 @@ export class SingleEditorTabsControl extends EditorTabsControl { colors: Boolean(options.decorations?.colors), badges: Boolean(options.decorations?.badges) }, - codIcon: editor.getIcon(), + icon: editor.getIcon(), } ); diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index 11c59fb5315..26459470d7d 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -651,7 +651,7 @@ class OpenEditorRenderer implements IListRenderer().explorer.decorations, title: editor.getTitle(Verbosity.LONG), - codIcon: editor.getIcon() + icon: editor.getIcon() }); const editorAction = openedEditor.isSticky() ? this.unpinEditorAction : this.closeEditorAction; if (!templateData.actionBar.hasAction(editorAction)) { From fb019c37d0b68d7bff82438e75953a7fd64999af Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Fri, 8 Dec 2023 16:32:21 +0100 Subject: [PATCH 13/80] :lipstick: --- src/vs/base/browser/ui/iconLabel/iconlabel.css | 2 +- src/vs/workbench/browser/labels.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index 20257d7b41f..df3d44593df 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -31,7 +31,7 @@ flex-shrink: 0; /* fix for https://github.com/microsoft/vscode/issues/13787 */ } -.monaco-icon-label.product-icon::before{ +.monaco-icon-label.product-icon::before { font-family: 'codicon'; padding-left: 3px; /* width (16px) - font-size (13px) = padding-left (3px) */ padding-right: 3px; diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 0c1df0ae564..4fe48917bf0 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -580,7 +580,7 @@ class ResourceLabelWidget extends IconLabel { if (this.options && !this.options.hideIcon) { if (!this.computedIconClasses) { if (this.options.icon) { - this.computedIconClasses = ['codicon-' + this.options.icon.id, 'product-icon']; + this.computedIconClasses = [`codicon-${this.options.icon.id}`, 'product-icon']; } else { this.computedIconClasses = getIconClasses(this.modelService, this.languageService, resource, this.options.fileKind); } From bb05ee67d65322a322954afe0e01ba855d207a92 Mon Sep 17 00:00:00 2001 From: Simon Siefke Date: Fri, 8 Dec 2023 17:35:59 +0100 Subject: [PATCH 14/80] fix: memory leak in diff editor --- .../features/revertButtonsFeature.ts | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts b/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts index 0bf0d8c2b73..084706bf613 100644 --- a/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts +++ b/src/vs/editor/browser/widget/diffEditor/features/revertButtonsFeature.ts @@ -3,6 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { addDisposableListener, h, EventType } from 'vs/base/browser/dom'; +import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { Codicon } from 'vs/base/common/codicons'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IObservable, autorunWithStore, derived } from 'vs/base/common/observable'; import { IGlyphMarginWidget, IGlyphMarginWidgetPosition } from 'vs/editor/browser/editorBrowser'; @@ -12,12 +15,9 @@ import { DiffEditorViewModel } from 'vs/editor/browser/widget/diffEditor/diffEdi import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditor/diffEditorWidget'; import { LineRange, LineRangeSet } from 'vs/editor/common/core/lineRange'; import { Range } from 'vs/editor/common/core/range'; +import { RangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { GlyphMarginLane } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; -import { RangeMapping } from 'vs/editor/common/diff/rangeMapping'; -import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels'; -import { Codicon } from 'vs/base/common/codicons'; -import { h } from 'vs/base/browser/dom'; export class RevertButtonsFeature extends Disposable { constructor( @@ -69,7 +69,7 @@ export class RevertButtonsFeature extends Disposable { if (selectedDiffs_.length > 0) { const selections = this._editors.modifiedSelections.read(reader); - const btn = new RevertButton(selections[selections.length - 1].positionLineNumber, this._widget, selectedDiffs_.flatMap(d => d.rangeMappings), true); + const btn = store.add(new RevertButton(selections[selections.length - 1].positionLineNumber, this._widget, selectedDiffs_.flatMap(d => d.rangeMappings), true)); this._editors.modified.addGlyphMarginWidget(btn); glyphWidgetsModified.push(btn); } @@ -79,7 +79,7 @@ export class RevertButtonsFeature extends Disposable { continue; } if (!m.lineRangeMapping.modified.isEmpty && m.lineRangeMapping.innerChanges) { - const btn = new RevertButton(m.lineRangeMapping.modified.startLineNumber, this._widget, m.lineRangeMapping.innerChanges, false); + const btn = store.add(new RevertButton(m.lineRangeMapping.modified.startLineNumber, this._widget, m.lineRangeMapping.innerChanges, false)); this._editors.modified.addGlyphMarginWidget(btn); glyphWidgetsModified.push(btn); } @@ -94,7 +94,7 @@ export class RevertButtonsFeature extends Disposable { } } -export class RevertButton implements IGlyphMarginWidget { +export class RevertButton extends Disposable implements IGlyphMarginWidget { public static counter = 0; private readonly _id: string = `revertButton${RevertButton.counter++}`; @@ -115,22 +115,27 @@ export class RevertButton implements IGlyphMarginWidget { private readonly _diffs: RangeMapping[], private readonly _selection: boolean, ) { - this._domNode.onmousedown = e => { + super(); + + + this._register(addDisposableListener(this._domNode, EventType.MOUSE_DOWN, e => { // don't prevent context menu from showing up if (e.button !== 2) { e.stopPropagation(); e.preventDefault(); } - }; - this._domNode.onmouseup = e => { + })); + + this._register(addDisposableListener(this._domNode, EventType.MOUSE_UP, e => { e.stopPropagation(); e.preventDefault(); - }; - this._domNode.onclick = (e) => { + })); + + this._register(addDisposableListener(this._domNode, EventType.CLICK, (e) => { this._widget.revertRangeMappings(this._diffs); e.stopPropagation(); e.preventDefault(); - }; + })); } /** From 7c7c1855b3496f42882418a21c25fbeaac1f8ce5 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 8 Dec 2023 18:22:04 +0100 Subject: [PATCH 15/80] placing the check effective column number into the if statement --- src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index c0527af4aba..fd61d1b0171 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -198,6 +198,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget { }; let effectiveLineNumber = lineNumber; + let effectiveColumnNumber = 1; if (!lineHasSpace) { if (lineNumber > 1 && !isFolded(lineNumber - 1)) { effectiveLineNumber -= 1; @@ -208,10 +209,11 @@ export class LightBulbWidget extends Disposable implements IContentWidget { // it inline would overlay the cursor... return this.hide(); } + effectiveColumnNumber = !!model.getLineContent(effectiveLineNumber).match(/^\S\s*$/) ? 2 : 1; } this.state = new LightBulbState.Showing(actions, trigger, atPosition, { - position: { lineNumber: effectiveLineNumber, column: !!model.getLineContent(effectiveLineNumber).match(/^\S\s*$/) ? 2 : 1 }, + position: { lineNumber: effectiveLineNumber, column: effectiveColumnNumber }, preference: LightBulbWidget._posPref }); this._editor.layoutContentWidget(this); From bcb4fd8c2050f5d8e9c5bbdce7604d97b1eb5198 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sat, 9 Dec 2023 14:28:58 +0100 Subject: [PATCH 16/80] hide codicons --- src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts index 44b78688c4a..9bdf29a3be5 100644 --- a/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.ts @@ -1464,6 +1464,7 @@ export class MultiEditorTabsControl extends EditorTabsControl { badges: fileDecorationBadges }, icon: editor.getIcon(), + hideIcon: options.showIcons === false, } ); From d0fa890a6521fce10ebda2a2bb793ca0a55b08d5 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sat, 9 Dec 2023 15:00:13 +0100 Subject: [PATCH 17/80] Refactored getIconClasses function to accept optional ThemeIcon parameter and updated its usage across multiple files --- src/vs/editor/common/services/getIconClasses.ts | 6 +++++- src/vs/workbench/browser/labels.ts | 7 ++----- src/vs/workbench/browser/parts/editor/editorQuickAccess.ts | 2 +- .../contrib/search/browser/anythingQuickAccess.ts | 4 +++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/common/services/getIconClasses.ts b/src/vs/editor/common/services/getIconClasses.ts index bc3da1e5e6c..0df1d17f6ee 100644 --- a/src/vs/editor/common/services/getIconClasses.ts +++ b/src/vs/editor/common/services/getIconClasses.ts @@ -10,10 +10,14 @@ import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry' import { ILanguageService } from 'vs/editor/common/languages/language'; import { IModelService } from 'vs/editor/common/services/model'; import { FileKind } from 'vs/platform/files/common/files'; +import { ThemeIcon } from 'vs/base/common/themables'; const fileIconDirectoryRegex = /(?:\/|^)(?:([^\/]+)\/)?([^\/]+)$/; -export function getIconClasses(modelService: IModelService, languageService: ILanguageService, resource: uri | undefined, fileKind?: FileKind): string[] { +export function getIconClasses(modelService: IModelService, languageService: ILanguageService, resource: uri | undefined, fileKind?: FileKind, icon?: ThemeIcon): string[] { + if (icon) { + return [`codicon-${icon.id}`, 'product-icon']; + } // we always set these base classes even if we do not have a path const classes = fileKind === FileKind.ROOT_FOLDER ? ['rootfolder-icon'] : fileKind === FileKind.FOLDER ? ['folder-icon'] : ['file-icon']; diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 4fe48917bf0..93309d1daf4 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -579,11 +579,8 @@ class ResourceLabelWidget extends IconLabel { if (this.options && !this.options.hideIcon) { if (!this.computedIconClasses) { - if (this.options.icon) { - this.computedIconClasses = [`codicon-${this.options.icon.id}`, 'product-icon']; - } else { - this.computedIconClasses = getIconClasses(this.modelService, this.languageService, resource, this.options.fileKind); - } + this.computedIconClasses = getIconClasses(this.modelService, this.languageService, resource, this.options.fileKind, this.options.icon); + } iconLabelOptions.extraClasses = this.computedIconClasses.slice(0); diff --git a/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts index 26553c5730f..225330438f6 100644 --- a/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts +++ b/src/vs/workbench/browser/parts/editor/editorQuickAccess.ts @@ -157,7 +157,7 @@ export abstract class BaseEditorQuickAccessProvider extends PickerQuickAccessPro return isDirty ? localize('entryAriaLabelDirty', "{0}, unsaved changes", nameAndDescription) : nameAndDescription; })(), description, - iconClasses: getIconClasses(this.modelService, this.languageService, resource).concat(editor.getLabelExtraClasses()), + iconClasses: getIconClasses(this.modelService, this.languageService, resource, undefined, editor.getIcon()).concat(editor.getLabelExtraClasses()), italic: !this.editorGroupService.getGroup(groupId)?.isPinned(editor), buttons: (() => { return [ diff --git a/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts b/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts index 35317213619..44360742523 100644 --- a/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts @@ -951,6 +951,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider getIconClasses(this.modelService, this.languageService, resource).concat(extraClasses)); + const iconClassesValue = new Lazy(() => getIconClasses(this.modelService, this.languageService, resource, undefined, icon).concat(extraClasses)); const buttonsValue = new Lazy(() => { const openSideBySideDirection = configuration.openSideBySideDirection; From 30a352a72761333f92c118a1f4476d44f589cb92 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sat, 9 Dec 2023 15:15:11 +0100 Subject: [PATCH 18/80] move css --- src/vs/base/browser/ui/iconLabel/iconlabel.css | 6 ------ src/vs/workbench/browser/media/style.css | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index df3d44593df..47f8891703c 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -31,12 +31,6 @@ flex-shrink: 0; /* fix for https://github.com/microsoft/vscode/issues/13787 */ } -.monaco-icon-label.product-icon::before { - font-family: 'codicon'; - padding-left: 3px; /* width (16px) - font-size (13px) = padding-left (3px) */ - padding-right: 3px; -} - .monaco-icon-label-container.disabled { color: var(--vscode-disabledForeground); } diff --git a/src/vs/workbench/browser/media/style.css b/src/vs/workbench/browser/media/style.css index 87ee974d535..c0ef8e0e953 100644 --- a/src/vs/workbench/browser/media/style.css +++ b/src/vs/workbench/browser/media/style.css @@ -150,6 +150,12 @@ body.web { font-size: 16px; /* sets font-size for codicons in workbench (https://github.com/microsoft/vscode/issues/98495) */ } +.monaco-workbench .monaco-icon-label.product-icon::before { + font-family: 'codicon'; + padding-left: 3px; /* width (16px) - font-size (13px) = padding-left (3px) */ + padding-right: 3px; +} + .monaco-workbench.modal-dialog-visible .monaco-progress-container.infinite .progress-bit { display: none; /* stop progress animations when dialogs are visible (https://github.com/microsoft/vscode/issues/138396) */ } From 3b4d17d77b5c085b09398f1f25ce51839d751200 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sat, 9 Dec 2023 15:20:57 +0100 Subject: [PATCH 19/80] :lipstick: --- src/vs/workbench/browser/media/style.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/media/style.css b/src/vs/workbench/browser/media/style.css index c0ef8e0e953..6c52fb2c369 100644 --- a/src/vs/workbench/browser/media/style.css +++ b/src/vs/workbench/browser/media/style.css @@ -150,8 +150,9 @@ body.web { font-size: 16px; /* sets font-size for codicons in workbench (https://github.com/microsoft/vscode/issues/98495) */ } -.monaco-workbench .monaco-icon-label.product-icon::before { +.monaco-workbench .product-icon[class*='codicon-']::before { font-family: 'codicon'; + width: 16px; padding-left: 3px; /* width (16px) - font-size (13px) = padding-left (3px) */ padding-right: 3px; } From 88864a3f13af23c9e6f59c586f3d2967e66bb818 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 10 Dec 2023 11:56:43 +0100 Subject: [PATCH 20/80] chat editor icon --- .../workbench/contrib/chat/browser/chatEditorInput.ts | 6 ++++-- .../contrib/chat/browser/media/chatEditor.css | 11 ----------- 2 files changed, 4 insertions(+), 13 deletions(-) delete mode 100644 src/vs/workbench/contrib/chat/browser/media/chatEditor.css diff --git a/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts b/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts index ed7152d1d44..310cd7658d0 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts @@ -4,9 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { CancellationToken } from 'vs/base/common/cancellation'; +import { Codicon } from 'vs/base/common/codicons'; import { Emitter } from 'vs/base/common/event'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; +import { ThemeIcon } from 'vs/base/common/themables'; import { URI } from 'vs/base/common/uri'; import * as nls from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -81,8 +83,8 @@ export class ChatEditorInput extends EditorInput { return this.model?.title || nls.localize('chatEditorName', "Chat") + (this.inputCount > 0 ? ` ${this.inputCount + 1}` : ''); } - override getLabelExtraClasses(): string[] { - return ['chat-editor-label']; + override getIcon(): ThemeIcon { + return Codicon.commentDiscussion; } override async resolve(): Promise { diff --git a/src/vs/workbench/contrib/chat/browser/media/chatEditor.css b/src/vs/workbench/contrib/chat/browser/media/chatEditor.css deleted file mode 100644 index fb57658b021..00000000000 --- a/src/vs/workbench/contrib/chat/browser/media/chatEditor.css +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -.vs .show-file-icons .chat-editor-label.file-icon::before, -.show-file-icons .chat-editor-label.file-icon::before { - content: '\EAC7'; - font-family: 'codicon'; - font-size: 16px; -} From 94687d50dfd7dbfe873f776d34a7328c2db30893 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 10 Dec 2023 11:58:52 +0100 Subject: [PATCH 21/80] Terminal theme icon support --- .../contrib/terminal/browser/media/terminal.css | 5 ----- .../contrib/terminal/browser/terminalEditorInput.ts | 12 ++++++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/terminal.css b/src/vs/workbench/contrib/terminal/browser/media/terminal.css index a934dae26c7..488815cf258 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/terminal.css +++ b/src/vs/workbench/contrib/terminal/browser/media/terminal.css @@ -58,11 +58,6 @@ opacity: 0 !important; } -.monaco-workbench .terminal-tab::before { - font-family: 'codicon' !important; - font-size: 16px !important; -} - .monaco-workbench .terminal-tab:not(.terminal-uri-icon)::before { background-image: none !important; } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts index 2c4cafe5172..94d3ce8960a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalEditorInput.ts @@ -191,11 +191,18 @@ export class TerminalEditorInput extends EditorInput implements IEditorCloseHand return this._terminalInstance?.title || this.resource.fragment; } + override getIcon(): ThemeIcon | undefined { + if (!this._terminalInstance || !ThemeIcon.isThemeIcon(this._terminalInstance.icon)) { + return undefined; + } + return this._terminalInstance.icon; + } + override getLabelExtraClasses(): string[] { if (!this._terminalInstance) { return []; } - const extraClasses: string[] = ['terminal-tab']; + const extraClasses: string[] = ['terminal-tab', 'product-icon']; const colorClass = getColorClass(this._terminalInstance); if (colorClass) { extraClasses.push(colorClass); @@ -204,9 +211,6 @@ export class TerminalEditorInput extends EditorInput implements IEditorCloseHand if (uriClasses) { extraClasses.push(...uriClasses); } - if (ThemeIcon.isThemeIcon(this._terminalInstance.icon)) { - extraClasses.push(`codicon-${this._terminalInstance.icon.id}`); - } return extraClasses; } From 15a273248e5a9e25cd83244ab3ee21ced540e67b Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 10 Dec 2023 12:14:50 +0100 Subject: [PATCH 22/80] Runtime extensions --- .../contrib/extensions/common/runtimeExtensionsInput.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/extensions/common/runtimeExtensionsInput.ts b/src/vs/workbench/contrib/extensions/common/runtimeExtensionsInput.ts index e7df1f9f846..51069228bb6 100644 --- a/src/vs/workbench/contrib/extensions/common/runtimeExtensionsInput.ts +++ b/src/vs/workbench/contrib/extensions/common/runtimeExtensionsInput.ts @@ -7,6 +7,8 @@ import * as nls from 'vs/nls'; import { URI } from 'vs/base/common/uri'; import { EditorInputCapabilities, IUntypedEditorInput } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; +import { ThemeIcon } from 'vs/base/common/themables'; +import { Codicon } from 'vs/base/common/codicons'; export class RuntimeExtensionsInput extends EditorInput { @@ -38,6 +40,10 @@ export class RuntimeExtensionsInput extends EditorInput { return nls.localize('extensionsInputName', "Running Extensions"); } + override getIcon(): ThemeIcon { + return Codicon.extensions; + } + override matches(other: EditorInput | IUntypedEditorInput): boolean { if (super.matches(other)) { return true; From 787dfdc6b4b3f3f7df834fd89c7da1d72e1ea0fe Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 10 Dec 2023 12:19:28 +0100 Subject: [PATCH 23/80] DisassemblyViewInput --- .../workbench/contrib/debug/common/disassemblyViewInput.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/debug/common/disassemblyViewInput.ts b/src/vs/workbench/contrib/debug/common/disassemblyViewInput.ts index f66b095f686..75d4548b4a6 100644 --- a/src/vs/workbench/contrib/debug/common/disassemblyViewInput.ts +++ b/src/vs/workbench/contrib/debug/common/disassemblyViewInput.ts @@ -5,6 +5,8 @@ import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { localize } from 'vs/nls'; +import { ThemeIcon } from 'vs/base/common/themables'; +import { Codicon } from 'vs/base/common/codicons'; export class DisassemblyViewInput extends EditorInput { @@ -29,6 +31,10 @@ export class DisassemblyViewInput extends EditorInput { return localize('disassemblyInputName', "Disassembly"); } + override getIcon(): ThemeIcon { + return Codicon.debug; + } + override matches(other: unknown): boolean { return other instanceof DisassemblyViewInput; } From 0202181a0dfc8aff1dc9f0ae59ce62600eea8324 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 10 Dec 2023 12:29:11 +0100 Subject: [PATCH 24/80] Workspace Trust --- .../workspace/browser/media/workspaceTrustEditor.css | 7 ------- .../workspaces/browser/workspaceTrustEditorInput.ts | 6 ++++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/workspace/browser/media/workspaceTrustEditor.css b/src/vs/workbench/contrib/workspace/browser/media/workspaceTrustEditor.css index 74ccb4fdf7f..ce487f6cf7b 100644 --- a/src/vs/workbench/contrib/workspace/browser/media/workspaceTrustEditor.css +++ b/src/vs/workbench/contrib/workspace/browser/media/workspaceTrustEditor.css @@ -3,13 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -.monaco-icon-label.file-icon.workspacetrusteditor-name-file-icon.ext-file-icon.tab-label::before { - font-family: 'codicon'; - content: '\eb53'; - background-image: none; - font-size: 16px; -} - .workspace-trust-editor { max-width: 1000px; padding-top: 11px; diff --git a/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts b/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts index 518b94cce20..8a7d78c3f37 100644 --- a/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts +++ b/src/vs/workbench/services/workspaces/browser/workspaceTrustEditorInput.ts @@ -3,7 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Codicon } from 'vs/base/common/codicons'; import { Schemas } from 'vs/base/common/network'; +import { ThemeIcon } from 'vs/base/common/themables'; import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { EditorInputCapabilities, IUntypedEditorInput } from 'vs/workbench/common/editor'; @@ -32,4 +34,8 @@ export class WorkspaceTrustEditorInput extends EditorInput { override getName(): string { return localize('workspaceTrustEditorInputName', "Workspace Trust"); } + + override getIcon(): ThemeIcon { + return Codicon.shield; + } } From 61a86046786d0af6cb3f6b730893a6b10c1af2a0 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Sun, 10 Dec 2023 12:48:35 +0100 Subject: [PATCH 25/80] :lipstick: --- src/vs/workbench/contrib/chat/browser/chatEditor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatEditor.ts b/src/vs/workbench/contrib/chat/browser/chatEditor.ts index 28724b58422..ee8045df6c3 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditor.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditor.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./media/chatEditor'; import * as dom from 'vs/base/browser/dom'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IContextKeyService, IScopedContextKeyService } from 'vs/platform/contextkey/common/contextkey'; From fb76941eb948d2dc678bc61dd9b92f24ede6a0a3 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 11 Dec 2023 10:22:32 +0100 Subject: [PATCH 26/80] Disabling auto-send on sparkle auto-run command (#199680) * wip * changing the arguments when opening inline chat * making the code more concise --- .../editor/contrib/codeAction/browser/lightBulbWidget.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index db41494f66a..3cfc0d39e24 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -93,8 +93,13 @@ export class LightBulbWidget extends Disposable implements IContentWidget { && this.state.actions.validActions.length === 1 ) { const action = this.state.actions.validActions[0].action; - if (action.command?.id) { - commandService.executeCommand(action.command.id, ...(action.command.arguments || [])); + const id = action.command?.id; + if (id) { + let args = action.command?.arguments; + if (id === 'inlineChat.start' && args && args.length === 1) { + args = [{ ...args[0], autoSend: false }]; + } + commandService.executeCommand(id, ...(args || [])); e.preventDefault(); return; } From 751baa0a26407b9bda344ee021b9693cb9508504 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Mon, 11 Dec 2023 11:06:42 +0100 Subject: [PATCH 27/80] :lipstick: --- src/vs/workbench/browser/labels.ts | 1 - src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 93309d1daf4..246bfb99d8c 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -580,7 +580,6 @@ class ResourceLabelWidget extends IconLabel { if (this.options && !this.options.hideIcon) { if (!this.computedIconClasses) { this.computedIconClasses = getIconClasses(this.modelService, this.languageService, resource, this.options.fileKind, this.options.icon); - } iconLabelOptions.extraClasses = this.computedIconClasses.slice(0); diff --git a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts index e0e5bbc9c7e..810dbc73083 100644 --- a/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts +++ b/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.ts @@ -324,6 +324,7 @@ export class SingleEditorTabsControl extends EditorTabsControl { badges: Boolean(options.decorations?.badges) }, icon: editor.getIcon(), + hideIcon: options.showIcons === false, } ); From 55d7566112ae7de85a6ff75d85374aad95d1cea9 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:09:12 +0100 Subject: [PATCH 28/80] SCM - fix scmProvider context keys (#200536) --- .../contrib/scm/browser/scmViewPane.ts | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index e13cf8e959a..35b650c0055 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -1416,13 +1416,9 @@ interface RepositoryVisibilityItem { class RepositoryVisibilityActionController { - private alwaysShowRepositories = false; private items = new Map(); private repositoryCountContextKey: IContextKey; private repositoryVisibilityCountContextKey: IContextKey; - private scmProviderContextKey: IContextKey; - private scmProviderRootUriContextKey: IContextKey; - private scmProviderHasRootUriContextKey: IContextKey; private readonly disposables = new DisposableStore(); constructor( @@ -1433,12 +1429,6 @@ class RepositoryVisibilityActionController { ) { this.repositoryCountContextKey = ContextKeys.RepositoryCount.bindTo(contextKeyService); this.repositoryVisibilityCountContextKey = ContextKeys.RepositoryVisibilityCount.bindTo(contextKeyService); - this.scmProviderContextKey = ContextKeys.SCMProvider.bindTo(contextKeyService); - this.scmProviderRootUriContextKey = ContextKeys.SCMProviderRootUri.bindTo(contextKeyService); - this.scmProviderHasRootUriContextKey = ContextKeys.SCMProviderHasRootUri.bindTo(contextKeyService); - - configurationService.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables); - this.onDidChangeConfiguration(); scmViewService.onDidChangeVisibleRepositories(this.onDidChangeVisibleRepositories, this, this.disposables); scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables); @@ -1492,27 +1482,9 @@ class RepositoryVisibilityActionController { this.repositoryVisibilityCountContextKey.set(count); } - private onDidChangeConfiguration(e?: IConfigurationChangeEvent): void { - if (!e || e.affectsConfiguration('scm.alwaysShowRepositories')) { - this.alwaysShowRepositories = this.contextKeyService.getContextKeyValue('scm.alwaysShowRepositories') === true; - this.updateRepositoryContextKeys(); - } - } - private updateRepositoryContextKeys(): void { this.repositoryCountContextKey.set(this.items.size); this.repositoryVisibilityCountContextKey.set(Iterable.reduce(this.items.keys(), (r, repository) => r + (this.scmViewService.isVisible(repository) ? 1 : 0), 0)); - - if (!this.alwaysShowRepositories && this.items.size === 1) { - const provider = Iterable.first(this.items.keys())!.provider; - this.scmProviderContextKey.set(provider.contextValue); - this.scmProviderRootUriContextKey.set(provider.rootUri?.toString()); - this.scmProviderHasRootUriContextKey.set(!!provider.rootUri); - } else { - this.scmProviderContextKey.set(undefined); - this.scmProviderRootUriContextKey.set(undefined); - this.scmProviderHasRootUriContextKey.set(false); - } } dispose(): void { @@ -2560,6 +2532,10 @@ export class SCMViewPane extends ViewPane { private areAllRepositoriesCollapsedContextKey: IContextKey; private isAnyRepositoryCollapsibleContextKey: IContextKey; + private scmProviderContextKey: IContextKey; + private scmProviderRootUriContextKey: IContextKey; + private scmProviderHasRootUriContextKey: IContextKey; + private readonly disposables = new DisposableStore(); constructor( @@ -2594,6 +2570,9 @@ export class SCMViewPane extends ViewPane { this.viewSortKeyContextKey.set(this.viewSortKey); this.areAllRepositoriesCollapsedContextKey = ContextKeys.SCMViewAreAllRepositoriesCollapsed.bindTo(contextKeyService); this.isAnyRepositoryCollapsibleContextKey = ContextKeys.SCMViewIsAnyRepositoryCollapsible.bindTo(contextKeyService); + this.scmProviderContextKey = ContextKeys.SCMProvider.bindTo(contextKeyService); + this.scmProviderRootUriContextKey = ContextKeys.SCMProviderRootUri.bindTo(contextKeyService); + this.scmProviderHasRootUriContextKey = ContextKeys.SCMProviderHasRootUri.bindTo(contextKeyService); this._onDidLayout = new Emitter(); this.layoutCache = { height: undefined, width: undefined, onDidChange: this._onDidLayout.event }; @@ -3090,6 +3069,7 @@ export class SCMViewPane extends ViewPane { this.inputRenderer.getRenderedInputWidget(focusedInput)?.forEach(widget => widget.focus()); } + this.updateScmProviderContextKeys(); this.updateRepositoryCollapseAllContextKeys(); })); } @@ -3101,6 +3081,19 @@ export class SCMViewPane extends ViewPane { this.treeContainer.classList.toggle('hide-arrows', this.viewMode === ViewMode.Tree && theme.hidesExplorerArrows === true); } + private updateScmProviderContextKeys(): void { + if (!this.alwaysShowRepositories && this.items.size === 1) { + const provider = Iterable.first(this.items.keys())!.provider; + this.scmProviderContextKey.set(provider.contextValue); + this.scmProviderRootUriContextKey.set(provider.rootUri?.toString()); + this.scmProviderHasRootUriContextKey.set(!!provider.rootUri); + } else { + this.scmProviderContextKey.set(undefined); + this.scmProviderRootUriContextKey.set(undefined); + this.scmProviderHasRootUriContextKey.set(false); + } + } + private updateRepositoryCollapseAllContextKeys(): void { if (!this.isBodyVisible() || this.items.size === 1) { this.isAnyRepositoryCollapsibleContextKey.set(false); From d68f53fdea72ed2fa6d04d9af3f835de554f42ea Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 11 Dec 2023 13:23:43 +0100 Subject: [PATCH 29/80] SCM - Input widget should use a context key service with an overlay (#200544) --- .../contrib/scm/browser/scmViewPane.ts | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 35b650c0055..7551a251013 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -1896,6 +1896,7 @@ class SCMInputWidget { }; private readonly defaultInputFontFamily = DEFAULT_FONT_FAMILY; + private readonly contextKeyService: IContextKeyService; private element: HTMLElement; private editorContainer: HTMLElement; @@ -2072,17 +2073,26 @@ class SCMInputWidget { } private createToolbar(input: ISCMInput): SCMInputWidgetToolbar { - const actionRunner = this.instantiationService.createInstance(SCMInputWidgetActionRunner, input); + const contextKeyService = this.contextKeyService.createOverlay([ + ['scmProvider', input.repository.provider.contextValue], + ['scmProviderRootUri', input.repository.provider.rootUri?.toString()], + ['scmProviderHasRootUri', !!input.repository.provider.rootUri] + ]); + + const serviceCollection = new ServiceCollection([IContextKeyService, contextKeyService]); + const instantiationService = this.instantiationService.createChild(serviceCollection); + + const actionRunner = instantiationService.createInstance(SCMInputWidgetActionRunner, input); this.repositoryDisposables.add(actionRunner); - const toolbar: SCMInputWidgetToolbar = this.instantiationService.createInstance(SCMInputWidgetToolbar, this.toolbarContainer, input, actionRunner, { + const toolbar: SCMInputWidgetToolbar = instantiationService.createInstance(SCMInputWidgetToolbar, this.toolbarContainer, input, actionRunner, { actionRunner, actionViewItemProvider: action => { if (action instanceof MenuItemAction && toolbar.dropdownActions.length > 1) { - return this.instantiationService.createInstance(DropdownWithPrimaryActionViewItem, action, toolbar.dropdownAction, toolbar.dropdownActions, '', this.contextMenuService, { actionRunner }); + return instantiationService.createInstance(DropdownWithPrimaryActionViewItem, action, toolbar.dropdownAction, toolbar.dropdownActions, '', this.contextMenuService, { actionRunner }); } - return createActionViewItem(this.instantiationService, action); + return createActionViewItem(instantiationService, action); }, menuOptions: { shouldForwardArgs: true @@ -2135,8 +2145,8 @@ class SCMInputWidget { this.setPlaceholderFontStyles(fontFamily, fontSize, lineHeight); - const contextKeyService2 = contextKeyService.createScoped(this.element); - this.repositoryIdContextKey = contextKeyService2.createKey('scmRepository', undefined); + this.contextKeyService = contextKeyService.createScoped(this.element); + this.repositoryIdContextKey = this.contextKeyService.createKey('scmRepository', undefined); const editorOptions: IEditorConstructionOptions = { ...getSimpleEditorOptions(configurationService), @@ -2180,7 +2190,7 @@ class SCMInputWidget { ]) }; - const services = new ServiceCollection([IContextKeyService, contextKeyService2]); + const services = new ServiceCollection([IContextKeyService, this.contextKeyService]); const instantiationService2 = instantiationService.createChild(services); this.inputEditor = instantiationService2.createInstance(CodeEditorWidget, this.editorContainer, editorOptions, codeEditorWidgetOptions); this.disposables.add(this.inputEditor); @@ -2203,8 +2213,8 @@ class SCMInputWidget { }, 0); })); - const firstLineKey = contextKeyService2.createKey('scmInputIsInFirstPosition', false); - const lastLineKey = contextKeyService2.createKey('scmInputIsInLastPosition', false); + const firstLineKey = this.contextKeyService.createKey('scmInputIsInFirstPosition', false); + const lastLineKey = this.contextKeyService.createKey('scmInputIsInLastPosition', false); this.disposables.add(this.inputEditor.onDidChangeCursorPosition(({ position }) => { const viewModel = this.inputEditor._getViewModel()!; From 13d454deca1309385a5bd14811c29a7117779a13 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Mon, 11 Dec 2023 13:58:26 +0100 Subject: [PATCH 30/80] fix terminal test? --- test/automation/src/terminal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/automation/src/terminal.ts b/test/automation/src/terminal.ts index b40606928f8..19a75ca948a 100644 --- a/test/automation/src/terminal.ts +++ b/test/automation/src/terminal.ts @@ -246,7 +246,7 @@ export class Terminal { await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!singleTab.className.includes(`terminal-icon-terminal_ansi${color}`)); } if (icon) { - selector = selector === Selector.EditorTab ? selector : `${selector} .codicon`; + [icon, selector] = selector === Selector.EditorTab ? [`.codicon-${icon}`, selector] : [icon, `${selector} .codicon`]; await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!singleTab.className.includes(icon)); } } From 528afd8e429e43818429ee1e5ed4ae98d2bbd20b Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Mon, 11 Dec 2023 14:41:37 +0100 Subject: [PATCH 31/80] fix typechecker error --- test/automation/src/terminal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/automation/src/terminal.ts b/test/automation/src/terminal.ts index 19a75ca948a..472cb442206 100644 --- a/test/automation/src/terminal.ts +++ b/test/automation/src/terminal.ts @@ -247,7 +247,7 @@ export class Terminal { } if (icon) { [icon, selector] = selector === Selector.EditorTab ? [`.codicon-${icon}`, selector] : [icon, `${selector} .codicon`]; - await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!singleTab.className.includes(icon)); + await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!icon && !!singleTab.className.includes(icon)); } } } From 8ff022bbe96a4682227d5584f6ee648b0bf03fed Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Mon, 11 Dec 2023 15:03:42 +0100 Subject: [PATCH 32/80] fix selector and icon name --- test/automation/src/terminal.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/automation/src/terminal.ts b/test/automation/src/terminal.ts index 472cb442206..27e2f4cbb54 100644 --- a/test/automation/src/terminal.ts +++ b/test/automation/src/terminal.ts @@ -20,7 +20,7 @@ export enum Selector { XtermFocused = '.terminal.xterm.focus', PlusButton = '.codicon-plus', EditorGroups = '.editor .split-view-view', - EditorTab = '.terminal-tab', + EditorTab = '.terminal-tab.product-icon', SingleTab = '.single-terminal-tab', Tabs = '.tabs-list .monaco-list-row', SplitButton = '.editor .codicon-split-horizontal', @@ -246,7 +246,7 @@ export class Terminal { await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!singleTab.className.includes(`terminal-icon-terminal_ansi${color}`)); } if (icon) { - [icon, selector] = selector === Selector.EditorTab ? [`.codicon-${icon}`, selector] : [icon, `${selector} .codicon`]; + [icon, selector] = selector === Selector.EditorTab ? [`codicon-${icon}`, selector] : [icon, `${selector} .codicon`]; await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!icon && !!singleTab.className.includes(icon)); } } From 5d6eac5b2d2b0e41d652ccf9de8d2ed5df63f86b Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:06:26 +0100 Subject: [PATCH 33/80] =?UTF-8?q?SCM=20-=20=F0=9F=92=84=20remove=20unused?= =?UTF-8?q?=20service=20(#200555)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/vs/workbench/contrib/scm/browser/scmViewPane.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 7551a251013..e998b2069e5 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -1424,7 +1424,6 @@ class RepositoryVisibilityActionController { constructor( @IContextKeyService private contextKeyService: IContextKeyService, @ISCMViewService private readonly scmViewService: ISCMViewService, - @IConfigurationService configurationService: IConfigurationService, @ISCMService scmService: ISCMService ) { this.repositoryCountContextKey = ContextKeys.RepositoryCount.bindTo(contextKeyService); From 692599b8335356110d33ae6b6708a0fa6259bd40 Mon Sep 17 00:00:00 2001 From: BeniBenj Date: Mon, 11 Dec 2023 16:04:41 +0100 Subject: [PATCH 34/80] support updating icon --- src/vs/workbench/browser/labels.ts | 7 ++++++- test/automation/src/terminal.ts | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 246bfb99d8c..74fc9277f80 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -468,6 +468,7 @@ class ResourceLabelWidget extends IconLabel { const hasResourceChanged = this.hasResourceChanged(label); const hasPathLabelChanged = hasResourceChanged || this.hasPathLabelChanged(label); const hasFileKindChanged = this.hasFileKindChanged(options); + const hasIconChanged = this.hasIconChanged(options); this.label = label; this.options = options; @@ -481,7 +482,7 @@ class ResourceLabelWidget extends IconLabel { } this.render({ - updateIcon: hasResourceChanged || hasFileKindChanged, + updateIcon: hasResourceChanged || hasFileKindChanged || hasIconChanged, updateDecoration: hasResourceChanged || hasFileKindChanged }); } @@ -514,6 +515,10 @@ class ResourceLabelWidget extends IconLabel { return !!newResource && this.computedPathLabel !== this.labelService.getUriLabel(newResource); } + private hasIconChanged(newOptions?: IResourceLabelOptions): boolean { + return this.options?.icon !== newOptions?.icon; + } + clear(): void { this.label = undefined; this.options = undefined; diff --git a/test/automation/src/terminal.ts b/test/automation/src/terminal.ts index 27e2f4cbb54..b40606928f8 100644 --- a/test/automation/src/terminal.ts +++ b/test/automation/src/terminal.ts @@ -20,7 +20,7 @@ export enum Selector { XtermFocused = '.terminal.xterm.focus', PlusButton = '.codicon-plus', EditorGroups = '.editor .split-view-view', - EditorTab = '.terminal-tab.product-icon', + EditorTab = '.terminal-tab', SingleTab = '.single-terminal-tab', Tabs = '.tabs-list .monaco-list-row', SplitButton = '.editor .codicon-split-horizontal', @@ -246,8 +246,8 @@ export class Terminal { await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!singleTab.className.includes(`terminal-icon-terminal_ansi${color}`)); } if (icon) { - [icon, selector] = selector === Selector.EditorTab ? [`codicon-${icon}`, selector] : [icon, `${selector} .codicon`]; - await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!icon && !!singleTab.className.includes(icon)); + selector = selector === Selector.EditorTab ? selector : `${selector} .codicon`; + await this.code.waitForElement(`${selector}`, singleTab => !!singleTab && !!singleTab.className.includes(icon)); } } } From 3fca41e19bdfda4cc8fa00ae6f3ba816924c4ca5 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 11 Dec 2023 16:34:20 +0100 Subject: [PATCH 35/80] Making the settings readonly (#200221) making the settings readonly --- src/vs/editor/contrib/hover/browser/hover.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index e8490c030b1..b23b8cd8594 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -39,9 +39,9 @@ const _sticky = false ; interface IHoverSettings { - enabled: boolean; - sticky: boolean; - hidingDelay: number; + readonly enabled: boolean; + readonly sticky: boolean; + readonly hidingDelay: number; } interface IHoverState { @@ -279,9 +279,7 @@ export class HoverController extends Disposable implements IEditorContribution { (decoratorActivatedOn === 'click' && !activatedByDecoratorClick) || (decoratorActivatedOn === 'hover' && !enabled && !_sticky) || (decoratorActivatedOn === 'clickAndHover' && !enabled && !activatedByDecoratorClick)) - ) - || - ( + ) || ( !mouseOnDecorator && !enabled && !activatedByDecoratorClick ) ) { From 83180a3d094d988162620cdee1ce32c997b90bc8 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 11 Dec 2023 16:36:57 +0100 Subject: [PATCH 36/80] Using the action title in the hover message when auto-running on clicking of sparkle (#199521) * using the action title prepended with Run keyword * setting the title in one function which is outside of _updateLightBulbTitleAndIcon --- .../codeAction/browser/lightBulbWidget.ts | 43 ++++++++----------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts index 3cfc0d39e24..fcbb3c3f32b 100644 --- a/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts +++ b/src/vs/editor/contrib/codeAction/browser/lightBulbWidget.ts @@ -244,32 +244,14 @@ export class LightBulbWidget extends Disposable implements IContentWidget { if (this.state.type !== LightBulbState.Type.Showing) { return; } - const updateAutoFixLightbulbTitle = () => { - if (this._preferredKbLabel) { - this.title = nls.localize('preferredcodeActionWithKb', "Show Code Actions. Preferred Quick Fix Available ({0})", this._preferredKbLabel); - } - }; - const updateLightbulbTitle = () => { - if (this._quickFixKbLabel) { - this.title = nls.localize('codeActionWithKb', "Show Code Actions ({0})", this._quickFixKbLabel); - } else { - this.title = nls.localize('codeAction', "Show Code Actions"); - } - }; let icon: ThemeIcon; + let autoRun = false; const option = this._editor.getOption(EditorOption.lightbulb).experimental.showAiIcon; if (option === ShowAiIconMode.On || option === ShowAiIconMode.OnCode) { if (option === ShowAiIconMode.On && this.state.actions.allAIFixes) { icon = Codicon.sparkleFilled; if (this.state.actions.validActions.length === 1) { - if (this.state.actions.validActions[0].action.command?.id === `inlineChat.start`) { - const keybinding = this._keybindingService.lookupKeybinding('inlineChat.start')?.getLabel() ?? undefined; - this.title = keybinding ? nls.localize('codeActionStartInlineChatWithKb', 'Start Inline Chat ({0})', keybinding) : nls.localize('codeActionStartInlineChat', 'Start Inline Chat',); - } else { - this.title = nls.localize('codeActionTriggerAiAction', "Trigger AI Action"); - } - } else { - updateLightbulbTitle(); + autoRun = true; } } else if (this.state.actions.hasAutoFix) { if (this.state.actions.hasAIFix) { @@ -277,27 +259,38 @@ export class LightBulbWidget extends Disposable implements IContentWidget { } else { icon = Codicon.lightbulbAutofix; } - updateAutoFixLightbulbTitle(); } else if (this.state.actions.hasAIFix) { icon = Codicon.lightbulbSparkle; - updateLightbulbTitle(); } else { icon = Codicon.lightBulb; - updateLightbulbTitle(); } } else { if (this.state.actions.hasAutoFix) { icon = Codicon.lightbulbAutofix; - updateAutoFixLightbulbTitle(); } else { icon = Codicon.lightBulb; - updateLightbulbTitle(); } } + this._updateLightbulbTitle(this.state.actions.hasAutoFix, autoRun); this._iconClasses = ThemeIcon.asClassNameArray(icon); this._domNode.classList.add(...this._iconClasses); } + private _updateLightbulbTitle(autoFix: boolean, autoRun: boolean): void { + if (this.state.type !== LightBulbState.Type.Showing) { + return; + } + if (autoRun) { + this.title = nls.localize('codeActionAutoRun', "Run: {0}", this.state.actions.validActions[0].action.title); + } else if (autoFix && this._preferredKbLabel) { + this.title = nls.localize('preferredcodeActionWithKb', "Show Code Actions. Preferred Quick Fix Available ({0})", this._preferredKbLabel); + } else if (!autoFix && this._quickFixKbLabel) { + this.title = nls.localize('codeActionWithKb', "Show Code Actions ({0})", this._quickFixKbLabel); + } else if (!autoFix) { + this.title = nls.localize('codeAction', "Show Code Actions"); + } + } + private set title(value: string) { this._domNode.title = value; } From aa79d7e5798eb54591587593ea21e390d56533ed Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:41:25 +0100 Subject: [PATCH 37/80] fix terminal editor icon color (#200573) --- src/vs/workbench/contrib/terminal/browser/terminalIcon.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts b/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts index 1ea310c533f..22015db095a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalIcon.ts @@ -77,6 +77,7 @@ export function getColorStyleContent(colorTheme: IColorTheme, editor?: boolean): if (color) { if (editor) { css += ( + `.monaco-workbench .show-file-icons .product-icon.terminal-tab.${colorClass}::before,` + `.monaco-workbench .show-file-icons .file-icon.terminal-tab.${colorClass}::before` + `{ color: ${color} !important; }` ); From 2120c548c33ea0f2d9a65a2c0ac5ae66cad4fa4c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 11 Dec 2023 20:11:57 +0100 Subject: [PATCH 38/80] editors - let simple browser auto lock groups (#200578) --- .../browser/parts/editor/editorConfiguration.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorConfiguration.ts b/src/vs/workbench/browser/parts/editor/editorConfiguration.ts index bd44c514cd6..c38c6b256ce 100644 --- a/src/vs/workbench/browser/parts/editor/editorConfiguration.ts +++ b/src/vs/workbench/browser/parts/editor/editorConfiguration.ts @@ -19,7 +19,10 @@ import { ByteSize, getLargeFileConfirmationLimit } from 'vs/platform/files/commo export class DynamicEditorConfigurations extends Disposable implements IWorkbenchContribution { - private static readonly AUTO_LOCK_DEFAULT_ENABLED = new Set(['terminalEditor']); + private static readonly AUTO_LOCK_DEFAULT_ENABLED = new Set([ + 'terminalEditor', + 'mainThreadWebview-simpleBrowser.view' + ]); private static readonly AUTO_LOCK_EXTRA_EDITORS: RegisteredEditorInfo[] = [ @@ -35,6 +38,11 @@ export class DynamicEditorConfigurations extends Disposable implements IWorkbenc id: 'mainThreadWebview-markdown.preview', label: localize('markdownPreview', "Markdown Preview"), priority: RegisteredEditorPriority.builtin + }, + { + id: 'mainThreadWebview-simpleBrowser.view', + label: localize('simpleBrowser', "Simple Browser"), + priority: RegisteredEditorPriority.builtin } ]; From c2ed45b371d4c0d9363b6c5f4b75ccd3cb3c6e8b Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 11 Dec 2023 21:15:55 +0100 Subject: [PATCH 39/80] editors - let live preview auto lock groups (#200584) --- .../workbench/browser/parts/editor/editorConfiguration.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorConfiguration.ts b/src/vs/workbench/browser/parts/editor/editorConfiguration.ts index c38c6b256ce..0374332a083 100644 --- a/src/vs/workbench/browser/parts/editor/editorConfiguration.ts +++ b/src/vs/workbench/browser/parts/editor/editorConfiguration.ts @@ -21,7 +21,8 @@ export class DynamicEditorConfigurations extends Disposable implements IWorkbenc private static readonly AUTO_LOCK_DEFAULT_ENABLED = new Set([ 'terminalEditor', - 'mainThreadWebview-simpleBrowser.view' + 'mainThreadWebview-simpleBrowser.view', + 'mainThreadWebview-browserPreview' ]); private static readonly AUTO_LOCK_EXTRA_EDITORS: RegisteredEditorInfo[] = [ @@ -43,6 +44,11 @@ export class DynamicEditorConfigurations extends Disposable implements IWorkbenc id: 'mainThreadWebview-simpleBrowser.view', label: localize('simpleBrowser', "Simple Browser"), priority: RegisteredEditorPriority.builtin + }, + { + id: 'mainThreadWebview-browserPreview', + label: localize('livePreview', "Live Preview"), + priority: RegisteredEditorPriority.builtin } ]; From 4c5336dae107b1908362c6d5e6b3b347e30f39b3 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Mon, 11 Dec 2023 13:52:25 -0800 Subject: [PATCH 40/80] Skip encoding of markdown links (#200588) Fixes #200213 This encoding should no longer be needed now that we can smartly insert angle bracket links --- .../src/languageFeatures/copyFiles/shared.ts | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts index 5c591457c41..e269ff45c9d 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts @@ -189,11 +189,11 @@ export function appendToLinkSnippet( title: string, link: string, placeholderValue: number, - isExternalLink: boolean, + _isExternalLink: boolean, ): void { snippet.appendText('['); snippet.appendPlaceholder(escapeBrackets(title) || 'Title', placeholderValue); - snippet.appendText(`](${escapeMarkdownLinkPath(link, isExternalLink)})`); + snippet.appendText(`](${escapeMarkdownLinkPath(link)})`); } export function createUriListSnippet( @@ -238,17 +238,15 @@ export function createUriListSnippet( snippet.appendPlaceholder(escapeBrackets(title) || 'Title', placeholderValue); snippet.appendText('">'); } else if (insertAsMedia) { - if (insertAsMedia) { - insertedImageCount++; - if (pasteAsMarkdownLink) { - snippet.appendText('!['); - const placeholderText = escapeBrackets(title) || options?.placeholderText || 'Alt text'; - const placeholderIndex = typeof options?.placeholderStartIndex !== 'undefined' ? options?.placeholderStartIndex + i : (placeholderValue === 0 ? undefined : placeholderValue); - snippet.appendPlaceholder(placeholderText, placeholderIndex); - snippet.appendText(`](${escapeMarkdownLinkPath(mdPath, isExternalLink)})`); - } else { - snippet.appendText(escapeMarkdownLinkPath(mdPath, isExternalLink)); - } + insertedImageCount++; + if (pasteAsMarkdownLink) { + snippet.appendText('!['); + const placeholderText = escapeBrackets(title) || options?.placeholderText || 'Alt text'; + const placeholderIndex = typeof options?.placeholderStartIndex !== 'undefined' ? options?.placeholderStartIndex + i : (placeholderValue === 0 ? undefined : placeholderValue); + snippet.appendPlaceholder(placeholderText, placeholderIndex); + snippet.appendText(`](${escapeMarkdownLinkPath(mdPath)})`); + } else { + snippet.appendText(escapeMarkdownLinkPath(mdPath)); } } else { insertedLinkCount++; @@ -371,12 +369,12 @@ function escapeHtmlAttribute(attr: string): string { return encodeURI(attr).replaceAll('"', '"'); } -function escapeMarkdownLinkPath(mdPath: string, isExternalLink: boolean): string { +function escapeMarkdownLinkPath(mdPath: string): string { if (needsBracketLink(mdPath)) { return '<' + mdPath.replaceAll('<', '\\<').replaceAll('>', '\\>') + '>'; } - return isExternalLink ? mdPath : encodeURI(mdPath); + return mdPath; } function escapeBrackets(value: string): string { @@ -384,7 +382,7 @@ function escapeBrackets(value: string): string { return value; } -function needsBracketLink(mdPath: string) { +function needsBracketLink(mdPath: string): boolean { // Links with whitespace or control characters must be enclosed in brackets if (mdPath.startsWith('<') || /\s|[\u007F\u0000-\u001f]/.test(mdPath)) { return true; From d5d14242969257ffff1815ef3bec45d1f2eb0e81 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Mon, 11 Dec 2023 15:47:06 -0800 Subject: [PATCH 41/80] Allow disabling filepath links (#200577) * add setting to enable/disable linkifying filepaths * implement linkify setting * update setting without reload * switch casing style --- extensions/notebook-renderers/src/ansi.ts | 14 +++--- extensions/notebook-renderers/src/index.ts | 9 ++-- extensions/notebook-renderers/src/linkify.ts | 45 ++++++++++++------- .../notebook-renderers/src/rendererTypes.ts | 2 + .../src/test/linkify.test.ts | 15 ++++--- .../src/test/notebookRenderer.test.ts | 31 ++++++++++++- .../notebook-renderers/src/textHelper.ts | 27 ++++++----- .../notebook/browser/notebook.contribution.ts | 6 +++ .../notebook/browser/notebookEditorWidget.ts | 1 + .../notebook/browser/notebookOptions.ts | 19 ++++++-- .../view/renderers/backLayerWebView.ts | 7 ++- .../browser/view/renderers/webviewPreloads.ts | 2 + .../contrib/notebook/common/notebookCommon.ts | 1 + 13 files changed, 130 insertions(+), 49 deletions(-) diff --git a/extensions/notebook-renderers/src/ansi.ts b/extensions/notebook-renderers/src/ansi.ts index d09e7b73edb..48d280b18b4 100644 --- a/extensions/notebook-renderers/src/ansi.ts +++ b/extensions/notebook-renderers/src/ansi.ts @@ -5,11 +5,10 @@ import { RGBA, Color } from './color'; import { ansiColorIdentifiers } from './colorMap'; -import { linkify } from './linkify'; +import { LinkOptions, linkify } from './linkify'; -export function handleANSIOutput(text: string, trustHtml: boolean): HTMLSpanElement { - const workspaceFolder = undefined; +export function handleANSIOutput(text: string, linkOptions: LinkOptions): HTMLSpanElement { const root: HTMLSpanElement = document.createElement('span'); const textLength: number = text.length; @@ -52,7 +51,7 @@ export function handleANSIOutput(text: string, trustHtml: boolean): HTMLSpanElem if (sequenceFound) { // Flush buffer with previous styles. - appendStylizedStringToContainer(root, buffer, trustHtml, styleNames, workspaceFolder, customFgColor, customBgColor, customUnderlineColor); + appendStylizedStringToContainer(root, buffer, linkOptions, styleNames, customFgColor, customBgColor, customUnderlineColor); buffer = ''; @@ -98,7 +97,7 @@ export function handleANSIOutput(text: string, trustHtml: boolean): HTMLSpanElem // Flush remaining text buffer if not empty. if (buffer) { - appendStylizedStringToContainer(root, buffer, trustHtml, styleNames, workspaceFolder, customFgColor, customBgColor, customUnderlineColor); + appendStylizedStringToContainer(root, buffer, linkOptions, styleNames, customFgColor, customBgColor, customUnderlineColor); } return root; @@ -382,9 +381,8 @@ export function handleANSIOutput(text: string, trustHtml: boolean): HTMLSpanElem function appendStylizedStringToContainer( root: HTMLElement, stringContent: string, - trustHtml: boolean, + linkOptions: LinkOptions, cssClasses: string[], - workspaceFolder: string | undefined, customTextColor?: RGBA | string, customBackgroundColor?: RGBA | string, customUnderlineColor?: RGBA | string @@ -397,7 +395,7 @@ function appendStylizedStringToContainer( if (container.childElementCount === 0) { // plain text - container = linkify(stringContent, true, workspaceFolder, trustHtml); + container = linkify(stringContent, linkOptions, true); } container.className = cssClasses.join(' '); diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index ba57767b7fc..ff79bd0e22e 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -176,7 +176,9 @@ function renderError( const stackTrace = formatStackTrace(err.stack); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); - const content = createOutputContent(outputInfo.id, stackTrace ?? '', { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml }); + const outputOptions = { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml, linkifyFilePaths: ctx.settings.linkifyFilePaths }; + + const content = createOutputContent(outputInfo.id, stackTrace ?? '', outputOptions); const contentParent = document.createElement('div'); contentParent.classList.toggle('word-wrap', ctx.settings.outputWordWrap); disposableStore.push(ctx.onDidChangeSettings(e => { @@ -279,7 +281,7 @@ function scrollingEnabled(output: OutputItem, options: RenderOptions) { function renderStream(outputInfo: OutputWithAppend, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable { const disposableStore = createDisposableStore(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); - const outputOptions = { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml: false, error }; + const outputOptions = { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml: false, error, linkifyFilePaths: ctx.settings.linkifyFilePaths }; outputElement.classList.add('output-stream'); @@ -330,7 +332,8 @@ function renderText(outputInfo: OutputItem, outputElement: HTMLElement, ctx: IRi const text = outputInfo.text(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings); - const content = createOutputContent(outputInfo.id, text, { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml: false }); + const outputOptions = { linesLimit: ctx.settings.lineLimit, scrollable: outputScrolling, trustHtml: false, linkifyFilePaths: ctx.settings.linkifyFilePaths }; + const content = createOutputContent(outputInfo.id, text, outputOptions); content.classList.add('output-plaintext'); if (ctx.settings.outputWordWrap) { content.classList.add('word-wrap'); diff --git a/extensions/notebook-renderers/src/linkify.ts b/extensions/notebook-renderers/src/linkify.ts index 49fdc4edf8c..c625c5fdba5 100644 --- a/extensions/notebook-renderers/src/linkify.ts +++ b/extensions/notebook-renderers/src/linkify.ts @@ -26,6 +26,11 @@ type LinkPart = { captures: string[]; }; +export type LinkOptions = { + trustHtml?: boolean; + linkifyFilePaths: boolean; +}; + export class LinkDetector { // used by unit tests @@ -51,7 +56,8 @@ export class LinkDetector { * When splitLines is true, each line of the text, even if it contains no links, is wrapped in a * and added as a child of the returned . */ - linkify(text: string, splitLines?: boolean, workspaceFolder?: string, trustHtml?: boolean): HTMLElement { + linkify(text: string, options: LinkOptions, splitLines?: boolean): HTMLElement { + console.log('linkifyiiiiiing', JSON.stringify(options)); if (splitLines) { const lines = text.split('\n'); for (let i = 0; i < lines.length - 1; i++) { @@ -61,7 +67,7 @@ export class LinkDetector { // Remove the last element ('') that split added. lines.pop(); } - const elements = lines.map(line => this.linkify(line, false, workspaceFolder, trustHtml)); + const elements = lines.map(line => this.linkify(line, options, false)); if (elements.length === 1) { // Do not wrap single line with extra span. return elements[0]; @@ -72,8 +78,9 @@ export class LinkDetector { } const container = document.createElement('span'); - for (const part of this.detectLinks(text)) { + for (const part of this.detectLinks(text, !!options.trustHtml, options.linkifyFilePaths)) { try { + let span: HTMLSpanElement | null = null; switch (part.kind) { case 'text': container.appendChild(document.createTextNode(part.value)); @@ -83,13 +90,9 @@ export class LinkDetector { container.appendChild(this.createWebLink(part.value)); break; case 'html': - if (this.shouldGenerateHtml(!!trustHtml)) { - const span = document.createElement('span'); - span.innerHTML = this.createHtml(part.value)!; - container.appendChild(span); - } else { - container.appendChild(document.createTextNode(part.value)); - } + span = document.createElement('span'); + span.innerHTML = this.createHtml(part.value)!; + container.appendChild(span); break; } } catch (e) { @@ -149,15 +152,27 @@ export class LinkDetector { return link; } - private detectLinks(text: string): LinkPart[] { + private detectLinks(text: string, trustHtml: boolean, detectFilepaths: boolean): LinkPart[] { if (text.length > MAX_LENGTH) { return [{ kind: 'text', value: text, captures: [] }]; } - const regexes: RegExp[] = [HTML_LINK_REGEX, WEB_LINK_REGEX, PATH_LINK_REGEX]; - const kinds: LinkKind[] = ['html', 'web', 'path']; + const regexes: RegExp[] = []; + const kinds: LinkKind[] = []; const result: LinkPart[] = []; + if (this.shouldGenerateHtml(trustHtml)) { + regexes.push(HTML_LINK_REGEX); + kinds.push('html'); + } + regexes.push(WEB_LINK_REGEX); + kinds.push('web'); + if (detectFilepaths) { + regexes.push(PATH_LINK_REGEX); + kinds.push('path'); + } + + const splitOne = (text: string, regexIndex: number) => { if (regexIndex >= regexes.length) { result.push({ value: text, kind: 'text', captures: [] }); @@ -192,6 +207,6 @@ export class LinkDetector { } const linkDetector = new LinkDetector(); -export function linkify(text: string, splitLines?: boolean, workspaceFolder?: string, trustHtml = false) { - return linkDetector.linkify(text, splitLines, workspaceFolder, trustHtml); +export function linkify(text: string, linkOptions: LinkOptions, splitLines?: boolean) { + return linkDetector.linkify(text, linkOptions, splitLines); } diff --git a/extensions/notebook-renderers/src/rendererTypes.ts b/extensions/notebook-renderers/src/rendererTypes.ts index ded12bdcacc..e1fc869a301 100644 --- a/extensions/notebook-renderers/src/rendererTypes.ts +++ b/extensions/notebook-renderers/src/rendererTypes.ts @@ -32,6 +32,7 @@ export interface RenderOptions { readonly lineLimit: number; readonly outputScrolling: boolean; readonly outputWordWrap: boolean; + readonly linkifyFilePaths: boolean; } export type IRichRenderContext = RendererContext & { readonly settings: RenderOptions; readonly onDidChangeSettings: Event }; @@ -41,6 +42,7 @@ export type OutputElementOptions = { scrollable?: boolean; error?: boolean; trustHtml?: boolean; + linkifyFilePaths: boolean; }; export interface OutputWithAppend extends OutputItem { diff --git a/extensions/notebook-renderers/src/test/linkify.test.ts b/extensions/notebook-renderers/src/test/linkify.test.ts index 7ee5487a84b..cae8f569423 100644 --- a/extensions/notebook-renderers/src/test/linkify.test.ts +++ b/extensions/notebook-renderers/src/test/linkify.test.ts @@ -15,27 +15,32 @@ suite('Notebook builtin output link detection', () => { LinkDetector.injectedHtmlCreator = (value: string) => value; test('no links', () => { - const htmlWithLinks = linkify('hello', true, undefined, true); + const htmlWithLinks = linkify('hello', { linkifyFilePaths: true, trustHtml: true }, true); assert.equal(htmlWithLinks.innerHTML, 'hello'); }); test('web link detection', () => { - const htmlWithLinks = linkify('something www.example.com something', true, undefined, true); + const htmlWithLinks = linkify('something www.example.com something', { linkifyFilePaths: true, trustHtml: true }, true); + const htmlWithLinks2 = linkify('something www.example.com something', { linkifyFilePaths: false, trustHtml: false }, true); assert.equal(htmlWithLinks.innerHTML, 'something www.example.com something'); assert.equal(htmlWithLinks.textContent, 'something www.example.com something'); + assert.equal(htmlWithLinks2.innerHTML, 'something www.example.com something'); + assert.equal(htmlWithLinks2.textContent, 'something www.example.com something'); }); test('html link detection', () => { - const htmlWithLinks = linkify('something link something', true, undefined, true); + const htmlWithLinks = linkify('something link something', { linkifyFilePaths: true, trustHtml: true }, true); + const htmlWithLinks2 = linkify('something link something', { linkifyFilePaths: false, trustHtml: true }, true); assert.equal(htmlWithLinks.innerHTML, 'something link something'); assert.equal(htmlWithLinks.textContent, 'something link something'); + assert.equal(htmlWithLinks2.innerHTML, 'something link something'); + assert.equal(htmlWithLinks2.textContent, 'something link something'); }); test('html link without trust', () => { - const trustHtml = false; - const htmlWithLinks = linkify('something link something', true, undefined, trustHtml); + const htmlWithLinks = linkify('something link something', { linkifyFilePaths: true, trustHtml: false }, true); assert.equal(htmlWithLinks.innerHTML, 'something <a href="file.py">link</a> something'); assert.equal(htmlWithLinks.textContent, 'something link something'); diff --git a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts index 8e33720d337..07ec9cdf9ea 100644 --- a/extensions/notebook-renderers/src/test/notebookRenderer.test.ts +++ b/extensions/notebook-renderers/src/test/notebookRenderer.test.ts @@ -273,6 +273,36 @@ suite('Notebook builtin output renderer', () => { assert.ok(inserted.innerHTML.indexOf('shouldBeTruncated') === -1, `Beginning content should be truncated`); }); + test(`Render filepath links in text output when enabled`, async () => { + LinkDetector.injectedHtmlCreator = (value: string) => value; + const context = createContext({ outputWordWrap: true, outputScrolling: true, linkifyFilePaths: true }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem('./dir/file.txt', stdoutMimeType); + await renderer!.renderOutputItem(outputItem, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); + assert.ok(outputElement.innerHTML.indexOf('') !== -1, `inner HTML:\n ${outputElement.innerHTML}`); + }); + + test(`No filepath links in text output when disabled`, async () => { + LinkDetector.injectedHtmlCreator = (value: string) => value; + const context = createContext({ outputWordWrap: true, outputScrolling: true, linkifyFilePaths: false }); + const renderer = await activate(context); + assert.ok(renderer, 'Renderer not created'); + + const outputElement = new OutputHtml().getFirstOuputElement(); + const outputItem = createOutputItem('./dir/file.txt', stdoutMimeType); + await renderer!.renderOutputItem(outputItem, outputElement); + + const inserted = outputElement.firstChild as HTMLElement; + assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); + assert.ok(outputElement.innerHTML.indexOf('') === -1, `inner HTML:\n ${outputElement.innerHTML}`); + }); + test(`Render with wordwrap and scrolling for error output`, async () => { LinkDetector.injectedHtmlCreator = (value: string) => value; const context = createContext({ outputWordWrap: true, outputScrolling: true }); @@ -474,7 +504,6 @@ suite('Notebook builtin output renderer', () => { const inserted = outputElement.firstChild as HTMLElement; assert.ok(inserted, `nothing appended to output element: ${outputElement.innerHTML}`); - //assert.ok(false, `TextContent:\n ${outputElement.textContent}`); assert.ok(outputElement.innerHTML.indexOf('class="code-background-colored"') === -1, `inner HTML:\n ${outputElement.innerHTML}`); }); diff --git a/extensions/notebook-renderers/src/textHelper.ts b/extensions/notebook-renderers/src/textHelper.ts index 5cf0e24eb96..b49dbb6ad8d 100644 --- a/extensions/notebook-renderers/src/textHelper.ts +++ b/extensions/notebook-renderers/src/textHelper.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { handleANSIOutput } from './ansi'; +import { LinkOptions } from './linkify'; import { OutputElementOptions, OutputWithAppend } from './rendererTypes'; export const scrollableClass = 'scrollable'; @@ -68,44 +69,44 @@ function generateNestedViewAllElement(outputId: string) { return container; } -function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number, trustHtml: boolean) { +function truncatedArrayOfString(id: string, buffer: string[], linesLimit: number, linkOptions: LinkOptions) { const container = document.createElement('div'); const lineCount = buffer.length; if (lineCount <= linesLimit) { - const spanElement = handleANSIOutput(buffer.join('\n'), trustHtml); + const spanElement = handleANSIOutput(buffer.join('\n'), linkOptions); container.appendChild(spanElement); return container; } - container.appendChild(handleANSIOutput(buffer.slice(0, linesLimit - 5).join('\n'), trustHtml)); + container.appendChild(handleANSIOutput(buffer.slice(0, linesLimit - 5).join('\n'), linkOptions)); // truncated piece const elipses = document.createElement('div'); elipses.innerText = '...'; container.appendChild(elipses); - container.appendChild(handleANSIOutput(buffer.slice(lineCount - 5).join('\n'), trustHtml)); + container.appendChild(handleANSIOutput(buffer.slice(lineCount - 5).join('\n'), linkOptions)); container.appendChild(generateViewMoreElement(id)); return container; } -function scrollableArrayOfString(id: string, buffer: string[], trustHtml: boolean) { +function scrollableArrayOfString(id: string, buffer: string[], linkOptions: LinkOptions) { const element = document.createElement('div'); if (buffer.length > softScrollableLineLimit) { element.appendChild(generateNestedViewAllElement(id)); } - element.appendChild(handleANSIOutput(buffer.slice(-1 * softScrollableLineLimit).join('\n'), trustHtml)); + element.appendChild(handleANSIOutput(buffer.slice(-1 * softScrollableLineLimit).join('\n'), linkOptions)); return element; } const outputLengths: Record = {}; -function appendScrollableOutput(element: HTMLElement, id: string, appended: string, trustHtml: boolean) { +function appendScrollableOutput(element: HTMLElement, id: string, appended: string, linkOptions: LinkOptions) { if (!outputLengths[id]) { outputLengths[id] = 0; } @@ -117,22 +118,23 @@ function appendScrollableOutput(element: HTMLElement, id: string, appended: stri return false; } else { - element.appendChild(handleANSIOutput(buffer.join('\n'), trustHtml)); + element.appendChild(handleANSIOutput(buffer.join('\n'), linkOptions)); outputLengths[id] = appendedLength; } return true; } export function createOutputContent(id: string, outputText: string, options: OutputElementOptions): HTMLElement { - const { linesLimit, error, scrollable, trustHtml } = options; + const { linesLimit, error, scrollable, trustHtml, linkifyFilePaths } = options; + const linkOptions: LinkOptions = { linkifyFilePaths, trustHtml }; const buffer = outputText.split(/\r\n|\r|\n/g); outputLengths[id] = outputLengths[id] = Math.min(buffer.length, softScrollableLineLimit); let outputElement: HTMLElement; if (scrollable) { - outputElement = scrollableArrayOfString(id, buffer, !!trustHtml); + outputElement = scrollableArrayOfString(id, buffer, linkOptions); } else { - outputElement = truncatedArrayOfString(id, buffer, linesLimit, !!trustHtml); + outputElement = truncatedArrayOfString(id, buffer, linesLimit, linkOptions); } outputElement.setAttribute('output-item-id', id); @@ -145,9 +147,10 @@ export function createOutputContent(id: string, outputText: string, options: Out export function appendOutput(outputInfo: OutputWithAppend, existingContent: HTMLElement, options: OutputElementOptions) { const appendedText = outputInfo.appendedText?.(); + const linkOptions = { linkifyFilePaths: options.linkifyFilePaths, trustHtml: options.trustHtml }; // appending output only supported for scrollable ouputs currently if (appendedText && options.scrollable) { - if (appendScrollableOutput(existingContent, outputInfo.id, appendedText, false)) { + if (appendScrollableOutput(existingContent, outputInfo.id, appendedText, linkOptions)) { return; } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index 943d28abb05..b0c8c072e62 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -922,6 +922,12 @@ configurationRegistry.registerConfiguration({ tags: ['notebookLayout', 'notebookOutputLayout'], minimum: 1, }, + [NotebookSetting.LinkifyOutputFilePaths]: { + description: nls.localize('notebook.disableOutputFilePathLinks', "Control whether to disable filepath links in the output of notebook cells."), + type: 'boolean', + default: true, + tags: ['notebookOutputLayout'] + }, [NotebookSetting.markupFontSize]: { markdownDescription: nls.localize('notebook.markup.fontSize', "Controls the font size in pixels of rendered markup in notebooks. When set to {0}, 120% of {1} is used.", '`0`', '`#editor.fontSize#`'), type: 'number', diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index 745adff1205..424862aeca3 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -372,6 +372,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD || e.outputFontFamily || e.outputWordWrap || e.outputScrolling + || e.outputLinkifyFilePaths ) { this._styleElement?.remove(); this._createLayoutStyles(); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts b/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts index c8bbccd4702..9e4c743e3ef 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookOptions.ts @@ -50,6 +50,7 @@ export interface NotebookDisplayOptions { outputScrolling: boolean; outputWordWrap: boolean; outputLineLimit: number; + outputLinkifyFilePaths: boolean; fontSize: number; outputFontSize: number; outputFontFamily: string; @@ -106,6 +107,7 @@ export interface NotebookOptionsChangeEvent { readonly outputLineHeight?: boolean; readonly outputWordWrap?: boolean; readonly outputScrolling?: boolean; + readonly outputLinkifyFilePaths?: boolean; } const defaultConfigConstants = Object.freeze({ @@ -199,6 +201,7 @@ export class NotebookOptions extends Disposable { const outputLineHeight = this._computeOutputLineHeight(outputLineHeightSettingValue, outputFontSize); const outputWordWrap = this.configurationService.getValue(NotebookSetting.outputWordWrap); const outputLineLimit = this.configurationService.getValue(NotebookSetting.textOutputLineLimit) ?? 30; + const linkifyFilePaths = this.configurationService.getValue(NotebookSetting.LinkifyOutputFilePaths) ?? true; this._layoutConfiguration = { ...(compactView ? compactConfigConstants : defaultConfigConstants), @@ -239,7 +242,8 @@ export class NotebookOptions extends Disposable { markdownFoldHintHeight: 22, outputScrolling: outputScrolling, outputWordWrap: outputWordWrap, - outputLineLimit: outputLineLimit + outputLineLimit: outputLineLimit, + outputLinkifyFilePaths: linkifyFilePaths }; this._register(this.configurationService.onDidChangeConfiguration(e => { @@ -355,6 +359,7 @@ export class NotebookOptions extends Disposable { const outputLineHeight = e.affectsConfiguration(NotebookSetting.outputLineHeight); const outputScrolling = e.affectsConfiguration(NotebookSetting.outputScrolling); const outputWordWrap = e.affectsConfiguration(NotebookSetting.outputWordWrap); + const outputLinkifyFilePaths = e.affectsConfiguration(NotebookSetting.LinkifyOutputFilePaths); if ( !cellStatusBarVisibility @@ -379,7 +384,8 @@ export class NotebookOptions extends Disposable { && !interactiveWindowCollapseCodeCells && !outputLineHeight && !outputScrolling - && !outputWordWrap) { + && !outputWordWrap + && !outputLinkifyFilePaths) { return; } @@ -478,6 +484,10 @@ export class NotebookOptions extends Disposable { configuration.outputScrolling = this.configurationService.getValue(NotebookSetting.outputScrolling); } + if (outputLinkifyFilePaths) { + configuration.outputLinkifyFilePaths = this.configurationService.getValue(NotebookSetting.LinkifyOutputFilePaths); + } + this._layoutConfiguration = Object.freeze(configuration); // trigger event @@ -504,7 +514,8 @@ export class NotebookOptions extends Disposable { interactiveWindowCollapseCodeCells, outputLineHeight, outputScrolling, - outputWordWrap + outputWordWrap, + outputLinkifyFilePaths: outputLinkifyFilePaths }); } @@ -713,6 +724,7 @@ export class NotebookOptions extends Disposable { outputScrolling: this._layoutConfiguration.outputScrolling, outputWordWrap: this._layoutConfiguration.outputWordWrap, outputLineLimit: this._layoutConfiguration.outputLineLimit, + outputLinkifyFilePaths: this._layoutConfiguration.outputLinkifyFilePaths, }; } @@ -734,6 +746,7 @@ export class NotebookOptions extends Disposable { outputScrolling: this._layoutConfiguration.outputScrolling, outputWordWrap: this._layoutConfiguration.outputWordWrap, outputLineLimit: this._layoutConfiguration.outputLineLimit, + outputLinkifyFilePaths: false }; } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index 83a3f715efd..6891a9ff4bf 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -117,6 +117,7 @@ interface BacklayerWebviewOptions { readonly outputScrolling: boolean; readonly outputWordWrap: boolean; readonly outputLineLimit: number; + readonly outputLinkifyFilePaths: boolean; } @@ -245,7 +246,8 @@ export class BackLayerWebView extends Themable { renderOptions: { lineLimit: this.options.outputLineLimit, outputScrolling: this.options.outputScrolling, - outputWordWrap: this.options.outputWordWrap + outputWordWrap: this.options.outputWordWrap, + linkifyFilePaths: this.options.outputLinkifyFilePaths, } }); } @@ -283,7 +285,8 @@ export class BackLayerWebView extends Themable { const renderOptions = { lineLimit: this.options.outputLineLimit, outputScrolling: this.options.outputScrolling, - outputWordWrap: this.options.outputWordWrap + outputWordWrap: this.options.outputWordWrap, + linkifyFilePaths: this.options.outputLinkifyFilePaths }; const preloadScript = preloadsScriptStr( { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 802a46145f8..6a0eb8e644b 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -70,6 +70,7 @@ export interface RenderOptions { readonly lineLimit: number; readonly outputScrolling: boolean; readonly outputWordWrap: boolean; + readonly linkifyFilePaths: boolean; } interface PreloadContext { @@ -1696,6 +1697,7 @@ async function webviewPreloads(ctx: PreloadContext) { get lineLimit() { return currentRenderOptions.lineLimit; }, get outputScrolling() { return currentRenderOptions.outputScrolling; }, get outputWordWrap() { return currentRenderOptions.outputWordWrap; }, + get linkifyFilePaths() { return currentRenderOptions.linkifyFilePaths; }, }, get onDidChangeSettings() { return settingChange.event; } }; diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index 29b3da03f12..e076f6ebf7e 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -956,6 +956,7 @@ export const NotebookSetting = { outputScrollingDeprecated: 'notebook.experimental.outputScrolling', outputScrolling: 'notebook.output.scrolling', textOutputLineLimit: 'notebook.output.textLineLimit', + LinkifyOutputFilePaths: 'notebook.output.linkifyFilePaths', formatOnSave: 'notebook.formatOnSave.enabled', insertFinalNewline: 'notebook.insertFinalNewline', formatOnCellExecution: 'notebook.formatOnCellExecution', From 72cb92fdc5d08101d65d59e4b1c046d397896dd2 Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 11 Dec 2023 18:44:17 -0700 Subject: [PATCH 42/80] Fix explorer paste (#200601) Fix paste --- src/vs/workbench/contrib/files/browser/explorerService.ts | 3 --- src/vs/workbench/contrib/files/browser/views/explorerView.ts | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/files/browser/explorerService.ts b/src/vs/workbench/contrib/files/browser/explorerService.ts index ed417b5fee5..8d184d071a0 100644 --- a/src/vs/workbench/contrib/files/browser/explorerService.ts +++ b/src/vs/workbench/contrib/files/browser/explorerService.ts @@ -286,9 +286,6 @@ export class ExplorerService implements IExplorerService { const previouslyCutItems = this.cutItems; this.cutItems = cut ? items : undefined; await this.clipboardService.writeResources(items.map(s => s.resource)); - if (items.length === 1) { - await this.clipboardService.writeText(items[0].name); - } this.view?.itemsCopied(items, cut, previouslyCutItems); } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index ff7b7892680..237fbfe5301 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -329,8 +329,9 @@ export class ExplorerView extends ViewPane implements IExplorerView { if (!this.hasFocus() || this.readonlyContext.get()) { return; } - - await this.commandService.executeCommand('filesExplorer.paste', event.clipboardData?.files); + if (event.clipboardData?.files?.length) { + await this.commandService.executeCommand('filesExplorer.paste', event.clipboardData?.files); + } })); } From df9f2a1868d2642c4b9c15e5a1991e57a8e28bf9 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 11 Dec 2023 20:59:55 -0800 Subject: [PATCH 43/80] Fix ChatAgentTask placeholder styling Fix #200575 --- src/vs/workbench/contrib/chat/browser/media/chat.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/chat/browser/media/chat.css b/src/vs/workbench/contrib/chat/browser/media/chat.css index 98919f4cad6..de89b0c9c7c 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chat.css +++ b/src/vs/workbench/contrib/chat/browser/media/chat.css @@ -520,6 +520,11 @@ .interactive-item-container .value .interactive-response-placeholder-content { color: var(--vscode-editorGhostText-foreground); font-size: 12px; + margin-bottom: 16px; +} + +.interactive-item-container .value .interactive-response-placeholder-content p { + margin: 0; } .interactive-response .interactive-response-codicon-details { From 9c679f1e07bd56c8ed8dbb3ebaa508a250aebcd3 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Dec 2023 11:14:59 +0100 Subject: [PATCH 44/80] Aux window: `increase current view size` doesn't consider floating windows (fix #200613) (#200617) --- .../workbench/browser/actions/layoutActions.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/browser/actions/layoutActions.ts b/src/vs/workbench/browser/actions/layoutActions.ts index 4a2a2ad5dc6..fd2348aabcf 100644 --- a/src/vs/workbench/browser/actions/layoutActions.ts +++ b/src/vs/workbench/browser/actions/layoutActions.ts @@ -1217,7 +1217,8 @@ class IncreaseViewSizeAction extends BaseResizeViewAction { super({ id: 'workbench.action.increaseViewSize', title: { value: localize('increaseViewSize', "Increase Current View Size"), original: 'Increase Current View Size' }, - f1: true + f1: true, + precondition: IsAuxiliaryWindowFocusedContext.toNegated() }); } @@ -1232,7 +1233,8 @@ class IncreaseViewWidthAction extends BaseResizeViewAction { super({ id: 'workbench.action.increaseViewWidth', title: { value: localize('increaseEditorWidth', "Increase Editor Width"), original: 'Increase Editor Width' }, - f1: true + f1: true, + precondition: IsAuxiliaryWindowFocusedContext.toNegated() }); } @@ -1247,7 +1249,8 @@ class IncreaseViewHeightAction extends BaseResizeViewAction { super({ id: 'workbench.action.increaseViewHeight', title: { value: localize('increaseEditorHeight', "Increase Editor Height"), original: 'Increase Editor Height' }, - f1: true + f1: true, + precondition: IsAuxiliaryWindowFocusedContext.toNegated() }); } @@ -1262,7 +1265,8 @@ class DecreaseViewSizeAction extends BaseResizeViewAction { super({ id: 'workbench.action.decreaseViewSize', title: { value: localize('decreaseViewSize', "Decrease Current View Size"), original: 'Decrease Current View Size' }, - f1: true + f1: true, + precondition: IsAuxiliaryWindowFocusedContext.toNegated() }); } @@ -1276,7 +1280,8 @@ class DecreaseViewWidthAction extends BaseResizeViewAction { super({ id: 'workbench.action.decreaseViewWidth', title: { value: localize('decreaseEditorWidth', "Decrease Editor Width"), original: 'Decrease Editor Width' }, - f1: true + f1: true, + precondition: IsAuxiliaryWindowFocusedContext.toNegated() }); } @@ -1291,7 +1296,8 @@ class DecreaseViewHeightAction extends BaseResizeViewAction { super({ id: 'workbench.action.decreaseViewHeight', title: { value: localize('decreaseEditorHeight', "Decrease Editor Height"), original: 'Decrease Editor Height' }, - f1: true + f1: true, + precondition: IsAuxiliaryWindowFocusedContext.toNegated() }); } From e7b5076dd7a2f807902664f26581f2c1fb7dce0b Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 12 Dec 2023 19:39:00 +0900 Subject: [PATCH 45/80] refactor: use sysroots on linux prod pipeline (#192513) * ci: use sysroots on linux prod pipeline to build native modules * ci: rebuild after electron update --- build/.cachesalt | 2 +- .../cli/cli-compile-and-publish.yml | 46 +++++- .../azure-pipelines/linux/cli-build-linux.yml | 49 +++++- build/azure-pipelines/linux/install.sh | 37 ++++- .../linux/product-build-linux.yml | 89 ++++++----- build/checksums/vscode-sysroot.txt | 3 + build/gulpfile.vscode.linux.js | 35 +++-- build/linux/debian/calculate-deps.js | 21 ++- build/linux/debian/calculate-deps.ts | 33 ++-- build/linux/debian/dep-lists.js | 30 ++-- build/linux/debian/dep-lists.ts | 30 ++-- build/linux/debian/install-sysroot.js | 137 ++++++++++++++++- build/linux/debian/install-sysroot.ts | 145 +++++++++++++++++- build/linux/dependencies-generator.js | 25 ++- build/linux/dependencies-generator.ts | 26 ++-- build/linux/rpm/dep-lists.js | 18 +++ build/linux/rpm/dep-lists.ts | 18 +++ build/npm/postinstall.js | 17 +- build/yarn.lock | 6 +- 19 files changed, 597 insertions(+), 170 deletions(-) create mode 100644 build/checksums/vscode-sysroot.txt diff --git a/build/.cachesalt b/build/.cachesalt index 1aad2ab5206..a8a329ac0b8 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2023-09-06T09:54:45.225Z +2023-12-07T16:21:36.646Z diff --git a/build/azure-pipelines/cli/cli-compile-and-publish.yml b/build/azure-pipelines/cli/cli-compile-and-publish.yml index 05ad5538d87..0fd3abfd6d8 100644 --- a/build/azure-pipelines/cli/cli-compile-and-publish.yml +++ b/build/azure-pipelines/cli/cli-compile-and-publish.yml @@ -38,14 +38,44 @@ steps: ${{ pair.key }}: ${{ pair.value }} - ${{ else }}: - - script: cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code - displayName: Compile ${{ parameters.VSCODE_CLI_TARGET }} - workingDirectory: $(Build.SourcesDirectory)/cli - env: - CARGO_NET_GIT_FETCH_WITH_CLI: true - VSCODE_CLI_COMMIT: $(Build.SourceVersion) - ${{ each pair in parameters.VSCODE_CLI_ENV }}: - ${{ pair.key }}: ${{ pair.value }} + - ${{ if contains(parameters.VSCODE_CLI_TARGET, '-linux-') }}: + - script: | + set -e + if [ -n "$SYSROOT_ARCH" ]; then + export VSCODE_SYSROOT_DIR=$(Build.SourcesDirectory)/.build/sysroots + node -e '(async () => { const { getVSCodeSysroot } = require("../build/linux/debian/install-sysroot.js"); await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' + if [ "$SYSROOT_ARCH" == "arm64" ]; then + export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc" + export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" + export CC_aarch64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc --sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" + elif [ "$SYSROOT_ARCH" == "amd64" ]; then + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc" + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -C link-arg=-L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu" + export CC_x86_64_unknown_linux_gnu="$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot" + elif [ "$SYSROOT_ARCH" == "armhf" ]; then + export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc" + export CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUSTFLAGS="-C link-arg=--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" + export CC_armv7_unknown_linux_gnueabihf="$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc --sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" + fi + fi + cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code + displayName: Compile ${{ parameters.VSCODE_CLI_TARGET }} + workingDirectory: $(Build.SourcesDirectory)/cli + env: + CARGO_NET_GIT_FETCH_WITH_CLI: true + VSCODE_CLI_COMMIT: $(Build.SourceVersion) + ${{ each pair in parameters.VSCODE_CLI_ENV }}: + ${{ pair.key }}: ${{ pair.value }} + + - ${{ else }}: + - script: cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code + displayName: Compile ${{ parameters.VSCODE_CLI_TARGET }} + workingDirectory: $(Build.SourcesDirectory)/cli + env: + CARGO_NET_GIT_FETCH_WITH_CLI: true + VSCODE_CLI_COMMIT: $(Build.SourceVersion) + ${{ each pair in parameters.VSCODE_CLI_ENV }}: + ${{ pair.key }}: ${{ pair.value }} - ${{ if contains(parameters.VSCODE_CLI_TARGET, '-windows-') }}: - powershell: | diff --git a/build/azure-pipelines/linux/cli-build-linux.yml b/build/azure-pipelines/linux/cli-build-linux.yml index ae031140e74..a820c588e61 100644 --- a/build/azure-pipelines/linux/cli-build-linux.yml +++ b/build/azure-pipelines/linux/cli-build-linux.yml @@ -39,13 +39,45 @@ steps: tar -xvzf $(Build.ArtifactStagingDirectory)/vscode-internal-openssl-prebuilt-0.0.11.tgz --strip-components=1 --directory=$(Build.ArtifactStagingDirectory)/openssl displayName: Extract openssl prebuilt - - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true) }}: - - bash: sudo apt-get install -yq gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf binutils-arm-linux-gnueabihf - displayName: Install arm32 toolchains + - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: + - script: node build/setup-npm-registry.js $NPM_REGISTRY + condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) + displayName: Setup NPM Registry - - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARM64, true) }}: - - bash: sudo apt-get install -yq gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu - displayName: Install arm64 toolchains + - script: | + set -e + npm config set registry "$NPM_REGISTRY" --location=project + # npm >v7 deprecated the `always-auth` config option, refs npm/cli@72a7eeb + # following is a workaround for yarn to send authorization header + # for GET requests to the registry. + echo "always-auth=true" >> .npmrc + yarn config set registry "$NPM_REGISTRY" + condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) + displayName: Setup NPM & Yarn + + - task: npmAuthenticate@0 + inputs: + workingFile: .npmrc + condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none')) + displayName: Setup NPM Authentication + + - script: | + set -e + + for i in {1..5}; do # try 5 times + yarn --cwd build --frozen-lockfile --check-files && break + if [ $i -eq 3 ]; then + echo "Yarn failed too many times" >&2 + exit 1 + fi + echo "Yarn failed $i, trying again..." + done + displayName: Install build dependencies + + - script: | + set -e + mkdir -p $(Build.SourcesDirectory)/.build + displayName: Create .build folder for misc dependencies - template: ../cli/install-rust-posix.yml parameters: @@ -65,9 +97,9 @@ steps: VSCODE_CLI_ARTIFACT: vscode_cli_linux_arm64_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: - CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm64-linux/include + SYSROOT_ARCH: arm64 - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - template: ../cli/cli-compile-and-publish.yml @@ -79,6 +111,7 @@ steps: VSCODE_CLI_ENV: OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/x64-linux/include + SYSROOT_ARCH: amd64 - ${{ if eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true) }}: - template: ../cli/cli-compile-and-publish.yml @@ -88,6 +121,6 @@ steps: VSCODE_CLI_ARTIFACT: vscode_cli_linux_armhf_cli VSCODE_CHECK_ONLY: ${{ parameters.VSCODE_CHECK_ONLY }} VSCODE_CLI_ENV: - CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm-linux/lib OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/openssl/arm-linux/include + SYSROOT_ARCH: armhf diff --git a/build/azure-pipelines/linux/install.sh b/build/azure-pipelines/linux/install.sh index 317a1b88455..16fefd2e754 100755 --- a/build/azure-pipelines/linux/install.sh +++ b/build/azure-pipelines/linux/install.sh @@ -5,7 +5,15 @@ set -e # To workaround the issue of yarn not respecting the registry value from .npmrc yarn config set registry "$NPM_REGISTRY" -if [ -z "$CC" ] || [ -z "$CXX" ]; then +SYSROOT_ARCH=$VSCODE_ARCH +if [ "$SYSROOT_ARCH" == "x64" ]; then + SYSROOT_ARCH="amd64" +fi + +export VSCODE_SYSROOT_DIR=$PWD/.build/sysroots +SYSROOT_ARCH="$SYSROOT_ARCH" node -e '(async () => { const { getVSCodeSysroot } = require("./build/linux/debian/install-sysroot.js"); await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()' + +if [ "$npm_config_arch" == "x64" ]; then # Download clang based on chromium revision used by vscode curl -s https://raw.githubusercontent.com/chromium/chromium/118.0.5993.159/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux @@ -22,12 +30,27 @@ if [ -z "$CC" ] || [ -z "$CXX" ]; then # https://source.chromium.org/chromium/chromium/src/+/refs/tags/118.0.5993.159:build/config/arm.gni # https://source.chromium.org/chromium/chromium/src/+/refs/tags/118.0.5993.159:build/config/compiler/BUILD.gn # https://source.chromium.org/chromium/chromium/src/+/refs/tags/118.0.5993.159:build/config/c++/BUILD.gn - export CC=$PWD/.build/CR_Clang/bin/clang - export CXX=$PWD/.build/CR_Clang/bin/clang++ - export CXXFLAGS="-nostdinc++ -D__NO_INLINE__ -I$PWD/.build/libcxx_headers -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit -D_LIBCPP_ABI_NAMESPACE=Cr" - export LDFLAGS="-stdlib=libc++ -fuse-ld=lld -flto=thin -L$PWD/.build/libcxx-objects -lc++abi -Wl,--lto-O0" - export VSCODE_REMOTE_CC=$(which gcc) - export VSCODE_REMOTE_CXX=$(which g++) + export CC="$PWD/.build/CR_Clang/bin/clang --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu" + export CXX="$PWD/.build/CR_Clang/bin/clang++ --gcc-toolchain=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu" + export CXXFLAGS="-nostdinc++ -D__NO_INLINE__ -I$PWD/.build/libcxx_headers -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit -D_LIBCPP_ABI_NAMESPACE=Cr --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot" + export LDFLAGS="-stdlib=libc++ --sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -fuse-ld=lld -flto=thin -L$PWD/.build/libcxx-objects -lc++abi -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu -Wl,--lto-O0" + # Set compiler toolchain for remote server + export VSCODE_REMOTE_CC=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-gcc + export VSCODE_REMOTE_CXX=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/bin/x86_64-linux-gnu-g++ + export VSCODE_REMOTE_CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot" + export VSCODE_REMOTE_LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/usr/lib/x86_64-linux-gnu -L$VSCODE_SYSROOT_DIR/x86_64-linux-gnu/x86_64-linux-gnu/sysroot/lib/x86_64-linux-gnu" +elif [ "$npm_config_arch" == "arm64" ]; then + # Set compiler toolchain for client native modules and remote server + export CC=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc + export CXX=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ + export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot" + export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu -L$VSCODE_SYSROOT_DIR/aarch64-linux-gnu/aarch64-linux-gnu/sysroot/lib/aarch64-linux-gnu" +elif [ "$npm_config_arch" == "arm" ]; then + # Set compiler toolchain for client native modules and remote server + export CC=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-gcc + export CXX=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/bin/arm-rpi-linux-gnueabihf-g++ + export CXXFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot" + export LDFLAGS="--sysroot=$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/usr/lib/arm-linux-gnueabihf -L$VSCODE_SYSROOT_DIR/arm-rpi-linux-gnueabihf/arm-rpi-linux-gnueabihf/sysroot/lib/arm-linux-gnueabihf" fi for i in {1..5}; do # try 5 times diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index c714b9a6c5e..a4b7faa3918 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -48,13 +48,13 @@ steps: # Start X server sudo apt-get update sudo apt-get install -y pkg-config \ - libxss1 \ dbus \ xvfb \ libgtk-3-0 \ - libgbm1 \ libxkbfile-dev \ - libkrb5-dev + libkrb5-dev \ + libgbm1 \ + rpm sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb sudo chmod +x /etc/init.d/xvfb sudo update-rc.d xvfb defaults @@ -100,17 +100,6 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none')) displayName: Setup NPM Authentication - - ${{ if and(ne(parameters.VSCODE_QUALITY, 'oss'), or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64'))) }}: - - task: Docker@1 - displayName: "Pull Docker image" - inputs: - azureSubscriptionEndpoint: "vscode-builds-subscription" - azureContainerRegistry: vscodehub.azurecr.io - command: "Run an image" - imageName: vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH) - containerCommand: uname - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - script: | set -e @@ -124,30 +113,62 @@ steps: echo "Yarn failed $i, trying again..." done - docker run -e GITHUB_TOKEN -e npm_config_arch -e NPM_REGISTRY \ - -e VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME -e VSCODE_HOST_MOUNT \ - -e ELECTRON_SKIP_BINARY_DOWNLOAD -e PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD \ - -e VSCODE_SKIP_NODE_VERSION_CHECK \ - -v /mnt/vss/_work/1/s:/home/builduser/vscode -v /mnt/vss/_work/1/s/.build/.netrc:/home/builduser/.netrc \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -u 1000:1000 \ - -w /home/builduser/vscode vscodehub.azurecr.io/vscode-linux-build-agent:bionic-$(VSCODE_ARCH) \ - /bin/bash -c "./build/azure-pipelines/linux/install.sh" - - sudo chown -R $USER:$USER /mnt/vss/_work/1/s + ./build/azure-pipelines/linux/install.sh env: npm_config_arch: $(NPM_ARCH) + VSCODE_ARCH: $(VSCODE_ARCH) NPM_REGISTRY: "$(NPM_REGISTRY)" ELECTRON_SKIP_BINARY_DOWNLOAD: 1 PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - VSCODE_SKIP_NODE_VERSION_CHECK: 1 GITHUB_TOKEN: "$(github-distro-mixin-password)" - VSCODE_HOST_MOUNT: "/mnt/vss/_work/1/s" - ${{ if or(eq(parameters.VSCODE_ARCH, 'x64'), eq(parameters.VSCODE_ARCH, 'arm64')) }}: - VSCODE_REMOTE_DEPENDENCIES_CONTAINER_NAME: vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-$(VSCODE_ARCH) displayName: Install dependencies (non-OSS) condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | + set -e + + TRIPLE="x86_64-linux-gnu" + if [ "$VSCODE_ARCH" == "arm64" ]; then + TRIPLE="aarch64-linux-gnu" + elif [ "$VSCODE_ARCH" == "armhf" ]; then + TRIPLE="arm-rpi-linux-gnueabihf" + fi + + # Get all files with .node extension from remote/node_modules folder + files=$(find remote/node_modules -name "*.node") + + # Check if any file has dependency of GLIBC > 2.28 or GLIBCXX > 3.4.25 + for file in $files; do + glibc_version="2.28" + glibcxx_version="3.4.25" + while IFS= read -r line; do + if [[ $line == *"GLIBC_"* ]]; then + version=$(echo "$line" | awk '{print $5}' | tr -d '()') + version=${version#*_} + if [[ $(printf "%s\n%s" "$version" "$glibc_version" | sort -V | tail -n1) == "$version" ]]; then + glibc_version=$version + fi + elif [[ $line == *"GLIBCXX_"* ]]; then + version=$(echo "$line" | awk '{print $5}' | tr -d '()') + version=${version#*_} + if [[ $(printf "%s\n%s" "$version" "$glibcxx_version" | sort -V | tail -n1) == "$version" ]]; then + glibcxx_version=$version + fi + fi + done < <("$PWD/.build/sysroots/$TRIPLE/$TRIPLE/bin/objdump" -T "$file") + + if [[ "$glibc_version" != "2.28" ]]; then + echo "Error: File $file has dependency on GLIBC > 2.28" + exit 1 + fi + if [[ "$glibcxx_version" != "3.4.25" ]]; then + echo "Error: File $file has dependency on GLIBCXX > 3.4.25" + exit 1 + fi + done + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + displayName: Check GLIBC and GLIBCXX dependencies in remote/node_modules + - script: node build/azure-pipelines/distro/mixin-npm condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Mixin distro node modules @@ -266,11 +287,6 @@ steps: - ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}: - script: | set -e - docker run -v /mnt/vss/_work/1/s:/home/builduser/vscode \ - -v /mnt/vss/_work/1/s/.build/.netrc:/home/builduser/.netrc \ - -v /mnt/vss/_work/1/VSCode-linux-$(VSCODE_ARCH):/home/builduser/VSCode-linux-$(VSCODE_ARCH) \ - -u 1000:1000 \ - -w /home/builduser/vscode vscodehub.azurecr.io/vscode-linux-build-agent:bionic-$(VSCODE_ARCH) \ yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-deb" displayName: Prepare deb package @@ -282,11 +298,6 @@ steps: - script: | set -e - docker run -v /mnt/vss/_work/1/s:/home/builduser/vscode \ - -v /mnt/vss/_work/1/s/.build/.netrc:/home/builduser/.netrc \ - -v /mnt/vss/_work/1/VSCode-linux-$(VSCODE_ARCH):/home/builduser/VSCode-linux-$(VSCODE_ARCH) \ - -u 1000:1000 \ - -w /home/builduser/vscode vscodehub.azurecr.io/vscode-linux-build-agent:bionic-$(VSCODE_ARCH) \ yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-rpm" displayName: Prepare rpm package diff --git a/build/checksums/vscode-sysroot.txt b/build/checksums/vscode-sysroot.txt new file mode 100644 index 00000000000..86da04db2ae --- /dev/null +++ b/build/checksums/vscode-sysroot.txt @@ -0,0 +1,3 @@ +a2d51dc505ed544c52757f90bcdab44920132295fc7a67166eff86b6e0e24aa8 aarch64-linux-gnu.tar.gz +032cf16bf8b965e1351305f10f3dedabf4f9868027ac6d0e8f52321ca0b70d4a arm-rpi-linux-gnueabihf.tar.gz +360475a764d0faf4d3743aa866347eff78072639d20660def83e1a03eadf534c x86_64-linux-gnu.tar.gz diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index 0d7d3c5b7f8..8c2b62f7b2a 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -17,7 +17,6 @@ const task = require('./lib/task'); const packageJson = require('../package.json'); const product = require('../product.json'); const dependenciesGenerator = require('./linux/dependencies-generator'); -const sysrootInstaller = require('./linux/debian/install-sysroot'); const debianRecommendedDependencies = require('./linux/debian/dep-lists').recommendedDeps; const path = require('path'); const root = path.dirname(__dirname); @@ -82,8 +81,7 @@ function prepareDebPackage(arch) { function (f) { size += f.isDirectory() ? 4096 : f.contents.length; }, async function () { const that = this; - const sysroot = await sysrootInstaller.getSysroot(debArch); - const dependencies = dependenciesGenerator.getDependencies('deb', binaryDir, product.applicationName, debArch, sysroot); + const dependencies = await dependenciesGenerator.getDependencies('deb', binaryDir, product.applicationName, debArch); gulp.src('resources/linux/debian/control.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@VERSION@@', packageJson.version + '-' + linuxPackageRevision)) @@ -186,19 +184,24 @@ function prepareRpmPackage(arch) { const code = gulp.src(binaryDir + '/**/*', { base: binaryDir }) .pipe(rename(function (p) { p.dirname = 'BUILD/usr/share/' + product.applicationName + '/' + p.dirname; })); - const dependencies = dependenciesGenerator.getDependencies('rpm', binaryDir, product.applicationName, rpmArch); - const spec = gulp.src('resources/linux/rpm/code.spec.template', { base: '.' }) - .pipe(replace('@@NAME@@', product.applicationName)) - .pipe(replace('@@NAME_LONG@@', product.nameLong)) - .pipe(replace('@@ICON@@', product.linuxIconName)) - .pipe(replace('@@VERSION@@', packageJson.version)) - .pipe(replace('@@RELEASE@@', linuxPackageRevision)) - .pipe(replace('@@ARCHITECTURE@@', rpmArch)) - .pipe(replace('@@LICENSE@@', product.licenseName)) - .pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@')) - .pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@')) - .pipe(replace('@@DEPENDENCIES@@', dependencies.join(', '))) - .pipe(rename('SPECS/' + product.applicationName + '.spec')); + const spec = code.pipe(es.through( + async function () { + const that = this; + const dependencies = await dependenciesGenerator.getDependencies('rpm', binaryDir, product.applicationName, rpmArch); + gulp.src('resources/linux/rpm/code.spec.template', { base: '.' }) + .pipe(replace('@@NAME@@', product.applicationName)) + .pipe(replace('@@NAME_LONG@@', product.nameLong)) + .pipe(replace('@@ICON@@', product.linuxIconName)) + .pipe(replace('@@VERSION@@', packageJson.version)) + .pipe(replace('@@RELEASE@@', linuxPackageRevision)) + .pipe(replace('@@ARCHITECTURE@@', rpmArch)) + .pipe(replace('@@LICENSE@@', product.licenseName)) + .pipe(replace('@@QUALITY@@', product.quality || '@@QUALITY@@')) + .pipe(replace('@@UPDATEURL@@', product.updateUrl || '@@UPDATEURL@@')) + .pipe(replace('@@DEPENDENCIES@@', dependencies.join(', '))) + .pipe(rename('SPECS/' + product.applicationName + '.spec')) + .pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); })); + })); const specIcon = gulp.src('resources/linux/rpm/code.xpm', { base: '.' }) .pipe(rename('SOURCES/' + product.applicationName + '.xpm')); diff --git a/build/linux/debian/calculate-deps.js b/build/linux/debian/calculate-deps.js index 6c74a8b64ef..6304df9edda 100644 --- a/build/linux/debian/calculate-deps.js +++ b/build/linux/debian/calculate-deps.js @@ -11,15 +11,15 @@ const os_1 = require("os"); const path = require("path"); const manifests = require("../../../cgmanifest.json"); const dep_lists_1 = require("./dep-lists"); -function generatePackageDeps(files, arch, sysroot) { - const dependencies = files.map(file => calculatePackageDeps(file, arch, sysroot)); +function generatePackageDeps(files, arch, chromiumSysroot, vscodeSysroot) { + const dependencies = files.map(file => calculatePackageDeps(file, arch, chromiumSysroot, vscodeSysroot)); const additionalDepsSet = new Set(dep_lists_1.additionalDeps); dependencies.push(additionalDepsSet); return dependencies; } exports.generatePackageDeps = generatePackageDeps; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py. -function calculatePackageDeps(binaryPath, arch, sysroot) { +function calculatePackageDeps(binaryPath, arch, chromiumSysroot, vscodeSysroot) { try { if (!((0, fs_1.statSync)(binaryPath).mode & fs_1.constants.S_IXUSR)) { throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); @@ -42,18 +42,19 @@ function calculatePackageDeps(binaryPath, arch, sysroot) { const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined']; switch (arch) { case 'amd64': - cmd.push(`-l${sysroot}/usr/lib/x86_64-linux-gnu`, `-l${sysroot}/lib/x86_64-linux-gnu`); + cmd.push(`-l${chromiumSysroot}/usr/lib/x86_64-linux-gnu`, `-l${chromiumSysroot}/lib/x86_64-linux-gnu`, `-l${vscodeSysroot}/usr/lib/x86_64-linux-gnu`, `-l${vscodeSysroot}/lib/x86_64-linux-gnu`); break; case 'armhf': - cmd.push(`-l${sysroot}/usr/lib/arm-linux-gnueabihf`, `-l${sysroot}/lib/arm-linux-gnueabihf`); + cmd.push(`-l${chromiumSysroot}/usr/lib/arm-linux-gnueabihf`, `-l${chromiumSysroot}/lib/arm-linux-gnueabihf`, `-l${vscodeSysroot}/usr/lib/arm-linux-gnueabihf`, `-l${vscodeSysroot}/lib/arm-linux-gnueabihf`); break; case 'arm64': - cmd.push(`-l${sysroot}/usr/lib/aarch64-linux-gnu`, `-l${sysroot}/lib/aarch64-linux-gnu`); + cmd.push(`-l${chromiumSysroot}/usr/lib/aarch64-linux-gnu`, `-l${chromiumSysroot}/lib/aarch64-linux-gnu`, `-l${vscodeSysroot}/usr/lib/aarch64-linux-gnu`, `-l${vscodeSysroot}/lib/aarch64-linux-gnu`); break; } - cmd.push(`-l${sysroot}/usr/lib`); + cmd.push(`-l${chromiumSysroot}/usr/lib`); + cmd.push(`-L${vscodeSysroot}/debian/libxkbfile1/DEBIAN/shlibs`); cmd.push('-O', '-e', path.resolve(binaryPath)); - const dpkgShlibdepsResult = (0, child_process_1.spawnSync)('perl', cmd, { cwd: sysroot }); + const dpkgShlibdepsResult = (0, child_process_1.spawnSync)('perl', cmd, { cwd: chromiumSysroot }); if (dpkgShlibdepsResult.status !== 0) { throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `); } @@ -78,9 +79,7 @@ function calculatePackageDeps(binaryPath, arch, sysroot) { // TODO(deepak1556): remove this workaround in favor of computing the // versions from build container for native modules. const filteredDeps = depsStr.split(', ').filter(dependency => { - return !dependency.startsWith('libgcc-s1') && - !dependency.startsWith('libgssapi-krb5-2') && - !dependency.startsWith('libkrb5-3'); + return !dependency.startsWith('libgcc-s1'); }).sort(); const requires = new Set(filteredDeps); return requires; diff --git a/build/linux/debian/calculate-deps.ts b/build/linux/debian/calculate-deps.ts index a23c41ace24..92f8065f262 100644 --- a/build/linux/debian/calculate-deps.ts +++ b/build/linux/debian/calculate-deps.ts @@ -11,15 +11,15 @@ import * as manifests from '../../../cgmanifest.json'; import { additionalDeps } from './dep-lists'; import { DebianArchString } from './types'; -export function generatePackageDeps(files: string[], arch: DebianArchString, sysroot: string): Set[] { - const dependencies: Set[] = files.map(file => calculatePackageDeps(file, arch, sysroot)); +export function generatePackageDeps(files: string[], arch: DebianArchString, chromiumSysroot: string, vscodeSysroot: string): Set[] { + const dependencies: Set[] = files.map(file => calculatePackageDeps(file, arch, chromiumSysroot, vscodeSysroot)); const additionalDepsSet = new Set(additionalDeps); dependencies.push(additionalDepsSet); return dependencies; } // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py. -function calculatePackageDeps(binaryPath: string, arch: DebianArchString, sysroot: string): Set { +function calculatePackageDeps(binaryPath: string, arch: DebianArchString, chromiumSysroot: string, vscodeSysroot: string): Set { try { if (!(statSync(binaryPath).mode & constants.S_IXUSR)) { throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); @@ -42,22 +42,29 @@ function calculatePackageDeps(binaryPath: string, arch: DebianArchString, sysroo const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined']; switch (arch) { case 'amd64': - cmd.push(`-l${sysroot}/usr/lib/x86_64-linux-gnu`, - `-l${sysroot}/lib/x86_64-linux-gnu`); + cmd.push(`-l${chromiumSysroot}/usr/lib/x86_64-linux-gnu`, + `-l${chromiumSysroot}/lib/x86_64-linux-gnu`, + `-l${vscodeSysroot}/usr/lib/x86_64-linux-gnu`, + `-l${vscodeSysroot}/lib/x86_64-linux-gnu`); break; case 'armhf': - cmd.push(`-l${sysroot}/usr/lib/arm-linux-gnueabihf`, - `-l${sysroot}/lib/arm-linux-gnueabihf`); + cmd.push(`-l${chromiumSysroot}/usr/lib/arm-linux-gnueabihf`, + `-l${chromiumSysroot}/lib/arm-linux-gnueabihf`, + `-l${vscodeSysroot}/usr/lib/arm-linux-gnueabihf`, + `-l${vscodeSysroot}/lib/arm-linux-gnueabihf`); break; case 'arm64': - cmd.push(`-l${sysroot}/usr/lib/aarch64-linux-gnu`, - `-l${sysroot}/lib/aarch64-linux-gnu`); + cmd.push(`-l${chromiumSysroot}/usr/lib/aarch64-linux-gnu`, + `-l${chromiumSysroot}/lib/aarch64-linux-gnu`, + `-l${vscodeSysroot}/usr/lib/aarch64-linux-gnu`, + `-l${vscodeSysroot}/lib/aarch64-linux-gnu`); break; } - cmd.push(`-l${sysroot}/usr/lib`); + cmd.push(`-l${chromiumSysroot}/usr/lib`); + cmd.push(`-L${vscodeSysroot}/debian/libxkbfile1/DEBIAN/shlibs`); cmd.push('-O', '-e', path.resolve(binaryPath)); - const dpkgShlibdepsResult = spawnSync('perl', cmd, { cwd: sysroot }); + const dpkgShlibdepsResult = spawnSync('perl', cmd, { cwd: chromiumSysroot }); if (dpkgShlibdepsResult.status !== 0) { throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `); } @@ -83,9 +90,7 @@ function calculatePackageDeps(binaryPath: string, arch: DebianArchString, sysroo // TODO(deepak1556): remove this workaround in favor of computing the // versions from build container for native modules. const filteredDeps = depsStr.split(', ').filter(dependency => { - return !dependency.startsWith('libgcc-s1') && - !dependency.startsWith('libgssapi-krb5-2') && - !dependency.startsWith('libkrb5-3'); + return !dependency.startsWith('libgcc-s1'); }).sort(); const requires = new Set(filteredDeps); return requires; diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js index 3005e01e7be..bdb265b6fec 100644 --- a/build/linux/debian/dep-lists.js +++ b/build/linux/debian/dep-lists.js @@ -13,8 +13,6 @@ exports.additionalDeps = [ 'libnss3 (>= 3.26)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports. 'xdg-utils (>= 1.0.2)', // OS integration - 'libgssapi-krb5-2', - 'libkrb5-3', ]; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends // Dependencies that we can only recommend @@ -33,6 +31,7 @@ exports.referenceGeneratedDepsByArch = { 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', + 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', @@ -40,10 +39,10 @@ exports.referenceGeneratedDepsByArch = { 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', - 'libgssapi-krb5-2', + 'libgssapi-krb5-2 (>= 1.17)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libkrb5-3', + 'libkrb5-3 (>= 1.6.dfsg.2)', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', @@ -56,9 +55,10 @@ exports.referenceGeneratedDepsByArch = { 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', - 'libxkbfile1', + 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', - 'xdg-utils (>= 1.0.2)' + 'xdg-utils (>= 1.0.2)', + 'zlib1g (>= 1:1.2.3.4)' ], 'armhf': [ 'ca-certificates', @@ -66,11 +66,10 @@ exports.referenceGeneratedDepsByArch = { 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.15)', 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', + 'libc6 (>= 2.28)', 'libc6 (>= 2.4)', - 'libc6 (>= 2.8)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', @@ -79,14 +78,15 @@ exports.referenceGeneratedDepsByArch = { 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', - 'libgssapi-krb5-2', + 'libgssapi-krb5-2 (>= 1.17)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libkrb5-3', + 'libkrb5-3 (>= 1.6.dfsg.2)', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', + 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', @@ -98,7 +98,7 @@ exports.referenceGeneratedDepsByArch = { 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', - 'libxkbfile1', + 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ], @@ -109,6 +109,7 @@ exports.referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', + 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', @@ -116,14 +117,15 @@ exports.referenceGeneratedDepsByArch = { 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', - 'libgssapi-krb5-2', + 'libgssapi-krb5-2 (>= 1.17)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libkrb5-3', + 'libkrb5-3 (>= 1.6.dfsg.2)', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', + 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', @@ -135,7 +137,7 @@ exports.referenceGeneratedDepsByArch = { 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', - 'libxkbfile1', + 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ] diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts index 4674f584bfe..3d6c2eba6e9 100644 --- a/build/linux/debian/dep-lists.ts +++ b/build/linux/debian/dep-lists.ts @@ -11,8 +11,6 @@ export const additionalDeps = [ 'libnss3 (>= 3.26)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports. 'xdg-utils (>= 1.0.2)', // OS integration - 'libgssapi-krb5-2', - 'libkrb5-3', ]; // Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends @@ -33,6 +31,7 @@ export const referenceGeneratedDepsByArch = { 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', 'libc6 (>= 2.2.5)', + 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', @@ -40,10 +39,10 @@ export const referenceGeneratedDepsByArch = { 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', - 'libgssapi-krb5-2', + 'libgssapi-krb5-2 (>= 1.17)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libkrb5-3', + 'libkrb5-3 (>= 1.6.dfsg.2)', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', @@ -56,9 +55,10 @@ export const referenceGeneratedDepsByArch = { 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', - 'libxkbfile1', + 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', - 'xdg-utils (>= 1.0.2)' + 'xdg-utils (>= 1.0.2)', + 'zlib1g (>= 1:1.2.3.4)' ], 'armhf': [ 'ca-certificates', @@ -66,11 +66,10 @@ export const referenceGeneratedDepsByArch = { 'libatk-bridge2.0-0 (>= 2.5.3)', 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.15)', 'libc6 (>= 2.16)', 'libc6 (>= 2.17)', + 'libc6 (>= 2.28)', 'libc6 (>= 2.4)', - 'libc6 (>= 2.8)', 'libc6 (>= 2.9)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', @@ -79,14 +78,15 @@ export const referenceGeneratedDepsByArch = { 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', - 'libgssapi-krb5-2', + 'libgssapi-krb5-2 (>= 1.17)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libkrb5-3', + 'libkrb5-3 (>= 1.6.dfsg.2)', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', + 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', @@ -98,7 +98,7 @@ export const referenceGeneratedDepsByArch = { 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', - 'libxkbfile1', + 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ], @@ -109,6 +109,7 @@ export const referenceGeneratedDepsByArch = { 'libatk1.0-0 (>= 2.2.0)', 'libatspi2.0-0 (>= 2.9.90)', 'libc6 (>= 2.17)', + 'libc6 (>= 2.28)', 'libcairo2 (>= 1.6.0)', 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', 'libdbus-1-3 (>= 1.9.14)', @@ -116,14 +117,15 @@ export const referenceGeneratedDepsByArch = { 'libexpat1 (>= 2.1~beta3)', 'libgbm1 (>= 17.1.0~rc2)', 'libglib2.0-0 (>= 2.37.3)', - 'libgssapi-krb5-2', + 'libgssapi-krb5-2 (>= 1.17)', 'libgtk-3-0 (>= 3.9.10)', 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libkrb5-3', + 'libkrb5-3 (>= 1.6.dfsg.2)', 'libnspr4 (>= 2:4.9-2~)', 'libnss3 (>= 2:3.30)', 'libnss3 (>= 3.26)', 'libpango-1.0-0 (>= 1.14.0)', + 'libstdc++6 (>= 4.1.1)', 'libstdc++6 (>= 5)', 'libstdc++6 (>= 5.2)', 'libstdc++6 (>= 6)', @@ -135,7 +137,7 @@ export const referenceGeneratedDepsByArch = { 'libxext6', 'libxfixes3', 'libxkbcommon0 (>= 0.5.0)', - 'libxkbfile1', + 'libxkbfile1 (>= 1:1.1.0)', 'libxrandr2', 'xdg-utils (>= 1.0.2)' ] diff --git a/build/linux/debian/install-sysroot.js b/build/linux/debian/install-sysroot.js index 03cdc8dc97c..de6c1656411 100644 --- a/build/linux/debian/install-sysroot.js +++ b/build/linux/debian/install-sysroot.js @@ -4,17 +4,35 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); -exports.getSysroot = void 0; +exports.getChromiumSysroot = exports.getVSCodeSysroot = void 0; const child_process_1 = require("child_process"); -const crypto_1 = require("crypto"); const os_1 = require("os"); const fs = require("fs"); const https = require("https"); const path = require("path"); -const util = require("../../lib/util"); +const crypto_1 = require("crypto"); +const ansiColors = require("ansi-colors"); // Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. const URL_PREFIX = 'https://msftelectron.blob.core.windows.net'; const URL_PATH = 'sysroots/toolchain'; +const REPO_ROOT = path.dirname(path.dirname(path.dirname(__dirname))); +const ghApiHeaders = { + Accept: 'application/vnd.github.v3+json', + 'User-Agent': 'VSCode Build', +}; +if (process.env.GITHUB_TOKEN) { + ghApiHeaders.Authorization = 'Basic ' + Buffer.from(process.env.GITHUB_TOKEN).toString('base64'); +} +const ghDownloadHeaders = { + ...ghApiHeaders, + Accept: 'application/octet-stream', +}; +function getElectronVersion() { + const yarnrc = fs.readFileSync(path.join(REPO_ROOT, '.yarnrc'), 'utf8'); + const electronVersion = /^target "(.*)"$/m.exec(yarnrc)[1]; + const msBuildId = /^ms_build_id "(.*)"$/m.exec(yarnrc)[1]; + return { electronVersion, msBuildId }; +} function getSha(filename) { const hash = (0, crypto_1.createHash)('sha1'); // Read file 1 MB at a time @@ -29,8 +47,115 @@ function getSha(filename) { hash.update(buffer.slice(0, bytesRead)); return hash.digest('hex'); } -async function getSysroot(arch) { - const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${util.getElectronVersion().electronVersion}/script/sysroots.json`; +function getVSCodeSysrootChecksum(expectedName) { + const checksums = fs.readFileSync(path.join(REPO_ROOT, 'build', 'checksums', 'vscode-sysroot.txt'), 'utf8'); + for (const line of checksums.split('\n')) { + const [checksum, name] = line.split(/\s+/); + if (name === expectedName) { + return checksum; + } + } + return undefined; +} +/* + * Do not use the fetch implementation from build/lib/fetch as it relies on vinyl streams + * and vinyl-fs breaks the symlinks in the compiler toolchain sysroot. We use the native + * tar implementation for that reason. + */ +async function fetchUrl(options, retries = 10, retryDelay = 1000) { + try { + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), 30 * 1000); + const version = '20231122-245579'; + try { + const response = await fetch(`https://api.github.com/repos/Microsoft/vscode-linux-build-agent/releases/tags/v${version}`, { + headers: ghApiHeaders, + signal: controller.signal /* Typings issue with lib.dom.d.ts */ + }); + if (response.ok && (response.status >= 200 && response.status < 300)) { + console.log(`Fetch completed: Status ${response.status}.`); + const contents = Buffer.from(await response.arrayBuffer()); + const asset = JSON.parse(contents.toString()).assets.find((a) => a.name === options.assetName); + if (!asset) { + throw new Error(`Could not find asset in release of Microsoft/vscode-linux-build-agent @ ${version}`); + } + console.log(`Found asset ${options.assetName} @ ${asset.url}.`); + const assetResponse = await fetch(asset.url, { + headers: ghDownloadHeaders + }); + if (assetResponse.ok && (assetResponse.status >= 200 && assetResponse.status < 300)) { + const assetContents = Buffer.from(await assetResponse.arrayBuffer()); + console.log(`Fetched response body buffer: ${ansiColors.magenta(`${assetContents.byteLength} bytes`)}`); + if (options.checksumSha256) { + const actualSHA256Checksum = (0, crypto_1.createHash)('sha256').update(assetContents).digest('hex'); + if (actualSHA256Checksum !== options.checksumSha256) { + throw new Error(`Checksum mismatch for ${ansiColors.cyan(asset.url)} (expected ${options.checksumSha256}, actual ${actualSHA256Checksum}))`); + } + } + console.log(`Verified SHA256 checksums match for ${ansiColors.cyan(asset.url)}`); + const tarCommand = `tar -xz -C ${options.dest}`; + (0, child_process_1.execSync)(tarCommand, { input: assetContents }); + console.log(`Fetch complete!`); + return; + } + throw new Error(`Request ${ansiColors.magenta(asset.url)} failed with status code: ${assetResponse.status}`); + } + throw new Error(`Request ${ansiColors.magenta('https://api.github.com')} failed with status code: ${response.status}`); + } + finally { + clearTimeout(timeout); + } + } + catch (e) { + if (retries > 0) { + console.log(`Fetching failed: ${e}`); + await new Promise(resolve => setTimeout(resolve, retryDelay)); + return fetchUrl(options, retries - 1, retryDelay); + } + throw e; + } +} +async function getVSCodeSysroot(arch) { + let expectedName; + let triple; + switch (arch) { + case 'amd64': + expectedName = `x86_64-linux-gnu.tar.gz`; + triple = 'x86_64-linux-gnu'; + break; + case 'arm64': + expectedName = `aarch64-linux-gnu.tar.gz`; + triple = 'aarch64-linux-gnu'; + break; + case 'armhf': + expectedName = `arm-rpi-linux-gnueabihf.tar.gz`; + triple = 'arm-rpi-linux-gnueabihf'; + break; + } + const checksumSha256 = getVSCodeSysrootChecksum(expectedName); + if (!checksumSha256) { + throw new Error(`Could not find checksum for ${expectedName}`); + } + const sysroot = process.env['VSCODE_SYSROOT_DIR'] ?? path.join((0, os_1.tmpdir)(), `vscode-${arch}-sysroot`); + const stamp = path.join(sysroot, '.stamp'); + const result = `${sysroot}/${triple}/${triple}/sysroot`; + if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === expectedName) { + return result; + } + console.log(`Installing ${arch} root image: ${sysroot}`); + fs.rmSync(sysroot, { recursive: true, force: true }); + fs.mkdirSync(sysroot); + await fetchUrl({ + checksumSha256, + assetName: expectedName, + dest: sysroot + }); + fs.writeFileSync(stamp, expectedName); + return result; +} +exports.getVSCodeSysroot = getVSCodeSysroot; +async function getChromiumSysroot(arch) { + const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${getElectronVersion().electronVersion}/script/sysroots.json`; const sysrootDictLocation = `${(0, os_1.tmpdir)()}/sysroots.json`; const result = (0, child_process_1.spawnSync)('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]); if (result.status !== 0) { @@ -86,5 +211,5 @@ async function getSysroot(arch) { fs.writeFileSync(stamp, url); return sysroot; } -exports.getSysroot = getSysroot; +exports.getChromiumSysroot = getChromiumSysroot; //# sourceMappingURL=install-sysroot.js.map \ No newline at end of file diff --git a/build/linux/debian/install-sysroot.ts b/build/linux/debian/install-sysroot.ts index 63ba46c9eef..9de84d60624 100644 --- a/build/linux/debian/install-sysroot.ts +++ b/build/linux/debian/install-sysroot.ts @@ -3,18 +3,46 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { spawnSync } from 'child_process'; -import { createHash } from 'crypto'; +import { spawnSync, execSync } from 'child_process'; import { tmpdir } from 'os'; import * as fs from 'fs'; import * as https from 'https'; import * as path from 'path'; +import { createHash } from 'crypto'; import { DebianArchString } from './types'; -import * as util from '../../lib/util'; +import * as ansiColors from 'ansi-colors'; // Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. const URL_PREFIX = 'https://msftelectron.blob.core.windows.net'; const URL_PATH = 'sysroots/toolchain'; +const REPO_ROOT = path.dirname(path.dirname(path.dirname(__dirname))); + +const ghApiHeaders: Record = { + Accept: 'application/vnd.github.v3+json', + 'User-Agent': 'VSCode Build', +}; + +if (process.env.GITHUB_TOKEN) { + ghApiHeaders.Authorization = 'Basic ' + Buffer.from(process.env.GITHUB_TOKEN).toString('base64'); +} + +const ghDownloadHeaders = { + ...ghApiHeaders, + Accept: 'application/octet-stream', +}; + +interface IFetchOptions { + assetName: string; + checksumSha256?: string; + dest: string; +} + +function getElectronVersion(): Record { + const yarnrc = fs.readFileSync(path.join(REPO_ROOT, '.yarnrc'), 'utf8'); + const electronVersion = /^target "(.*)"$/m.exec(yarnrc)![1]; + const msBuildId = /^ms_build_id "(.*)"$/m.exec(yarnrc)![1]; + return { electronVersion, msBuildId }; +} function getSha(filename: fs.PathLike): string { const hash = createHash('sha1'); @@ -31,14 +59,121 @@ function getSha(filename: fs.PathLike): string { return hash.digest('hex'); } +function getVSCodeSysrootChecksum(expectedName: string) { + const checksums = fs.readFileSync(path.join(REPO_ROOT, 'build', 'checksums', 'vscode-sysroot.txt'), 'utf8'); + for (const line of checksums.split('\n')) { + const [checksum, name] = line.split(/\s+/); + if (name === expectedName) { + return checksum; + } + } + return undefined; +} + +/* + * Do not use the fetch implementation from build/lib/fetch as it relies on vinyl streams + * and vinyl-fs breaks the symlinks in the compiler toolchain sysroot. We use the native + * tar implementation for that reason. + */ +async function fetchUrl(options: IFetchOptions, retries = 10, retryDelay = 1000): Promise { + try { + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), 30 * 1000); + const version = '20231122-245579'; + try { + const response = await fetch(`https://api.github.com/repos/Microsoft/vscode-linux-build-agent/releases/tags/v${version}`, { + headers: ghApiHeaders, + signal: controller.signal as any /* Typings issue with lib.dom.d.ts */ + }); + if (response.ok && (response.status >= 200 && response.status < 300)) { + console.log(`Fetch completed: Status ${response.status}.`); + const contents = Buffer.from(await response.arrayBuffer()); + const asset = JSON.parse(contents.toString()).assets.find((a: { name: string }) => a.name === options.assetName); + if (!asset) { + throw new Error(`Could not find asset in release of Microsoft/vscode-linux-build-agent @ ${version}`); + } + console.log(`Found asset ${options.assetName} @ ${asset.url}.`); + const assetResponse = await fetch(asset.url, { + headers: ghDownloadHeaders + }); + if (assetResponse.ok && (assetResponse.status >= 200 && assetResponse.status < 300)) { + const assetContents = Buffer.from(await assetResponse.arrayBuffer()); + console.log(`Fetched response body buffer: ${ansiColors.magenta(`${(assetContents as Buffer).byteLength} bytes`)}`); + if (options.checksumSha256) { + const actualSHA256Checksum = createHash('sha256').update(assetContents).digest('hex'); + if (actualSHA256Checksum !== options.checksumSha256) { + throw new Error(`Checksum mismatch for ${ansiColors.cyan(asset.url)} (expected ${options.checksumSha256}, actual ${actualSHA256Checksum}))`); + } + } + console.log(`Verified SHA256 checksums match for ${ansiColors.cyan(asset.url)}`); + const tarCommand = `tar -xz -C ${options.dest}`; + execSync(tarCommand, { input: assetContents }); + console.log(`Fetch complete!`); + return; + } + throw new Error(`Request ${ansiColors.magenta(asset.url)} failed with status code: ${assetResponse.status}`); + } + throw new Error(`Request ${ansiColors.magenta('https://api.github.com')} failed with status code: ${response.status}`); + } finally { + clearTimeout(timeout); + } + } catch (e) { + if (retries > 0) { + console.log(`Fetching failed: ${e}`); + await new Promise(resolve => setTimeout(resolve, retryDelay)); + return fetchUrl(options, retries - 1, retryDelay); + } + throw e; + } +} + type SysrootDictEntry = { Sha1Sum: string; SysrootDir: string; Tarball: string; }; -export async function getSysroot(arch: DebianArchString): Promise { - const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${util.getElectronVersion().electronVersion}/script/sysroots.json`; +export async function getVSCodeSysroot(arch: DebianArchString): Promise { + let expectedName: string; + let triple: string; + switch (arch) { + case 'amd64': + expectedName = `x86_64-linux-gnu.tar.gz`; + triple = 'x86_64-linux-gnu'; + break; + case 'arm64': + expectedName = `aarch64-linux-gnu.tar.gz`; + triple = 'aarch64-linux-gnu'; + break; + case 'armhf': + expectedName = `arm-rpi-linux-gnueabihf.tar.gz`; + triple = 'arm-rpi-linux-gnueabihf'; + break; + } + const checksumSha256 = getVSCodeSysrootChecksum(expectedName); + if (!checksumSha256) { + throw new Error(`Could not find checksum for ${expectedName}`); + } + const sysroot = process.env['VSCODE_SYSROOT_DIR'] ?? path.join(tmpdir(), `vscode-${arch}-sysroot`); + const stamp = path.join(sysroot, '.stamp'); + const result = `${sysroot}/${triple}/${triple}/sysroot`; + if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === expectedName) { + return result; + } + console.log(`Installing ${arch} root image: ${sysroot}`); + fs.rmSync(sysroot, { recursive: true, force: true }); + fs.mkdirSync(sysroot); + await fetchUrl({ + checksumSha256, + assetName: expectedName, + dest: sysroot + }); + fs.writeFileSync(stamp, expectedName); + return result; +} + +export async function getChromiumSysroot(arch: DebianArchString): Promise { + const sysrootJSONUrl = `https://raw.githubusercontent.com/electron/electron/v${getElectronVersion().electronVersion}/script/sysroots.json`; const sysrootDictLocation = `${tmpdir()}/sysroots.json`; const result = spawnSync('curl', [sysrootJSONUrl, '-o', sysrootDictLocation]); if (result.status !== 0) { diff --git a/build/linux/dependencies-generator.js b/build/linux/dependencies-generator.js index e348741d827..e40ed70901c 100644 --- a/build/linux/dependencies-generator.js +++ b/build/linux/dependencies-generator.js @@ -7,12 +7,14 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getDependencies = void 0; const child_process_1 = require("child_process"); const path = require("path"); +const install_sysroot_1 = require("./debian/install-sysroot"); const calculate_deps_1 = require("./debian/calculate-deps"); const calculate_deps_2 = require("./rpm/calculate-deps"); const dep_lists_1 = require("./debian/dep-lists"); const dep_lists_2 = require("./rpm/dep-lists"); const types_1 = require("./debian/types"); const types_2 = require("./rpm/types"); +const product = require("../../product.json"); // A flag that can easily be toggled. // Make sure to compile the build directory after toggling the value. // If false, we warn about new dependencies if they show up @@ -31,14 +33,11 @@ const bundledDeps = [ 'libvk_swiftshader.so', 'libffmpeg.so' ]; -function getDependencies(packageType, buildDir, applicationName, arch, sysroot) { +async function getDependencies(packageType, buildDir, applicationName, arch) { if (packageType === 'deb') { if (!(0, types_1.isDebianArchString)(arch)) { throw new Error('Invalid Debian arch string ' + arch); } - if (!sysroot) { - throw new Error('Missing sysroot parameter'); - } } if (packageType === 'rpm' && !(0, types_2.isRpmArchString)(arch)) { throw new Error('Invalid RPM arch string ' + arch); @@ -51,16 +50,26 @@ function getDependencies(packageType, buildDir, applicationName, arch, sysroot) console.error(findResult.stderr.toString()); return []; } - const files = findResult.stdout.toString().trimEnd().split('\n'); const appPath = path.join(buildDir, applicationName); + // Add the native modules + const files = findResult.stdout.toString().trimEnd().split('\n'); + // Add the tunnel binary. + files.push(path.join(buildDir, 'bin', product.tunnelApplicationName)); + // Add the main executable. files.push(appPath); // Add chrome sandbox and crashpad handler. files.push(path.join(buildDir, 'chrome-sandbox')); files.push(path.join(buildDir, 'chrome_crashpad_handler')); // Generate the dependencies. - const dependencies = packageType === 'deb' ? - (0, calculate_deps_1.generatePackageDeps)(files, arch, sysroot) : - (0, calculate_deps_2.generatePackageDeps)(files); + let dependencies; + if (packageType === 'deb') { + const chromiumSysroot = await (0, install_sysroot_1.getChromiumSysroot)(arch); + const vscodeSysroot = await (0, install_sysroot_1.getVSCodeSysroot)(arch); + dependencies = (0, calculate_deps_1.generatePackageDeps)(files, arch, chromiumSysroot, vscodeSysroot); + } + else { + dependencies = (0, calculate_deps_2.generatePackageDeps)(files); + } // Merge all the dependencies. const mergedDependencies = mergePackageDeps(dependencies); // Exclude bundled dependencies and sort diff --git a/build/linux/dependencies-generator.ts b/build/linux/dependencies-generator.ts index b08762f6e2d..12bc3c08a64 100644 --- a/build/linux/dependencies-generator.ts +++ b/build/linux/dependencies-generator.ts @@ -7,12 +7,14 @@ import { spawnSync } from 'child_process'; import path = require('path'); +import { getChromiumSysroot, getVSCodeSysroot } from './debian/install-sysroot'; import { generatePackageDeps as generatePackageDepsDebian } from './debian/calculate-deps'; import { generatePackageDeps as generatePackageDepsRpm } from './rpm/calculate-deps'; import { referenceGeneratedDepsByArch as debianGeneratedDeps } from './debian/dep-lists'; import { referenceGeneratedDepsByArch as rpmGeneratedDeps } from './rpm/dep-lists'; import { DebianArchString, isDebianArchString } from './debian/types'; import { isRpmArchString, RpmArchString } from './rpm/types'; +import product = require('../../product.json'); // A flag that can easily be toggled. // Make sure to compile the build directory after toggling the value. @@ -34,14 +36,11 @@ const bundledDeps = [ 'libffmpeg.so' ]; -export function getDependencies(packageType: 'deb' | 'rpm', buildDir: string, applicationName: string, arch: string, sysroot?: string): string[] { +export async function getDependencies(packageType: 'deb' | 'rpm', buildDir: string, applicationName: string, arch: string): Promise { if (packageType === 'deb') { if (!isDebianArchString(arch)) { throw new Error('Invalid Debian arch string ' + arch); } - if (!sysroot) { - throw new Error('Missing sysroot parameter'); - } } if (packageType === 'rpm' && !isRpmArchString(arch)) { throw new Error('Invalid RPM arch string ' + arch); @@ -56,19 +55,26 @@ export function getDependencies(packageType: 'deb' | 'rpm', buildDir: string, ap return []; } - const files = findResult.stdout.toString().trimEnd().split('\n'); - const appPath = path.join(buildDir, applicationName); + // Add the native modules + const files = findResult.stdout.toString().trimEnd().split('\n'); + // Add the tunnel binary. + files.push(path.join(buildDir, 'bin', product.tunnelApplicationName)); + // Add the main executable. files.push(appPath); - // Add chrome sandbox and crashpad handler. files.push(path.join(buildDir, 'chrome-sandbox')); files.push(path.join(buildDir, 'chrome_crashpad_handler')); // Generate the dependencies. - const dependencies = packageType === 'deb' ? - generatePackageDepsDebian(files, arch as DebianArchString, sysroot!) : - generatePackageDepsRpm(files); + let dependencies: Set[]; + if (packageType === 'deb') { + const chromiumSysroot = await getChromiumSysroot(arch as DebianArchString); + const vscodeSysroot = await getVSCodeSysroot(arch as DebianArchString); + dependencies = generatePackageDepsDebian(files, arch as DebianArchString, chromiumSysroot, vscodeSysroot); + } else { + dependencies = generatePackageDepsRpm(files); + } // Merge all the dependencies. const mergedDependencies = mergePackageDeps(dependencies); diff --git a/build/linux/rpm/dep-lists.js b/build/linux/rpm/dep-lists.js index 38ba2f9aa77..e824f19c177 100644 --- a/build/linux/rpm/dep-lists.js +++ b/build/linux/rpm/dep-lists.js @@ -42,7 +42,11 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.15)(64bit)', 'libc.so.6(GLIBC_2.16)(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', + 'libc.so.6(GLIBC_2.18)(64bit)', 'libc.so.6(GLIBC_2.2.5)(64bit)', + 'libc.so.6(GLIBC_2.25)(64bit)', + 'libc.so.6(GLIBC_2.27)(64bit)', + 'libc.so.6(GLIBC_2.28)(64bit)', 'libc.so.6(GLIBC_2.3)(64bit)', 'libc.so.6(GLIBC_2.3.2)(64bit)', 'libc.so.6(GLIBC_2.3.3)(64bit)', @@ -63,6 +67,8 @@ exports.referenceGeneratedDepsByArch = { 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', + 'libgcc_s.so.1(GCC_3.3)(64bit)', + 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', @@ -107,6 +113,8 @@ exports.referenceGeneratedDepsByArch = { 'libxkbcommon.so.0()(64bit)', 'libxkbcommon.so.0(V_0.5.0)(64bit)', 'libxkbfile.so.1()(64bit)', + 'libz.so.1()(64bit)', + 'libz.so.1(ZLIB_1.2.3.4)(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' @@ -133,6 +141,10 @@ exports.referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.15)', 'libc.so.6(GLIBC_2.16)', 'libc.so.6(GLIBC_2.17)', + 'libc.so.6(GLIBC_2.18)', + 'libc.so.6(GLIBC_2.25)', + 'libc.so.6(GLIBC_2.27)', + 'libc.so.6(GLIBC_2.28)', 'libc.so.6(GLIBC_2.4)', 'libc.so.6(GLIBC_2.6)', 'libc.so.6(GLIBC_2.7)', @@ -150,6 +162,7 @@ exports.referenceGeneratedDepsByArch = { 'libgcc_s.so.1', 'libgcc_s.so.1(GCC_3.0)', 'libgcc_s.so.1(GCC_3.5)', + 'libgcc_s.so.1(GCC_4.3.0)', 'libgio-2.0.so.0', 'libglib-2.0.so.0', 'libgobject-2.0.so.0', @@ -232,6 +245,10 @@ exports.referenceGeneratedDepsByArch = { 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', + 'libc.so.6(GLIBC_2.18)(64bit)', + 'libc.so.6(GLIBC_2.25)(64bit)', + 'libc.so.6(GLIBC_2.27)(64bit)', + 'libc.so.6(GLIBC_2.28)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', @@ -243,6 +260,7 @@ exports.referenceGeneratedDepsByArch = { 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', + 'libgcc_s.so.1(GCC_3.3)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgcc_s.so.1(GCC_4.5.0)(64bit)', 'libgio-2.0.so.0()(64bit)', diff --git a/build/linux/rpm/dep-lists.ts b/build/linux/rpm/dep-lists.ts index 7dfa3013401..1c38df695db 100644 --- a/build/linux/rpm/dep-lists.ts +++ b/build/linux/rpm/dep-lists.ts @@ -41,7 +41,11 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.15)(64bit)', 'libc.so.6(GLIBC_2.16)(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', + 'libc.so.6(GLIBC_2.18)(64bit)', 'libc.so.6(GLIBC_2.2.5)(64bit)', + 'libc.so.6(GLIBC_2.25)(64bit)', + 'libc.so.6(GLIBC_2.27)(64bit)', + 'libc.so.6(GLIBC_2.28)(64bit)', 'libc.so.6(GLIBC_2.3)(64bit)', 'libc.so.6(GLIBC_2.3.2)(64bit)', 'libc.so.6(GLIBC_2.3.3)(64bit)', @@ -62,6 +66,8 @@ export const referenceGeneratedDepsByArch = { 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', + 'libgcc_s.so.1(GCC_3.3)(64bit)', + 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', @@ -106,6 +112,8 @@ export const referenceGeneratedDepsByArch = { 'libxkbcommon.so.0()(64bit)', 'libxkbcommon.so.0(V_0.5.0)(64bit)', 'libxkbfile.so.1()(64bit)', + 'libz.so.1()(64bit)', + 'libz.so.1(ZLIB_1.2.3.4)(64bit)', 'rpmlib(FileDigests) <= 4.6.0-1', 'rtld(GNU_HASH)', 'xdg-utils' @@ -132,6 +140,10 @@ export const referenceGeneratedDepsByArch = { 'libc.so.6(GLIBC_2.15)', 'libc.so.6(GLIBC_2.16)', 'libc.so.6(GLIBC_2.17)', + 'libc.so.6(GLIBC_2.18)', + 'libc.so.6(GLIBC_2.25)', + 'libc.so.6(GLIBC_2.27)', + 'libc.so.6(GLIBC_2.28)', 'libc.so.6(GLIBC_2.4)', 'libc.so.6(GLIBC_2.6)', 'libc.so.6(GLIBC_2.7)', @@ -149,6 +161,7 @@ export const referenceGeneratedDepsByArch = { 'libgcc_s.so.1', 'libgcc_s.so.1(GCC_3.0)', 'libgcc_s.so.1(GCC_3.5)', + 'libgcc_s.so.1(GCC_4.3.0)', 'libgio-2.0.so.0', 'libglib-2.0.so.0', 'libgobject-2.0.so.0', @@ -231,6 +244,10 @@ export const referenceGeneratedDepsByArch = { 'libatspi.so.0()(64bit)', 'libc.so.6()(64bit)', 'libc.so.6(GLIBC_2.17)(64bit)', + 'libc.so.6(GLIBC_2.18)(64bit)', + 'libc.so.6(GLIBC_2.25)(64bit)', + 'libc.so.6(GLIBC_2.27)(64bit)', + 'libc.so.6(GLIBC_2.28)(64bit)', 'libcairo.so.2()(64bit)', 'libcurl.so.4()(64bit)', 'libdbus-1.so.3()(64bit)', @@ -242,6 +259,7 @@ export const referenceGeneratedDepsByArch = { 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', + 'libgcc_s.so.1(GCC_3.3)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgcc_s.so.1(GCC_4.5.0)(64bit)', 'libgio-2.0.so.0()(64bit)', diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index 07b4412c458..cce0f460378 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -85,22 +85,27 @@ for (let dir of dirs) { continue; } + let opts; + if (dir === 'build') { + const env = { ...process.env }; setupBuildYarnrc(); - yarnInstall('build'); + opts = { env }; + if (process.env['CC']) { env['CC'] = 'gcc'; } + if (process.env['CXX']) { env['CXX'] = 'g++'; } + if (process.env['CXXFLAGS']) { env['CXXFLAGS'] = ''; } + if (process.env['LDFLAGS']) { env['LDFLAGS'] = ''; } + yarnInstall('build', opts); continue; } - let opts; - if (/^(.build\/distro\/npm\/)?remote$/.test(dir)) { // node modules used by vscode server const env = { ...process.env }; if (process.env['VSCODE_REMOTE_CC']) { env['CC'] = process.env['VSCODE_REMOTE_CC']; } if (process.env['VSCODE_REMOTE_CXX']) { env['CXX'] = process.env['VSCODE_REMOTE_CXX']; } - if (process.env['CXXFLAGS']) { delete env['CXXFLAGS']; } - if (process.env['CFLAGS']) { delete env['CFLAGS']; } - if (process.env['LDFLAGS']) { delete env['LDFLAGS']; } + if (process.env['VSCODE_REMOTE_CXXFLAGS']) { env['CXXFLAGS'] = process.env['VSCODE_REMOTE_CXXFLAGS']; } + if (process.env['VSCODE_REMOTE_LDFLAGS']) { env['LDFLAGS'] = process.env['VSCODE_REMOTE_LDFLAGS']; } if (process.env['VSCODE_REMOTE_NODE_GYP']) { env['npm_config_node_gyp'] = process.env['VSCODE_REMOTE_NODE_GYP']; } opts = { env }; diff --git a/build/yarn.lock b/build/yarn.lock index b79ad430a0e..c7d9bb3a37b 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -1721,7 +1721,7 @@ is-extendable@^1.0.1: is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-glob@^4.0.1: version "4.0.1" @@ -2201,7 +2201,7 @@ picomatch@^2.2.1: pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== pify@^3.0.0: version "3.0.0" @@ -2602,7 +2602,7 @@ through2@^4.0.2: through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== time-stamp@^1.0.0: version "1.1.0" From f29415ce2cc1118d62ae269c1349c08571a43a64 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 12 Dec 2023 11:43:03 +0100 Subject: [PATCH 46/80] editors - do not prevent group locking anymore when only 1 group opened (#200610) * editors - do not prevent group locking anymore when only 1 group opened * . --- .../parts/editor/editor.contribution.ts | 4 ++-- .../browser/parts/editor/editorCommands.ts | 5 ++--- .../browser/parts/editor/editorGroupView.ts | 22 +++---------------- .../browser/parts/editor/editorParts.ts | 15 ++----------- .../test/browser/editorGroupsService.test.ts | 8 +++---- 5 files changed, 13 insertions(+), 41 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index 213f338e769..146e91e1b59 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -353,7 +353,7 @@ MenuRegistry.appendMenuItem(MenuId.EmptyEditorGroupContext, { command: { id: SPL MenuRegistry.appendMenuItem(MenuId.EmptyEditorGroupContext, { command: { id: SPLIT_EDITOR_LEFT, title: localize('splitLeft', "Split Left") }, group: '2_split', order: 30 }); MenuRegistry.appendMenuItem(MenuId.EmptyEditorGroupContext, { command: { id: SPLIT_EDITOR_RIGHT, title: localize('splitRight', "Split Right") }, group: '2_split', order: 40 }); MenuRegistry.appendMenuItem(MenuId.EmptyEditorGroupContext, { command: { id: NEW_EMPTY_EDITOR_WINDOW_COMMAND_ID, title: localize('newWindow', "New Window") }, group: '3_window', order: 10 }); -MenuRegistry.appendMenuItem(MenuId.EmptyEditorGroupContext, { command: { id: TOGGLE_LOCK_GROUP_COMMAND_ID, title: localize('toggleLockGroup', "Lock Group"), toggled: ActiveEditorGroupLockedContext }, group: '4_lock', order: 10, when: ContextKeyExpr.and(MultipleEditorGroupsContext, IsAuxiliaryEditorPartContext.toNegated()) }); +MenuRegistry.appendMenuItem(MenuId.EmptyEditorGroupContext, { command: { id: TOGGLE_LOCK_GROUP_COMMAND_ID, title: localize('toggleLockGroup', "Lock Group"), toggled: ActiveEditorGroupLockedContext }, group: '4_lock', order: 10, when: IsAuxiliaryEditorPartContext.toNegated() /* already a primary action for aux windows */ }); MenuRegistry.appendMenuItem(MenuId.EmptyEditorGroupContext, { command: { id: CLOSE_EDITOR_GROUP_COMMAND_ID, title: localize('close', "Close") }, group: '5_close', order: 10, when: MultipleEditorGroupsContext }); // Editor Tab Container Context Menu @@ -407,7 +407,7 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: CLOSE_SAVED_EDI MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: TOGGLE_KEEP_EDITORS_COMMAND_ID, title: localize('togglePreviewMode', "Enable Preview Editors"), toggled: ContextKeyExpr.has('config.workbench.editor.enablePreview') }, group: '7_settings', order: 10 }); MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: TOGGLE_MAXIMIZE_EDITOR_GROUP, title: localize('maximizeGroup', "Maximize Group") }, group: '8_group_operations', order: 5, when: ContextKeyExpr.and(EditorPartMaximizedEditorGroupContext.negate(), EditorPartMultipleEditorGroupsContext) }); MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: TOGGLE_MAXIMIZE_EDITOR_GROUP, title: localize('unmaximizeGroup', "Unmaximize Group") }, group: '8_group_operations', order: 5, when: EditorPartMaximizedEditorGroupContext }); -MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: TOGGLE_LOCK_GROUP_COMMAND_ID, title: localize('lockGroup', "Lock Group"), toggled: ActiveEditorGroupLockedContext }, group: '8_group_operations', order: 10, when: ContextKeyExpr.and(MultipleEditorGroupsContext, IsAuxiliaryEditorPartContext.toNegated()) }); +MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: TOGGLE_LOCK_GROUP_COMMAND_ID, title: localize('lockGroup', "Lock Group"), toggled: ActiveEditorGroupLockedContext }, group: '8_group_operations', order: 10, when: IsAuxiliaryEditorPartContext.toNegated() /* already a primary action for aux windows */ }); function appendEditorToolItem(primary: ICommandAction, when: ContextKeyExpression | undefined, order: number, alternative?: ICommandAction, precondition?: ContextKeyExpression | undefined): void { const item: IMenuItem = { diff --git a/src/vs/workbench/browser/parts/editor/editorCommands.ts b/src/vs/workbench/browser/parts/editor/editorCommands.ts index 6b5010a536b..19e63fbccfd 100644 --- a/src/vs/workbench/browser/parts/editor/editorCommands.ts +++ b/src/vs/workbench/browser/parts/editor/editorCommands.ts @@ -1435,7 +1435,6 @@ function registerOtherEditorCommands(): void { id: TOGGLE_LOCK_GROUP_COMMAND_ID, title: { value: localize('toggleEditorGroupLock', "Toggle Editor Group Lock"), original: 'Toggle Editor Group Lock' }, category: Categories.View, - precondition: MultipleEditorGroupsContext, f1: true }); } @@ -1450,7 +1449,7 @@ function registerOtherEditorCommands(): void { id: LOCK_GROUP_COMMAND_ID, title: { value: localize('lockEditorGroup', "Lock Editor Group"), original: 'Lock Editor Group' }, category: Categories.View, - precondition: ContextKeyExpr.and(MultipleEditorGroupsContext, ActiveEditorGroupLockedContext.toNegated()), + precondition: ActiveEditorGroupLockedContext.toNegated(), f1: true }); } @@ -1464,7 +1463,7 @@ function registerOtherEditorCommands(): void { super({ id: UNLOCK_GROUP_COMMAND_ID, title: { value: localize('unlockEditorGroup', "Unlock Editor Group"), original: 'Unlock Editor Group' }, - precondition: ContextKeyExpr.and(MultipleEditorGroupsContext, ActiveEditorGroupLockedContext), + precondition: ActiveEditorGroupLockedContext, category: Categories.View, f1: true }); diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 6f60d8f8134..3aa8ff4bd58 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -1083,9 +1083,9 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Conditionally lock the group if ( - isNew && // only if this editor was new for the group - this.count === 1 && // only when this editor was the first editor in the group - this.canLock() // only when we met the requirements to lock + isNew && // only if this editor was new for the group + this.count === 1 && // only when this editor was the first editor in the group + this.editorPartsView.groups.length > 1 // only allow auto locking if more than 1 group is opened ) { // only when the editor identifier is configured as such if (openedEditor.editorId && this.groupsView.partOptions.autoLockGroups?.has(openedEditor.editorId)) { @@ -1884,29 +1884,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView { //#region Locking get isLocked(): boolean { - if (!this.canLock()) { - // Special case: if only 1 group is opened, never report it as locked - // to ensure editors can always open in the "default" editor group - return false; - } - return this.model.isLocked; } lock(locked: boolean): void { - if (!this.canLock()) { - // Special case: if only 1 group is opened, never allow to lock - // to ensure editors can always open in the "default" editor group - locked = false; - } - this.model.lock(locked); } - private canLock(): boolean { - return this.editorPartsView.groups.length > 1; // only allow locking if more than 1 group is opened - } - //#endregion //#region Editor Actions diff --git a/src/vs/workbench/browser/parts/editor/editorParts.ts b/src/vs/workbench/browser/parts/editor/editorParts.ts index deb9c9aedfa..155d6d153d2 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, firstOrDefault } from 'vs/base/common/arrays'; +import { distinct } 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.handleOnDidRemoveGroup(group))); + disposables.add(part.onDidRemoveGroup(group => this._onDidRemoveGroup.fire(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,17 +103,6 @@ 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); diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index b95fe353242..7c27b129fab 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -1701,12 +1701,12 @@ suite('EditorGroupsService', () => { rightGroupListener.dispose(); }); - test('locked groups - single group is never locked', async () => { + test('locked groups - single group is can be locked', async () => { const [part] = await createPart(); const group = part.activeGroup; group.lock(true); - assert.strictEqual(group.isLocked, false); + assert.strictEqual(group.isLocked, true); const rightGroup = part.addGroup(group, GroupDirection.RIGHT); rightGroup.lock(true); @@ -1714,7 +1714,7 @@ suite('EditorGroupsService', () => { assert.strictEqual(rightGroup.isLocked, true); part.removeGroup(group); - assert.strictEqual(rightGroup.isLocked, false); + assert.strictEqual(rightGroup.isLocked, true); const rightGroup2 = part.addGroup(rightGroup, GroupDirection.RIGHT); rightGroup.lock(true); @@ -1725,7 +1725,7 @@ suite('EditorGroupsService', () => { part.removeGroup(rightGroup2); - assert.strictEqual(rightGroup.isLocked, false); + assert.strictEqual(rightGroup.isLocked, true); }); test('locked groups - auto locking via setting', async () => { From 1d10285782d7c2c1996f9c5d5d9e0ca4605b93b2 Mon Sep 17 00:00:00 2001 From: isidor Date: Tue, 12 Dec 2023 11:44:20 +0100 Subject: [PATCH 47/80] Update distro version in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 301a948ff01..4ab6051a9c3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.86.0", - "distro": "1a07d32cc58bafa5dc4cf8cfa8f044b3789e285c", + "distro": "536a5224f3131ed95718b23b3f82d75485d89721", "author": { "name": "Microsoft Corporation" }, From d8285a178904af549d33ec193badad7b055d05bd Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:47:06 +0100 Subject: [PATCH 48/80] Benibenj/removeUnusedContextKeys (#200618) * Remove unused context keys * :lipstick: --- .../workbench/browser/parts/editor/editorGroupView.ts | 10 +--------- src/vs/workbench/common/contextkeys.ts | 1 - 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 3aa8ff4bd58..654c23c6024 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -6,7 +6,7 @@ import 'vs/css!./media/editorgroupview'; import { EditorGroupModel, IEditorOpenOptions, IGroupModelChangeEvent, ISerializedEditorGroupModel, isGroupEditorCloseEvent, isGroupEditorOpenEvent, isSerializedEditorGroupModel } from 'vs/workbench/common/editor/editorGroupModel'; import { GroupIdentifier, CloseDirection, IEditorCloseEvent, IEditorPane, SaveReason, IEditorPartOptionsChangeEvent, EditorsOrder, IVisibleEditorPane, EditorResourceAccessor, EditorInputCapabilities, IUntypedEditorInput, DEFAULT_EDITOR_ASSOCIATION, SideBySideEditor, EditorCloseContext, IEditorWillMoveEvent, IEditorWillOpenEvent, IMatchEditorOptions, GroupModelChangeKind, IActiveEditorChangeEvent, IFindEditorOptions, IToolbarActions } from 'vs/workbench/common/editor'; -import { ActiveEditorGroupLockedContext, ActiveEditorDirtyContext, EditorGroupEditorsCountContext, ActiveEditorStickyContext, ActiveEditorPinnedContext, ActiveEditorLastInGroupContext, ActiveEditorFirstInGroupContext, EditorPinnedAndUnpinnedTabsContext, ResourceContextKey, applyAvailableEditorIds, ActiveEditorAvailableEditorIdsContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext } from 'vs/workbench/common/contextkeys'; +import { ActiveEditorGroupLockedContext, ActiveEditorDirtyContext, EditorGroupEditorsCountContext, ActiveEditorStickyContext, ActiveEditorPinnedContext, ActiveEditorLastInGroupContext, ActiveEditorFirstInGroupContext, ResourceContextKey, applyAvailableEditorIds, ActiveEditorAvailableEditorIdsContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext } from 'vs/workbench/common/contextkeys'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput'; import { Emitter, Relay } from 'vs/base/common/event'; @@ -249,7 +249,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { const groupActiveEditorStickyContext = ActiveEditorStickyContext.bindTo(this.scopedContextKeyService); const groupEditorsCountContext = EditorGroupEditorsCountContext.bindTo(this.scopedContextKeyService); const groupLockedContext = ActiveEditorGroupLockedContext.bindTo(this.scopedContextKeyService); - const groupHasPinnedAndUnpinnedContext = EditorPinnedAndUnpinnedTabsContext.bindTo(this.scopedContextKeyService); const groupActiveEditorAvailableEditorIds = ActiveEditorAvailableEditorIdsContext.bindTo(this.scopedContextKeyService); const groupActiveEditorCanSplitInGroupContext = ActiveEditorCanSplitInGroupContext.bindTo(this.scopedContextKeyService); @@ -289,7 +288,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { break; case GroupModelChangeKind.EDITOR_CLOSE: case GroupModelChangeKind.EDITOR_OPEN: - groupHasPinnedAndUnpinnedContext.set(this.hasPinnedAndUnpinnedEditors()); case GroupModelChangeKind.EDITOR_ACTIVE: case GroupModelChangeKind.EDITOR_MOVE: groupActiveEditorFirstContext.set(this.model.isFirst(this.model.activeEditor)); @@ -304,7 +302,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { if (e.editor && e.editor === this.model.activeEditor) { groupActiveEditorStickyContext.set(this.model.isSticky(this.model.activeEditor)); } - groupHasPinnedAndUnpinnedContext.set(this.hasPinnedAndUnpinnedEditors()); break; } @@ -320,11 +317,6 @@ export class EditorGroupView extends Themable implements IEditorGroupView { // Update context keys on startup observeActiveEditor(); - groupHasPinnedAndUnpinnedContext.set(this.hasPinnedAndUnpinnedEditors()); - } - - private hasPinnedAndUnpinnedEditors(): boolean { - return this.model.stickyCount > 0 && this.model.stickyCount < this.model.count; } private registerContainerListeners(): void { diff --git a/src/vs/workbench/common/contextkeys.ts b/src/vs/workbench/common/contextkeys.ts index 09e6794bb32..fc4a59cb05e 100644 --- a/src/vs/workbench/common/contextkeys.ts +++ b/src/vs/workbench/common/contextkeys.ts @@ -86,7 +86,6 @@ export const IsCenteredLayoutContext = new RawContextKey('isCenteredLay export const SplitEditorsVertically = new RawContextKey('splitEditorsVertically', false, localize('splitEditorsVertically', "Whether editors split vertically")); export const MainEditorAreaVisibleContext = new RawContextKey('mainEditorAreaVisible', true, localize('mainEditorAreaVisible', "Whether the editor area in the main window is visible")); export const EditorTabsVisibleContext = new RawContextKey('editorTabsVisible', true, localize('editorTabsVisible', "Whether editor tabs are visible")); -export const EditorPinnedAndUnpinnedTabsContext = new RawContextKey('editorPinnedAndUnpinnedTabsVisible', false, true); //#endregion From 5d865611780887151f4d0ef1004eb4206ad8d4bf Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:34:55 +0100 Subject: [PATCH 49/80] some context keys do not updated on active editor change (#200624) context keys not updated on active editor change --- src/vs/workbench/browser/parts/editor/editorGroupView.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 654c23c6024..8859b6050a0 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -286,9 +286,14 @@ export class EditorGroupView extends Themable implements IEditorGroupView { case GroupModelChangeKind.GROUP_LOCKED: groupLockedContext.set(this.isLocked); break; + case GroupModelChangeKind.EDITOR_ACTIVE: + groupActiveEditorFirstContext.set(this.model.isFirst(this.model.activeEditor)); + groupActiveEditorLastContext.set(this.model.isLast(this.model.activeEditor)); + groupActiveEditorPinnedContext.set(this.model.activeEditor ? this.model.isPinned(this.model.activeEditor) : false); + groupActiveEditorStickyContext.set(this.model.activeEditor ? this.model.isSticky(this.model.activeEditor) : false); + break; case GroupModelChangeKind.EDITOR_CLOSE: case GroupModelChangeKind.EDITOR_OPEN: - case GroupModelChangeKind.EDITOR_ACTIVE: case GroupModelChangeKind.EDITOR_MOVE: groupActiveEditorFirstContext.set(this.model.isFirst(this.model.activeEditor)); groupActiveEditorLastContext.set(this.model.isLast(this.model.activeEditor)); From 91a4378f47544a3eedb0bba8f7d6e7cb7c08e633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Tue, 12 Dec 2023 12:49:40 +0100 Subject: [PATCH 50/80] allow CORS from PRSS CDN (#200554) fixes microsoft/vscode-remote-release#9246 --- src/vs/code/electron-main/app.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 42e165b8517..641ee04aa63 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -301,6 +301,24 @@ export class CodeApplication extends Disposable { //#endregion + //#region Allow CORS for the PRSS CDN + + // https://github.com/microsoft/vscode-remote-release/issues/9246 + session.defaultSession.webRequest.onHeadersReceived((details, callback) => { + if (details.url.startsWith('https://vscode.download.prss.microsoft.com/')) { + const responseHeaders = details.responseHeaders ?? Object.create(null); + + if (responseHeaders['Access-Control-Allow-Origin'] === undefined) { + responseHeaders['Access-Control-Allow-Origin'] = ['*']; + return callback({ cancel: false, responseHeaders }); + } + } + + return callback({ cancel: false }); + }); + + //#endregion + //#region Code Cache type SessionWithCodeCachePathSupport = Session & { From 039dacca94807b92e37bfe0a454be5cb8f0e49ab Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Dec 2023 04:17:04 -0800 Subject: [PATCH 51/80] Fix 3 terminal panel action toggles Fixes #200510 --- src/vs/workbench/contrib/terminal/browser/terminalMenus.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts index ec8f6651b75..5be6c8bc726 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalMenus.ts @@ -515,7 +515,7 @@ export function setupTerminalMenus(): void { title: localize('workbench.action.terminal.clearLong', "Clear Terminal"), icon: Codicon.clearAll }, - group: 'execute', + group: 'navigation', order: 4, when: ContextKeyExpr.equals('view', TERMINAL_VIEW_ID), isHiddenByDefault: true @@ -529,7 +529,7 @@ export function setupTerminalMenus(): void { title: localize('workbench.action.terminal.runActiveFile', "Run Active File"), icon: Codicon.run }, - group: 'execute', + group: 'navigation', order: 5, when: ContextKeyExpr.equals('view', TERMINAL_VIEW_ID), isHiddenByDefault: true @@ -543,7 +543,7 @@ export function setupTerminalMenus(): void { title: localize('workbench.action.terminal.runSelectedText', "Run Selected Text"), icon: Codicon.selection }, - group: 'execute', + group: 'navigation', order: 6, when: ContextKeyExpr.equals('view', TERMINAL_VIEW_ID), isHiddenByDefault: true From 45a10538c4c558a7b5accf37a8d79a609c17177f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Dec 2023 13:21:33 +0100 Subject: [PATCH 52/80] fix https://github.com/microsoft/vscode/issues/200631 (#200632) --- .../contrib/suggest/browser/suggestWidget.ts | 3 +++ .../suggest/browser/suggestWidgetRenderer.ts | 16 +++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index e8642e9a6a4..fc41e265fc4 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -282,6 +282,9 @@ export class SuggestWidget implements IDisposable { applyStatusBarStyle(); applyIconStyle(); } + if (this._completionModel && (e.hasChanged(EditorOption.fontInfo) || e.hasChanged(EditorOption.suggestFontSize) || e.hasChanged(EditorOption.suggestLineHeight))) { + this._list.splice(0, this._list.length, this._completionModel.items); + } })); this._ctxSuggestWidgetVisible = SuggestContext.Visible.bindTo(_contextKeyService); diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts b/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts index 431f3b4964f..75c44777e22 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidgetRenderer.ts @@ -85,6 +85,8 @@ export interface ISuggestionTemplateData { readonly detailsLabel: HTMLElement; readonly readMore: HTMLElement; readonly disposables: DisposableStore; + + readonly configureFont: () => void; } export class ItemRenderer implements IListRenderer { @@ -156,18 +158,14 @@ export class ItemRenderer implements IListRenderer { - if (e.hasChanged(EditorOption.fontInfo) || e.hasChanged(EditorOption.suggestFontSize) || e.hasChanged(EditorOption.suggestLineHeight)) { - configureFont(); - } - })); - - return { root, left, right, icon, colorspan, iconLabel, iconContainer, parametersLabel, qualifierLabel, detailsLabel, readMore, disposables }; + return { root, left, right, icon, colorspan, iconLabel, iconContainer, parametersLabel, qualifierLabel, detailsLabel, readMore, disposables, configureFont }; } renderElement(element: CompletionItem, index: number, data: ISuggestionTemplateData): void { + + + data.configureFont(); + const { completion } = element; data.root.id = getAriaId(index); data.colorspan.style.backgroundColor = ''; From 1d952ed6e7537b3d8d44500ff6e05e9973d09c44 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Dec 2023 05:07:47 -0800 Subject: [PATCH 53/80] Terminal mouse wheel zoom Fixes #76381 --- src/vs/platform/terminal/common/terminal.ts | 1 + .../terminal/common/terminalConfiguration.ts | 9 +- .../contrib/terminal/terminal.all.ts | 1 + .../terminal.mouseWheelZoom.contribution.ts | 121 ++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 91a28ae57e0..37a2af309ae 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -120,6 +120,7 @@ export const enum TerminalSettingId { AccessibleViewFocusOnCommandExecution = 'terminal.integrated.accessibleViewFocusOnCommandExecution', StickyScrollEnabled = 'terminal.integrated.stickyScroll.enabled', StickyScrollMaxLineCount = 'terminal.integrated.stickyScroll.maxLineCount', + MouseWheelZoom = 'terminal.integrated.mouseWheelZoom', // Debug settings that are hidden from user diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 26a9d0bc58c..8913ae57c39 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -643,7 +643,14 @@ const terminalConfiguration: IConfigurationNode = { default: 5, minimum: 1, maximum: 10 - } + }, + [TerminalSettingId.MouseWheelZoom]: { + markdownDescription: isMacintosh + ? localize('terminal.integrated.mouseWheelZoom.mac', "Zoom the font of the editor when using mouse wheel and holding `Cmd`.") + : localize('terminal.integrated.mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`."), + type: 'boolean', + default: false + }, } }; diff --git a/src/vs/workbench/contrib/terminal/terminal.all.ts b/src/vs/workbench/contrib/terminal/terminal.all.ts index 81d48baad1f..5484ab7adeb 100644 --- a/src/vs/workbench/contrib/terminal/terminal.all.ts +++ b/src/vs/workbench/contrib/terminal/terminal.all.ts @@ -19,6 +19,7 @@ import 'vs/workbench/contrib/terminalContrib/environmentChanges/browser/terminal import 'vs/workbench/contrib/terminalContrib/find/browser/terminal.find.contribution'; import 'vs/workbench/contrib/terminalContrib/highlight/browser/terminal.highlight.contribution'; import 'vs/workbench/contrib/terminalContrib/links/browser/terminal.links.contribution'; +import 'vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution'; import 'vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminal.stickyScroll.contribution'; import 'vs/workbench/contrib/terminalContrib/quickFix/browser/terminal.quickFix.contribution'; import 'vs/workbench/contrib/terminalContrib/typeAhead/browser/terminal.typeAhead.contribution'; diff --git a/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts b/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts new file mode 100644 index 00000000000..7c574c18841 --- /dev/null +++ b/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts @@ -0,0 +1,121 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; +import { Event } from 'vs/base/common/event'; +import { EventType, addDisposableListener } from 'vs/base/browser/dom'; +import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; +import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { isMacintosh } from 'vs/base/common/platform'; +import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { IDetachedTerminalInstance, ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { registerTerminalContribution } from 'vs/workbench/contrib/terminal/browser/terminalExtensions'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ITerminalProcessInfo, ITerminalProcessManager } from 'vs/workbench/contrib/terminal/common/terminal'; +import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; + +class TerminalMouseWheelZoomContribution extends Disposable implements ITerminalContribution { + static readonly ID = 'terminal.find'; + + /** + * Currently focused find widget. This is used to track action context since + * 'active terminals' are only tracked for non-detached terminal instanecs. + */ + static activeFindWidget?: TerminalMouseWheelZoomContribution; + + static get(instance: ITerminalInstance | IDetachedTerminalInstance): TerminalMouseWheelZoomContribution | null { + return instance.getContribution(TerminalMouseWheelZoomContribution.ID); + } + + private _listener = this._register(new MutableDisposable()); + + constructor( + instance: ITerminalInstance | IDetachedTerminalInstance, + processManager: ITerminalProcessManager | ITerminalProcessInfo, + widgetManager: TerminalWidgetManager, + @IConfigurationService private readonly _configurationService: IConfigurationService, + ) { + super(); + } + + xtermReady(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { + this._register(Event.runAndSubscribe(this._configurationService.onDidChangeConfiguration, e => { + if (!e || e.affectsConfiguration(TerminalSettingId.MouseWheelZoom)) { + if (!!this._configurationService.getValue(TerminalSettingId.MouseWheelZoom)) { + this._setupMouseWheelZoomListener(xterm.raw); + } else { + this._listener.clear(); + } + } + })); + } + + private _getConfigFontSize(): number { + return this._configurationService.getValue(TerminalSettingId.FontSize); + } + + private _setupMouseWheelZoomListener(raw: RawXtermTerminal) { + // This is essentially a copy of what we do in the editor, just we modify font size directly + // as there is no separate zoom level concept in the terminal + const classifier = MouseWheelClassifier.INSTANCE; + + let prevMouseWheelTime = 0; + let gestureStartFontSize = this._getConfigFontSize(); + let gestureHasZoomModifiers = false; + let gestureAccumulatedDelta = 0; + + this._listener.value = addDisposableListener(raw.element!, EventType.MOUSE_WHEEL, (browserEvent: IMouseWheelEvent) => { + if (classifier.isPhysicalMouseWheel()) { + if (hasMouseWheelZoomModifiers(browserEvent)) { + const delta = browserEvent.deltaY > 0 ? -1 : 1; + console.log('delta', delta); + this._configurationService.updateValue(TerminalSettingId.FontSize, this._getConfigFontSize() + delta); + // EditorZoom.setZoomLevel(zoomLevel + delta); + browserEvent.preventDefault(); + browserEvent.stopPropagation(); + } + } else { + // we consider mousewheel events that occur within 50ms of each other to be part of the same gesture + // we don't want to consider mouse wheel events where ctrl/cmd is pressed during the inertia phase + // we also want to accumulate deltaY values from the same gesture and use that to set the zoom level + if (Date.now() - prevMouseWheelTime > 50) { + // reset if more than 50ms have passed + gestureStartFontSize = this._getConfigFontSize(); + gestureHasZoomModifiers = hasMouseWheelZoomModifiers(browserEvent); + gestureAccumulatedDelta = 0; + } + + prevMouseWheelTime = Date.now(); + gestureAccumulatedDelta += browserEvent.deltaY; + + if (gestureHasZoomModifiers) { + + console.log('set', gestureStartFontSize + gestureAccumulatedDelta / 5); + + const deltaAbs = Math.ceil(Math.abs(gestureAccumulatedDelta / 5)); + const deltaDirection = gestureAccumulatedDelta > 0 ? -1 : 1; + const delta = deltaAbs * deltaDirection; + this._configurationService.updateValue(TerminalSettingId.FontSize, gestureStartFontSize + delta); + gestureAccumulatedDelta += browserEvent.deltaY; + browserEvent.preventDefault(); + browserEvent.stopPropagation(); + } + } + }, { passive: false }); + } +} + +registerTerminalContribution(TerminalMouseWheelZoomContribution.ID, TerminalMouseWheelZoomContribution, true); + +function hasMouseWheelZoomModifiers(browserEvent: IMouseWheelEvent): boolean { + return ( + isMacintosh + // on macOS we support cmd + two fingers scroll (`metaKey` set) + // and also the two fingers pinch gesture (`ctrKey` set) + ? ((browserEvent.metaKey || browserEvent.ctrlKey) && !browserEvent.shiftKey && !browserEvent.altKey) + : (browserEvent.ctrlKey && !browserEvent.metaKey && !browserEvent.shiftKey && !browserEvent.altKey) + ); +} From 32bf697587a8500c211182d91bd79dd865f0bb74 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Dec 2023 05:45:30 -0800 Subject: [PATCH 54/80] Update xterm, adopt wheel event handler --- package.json | 16 ++--- remote/package.json | 16 ++--- remote/web/package.json | 14 ++-- remote/web/yarn.lock | 56 ++++++++-------- remote/yarn.lock | 64 +++++++++---------- .../terminal.mouseWheelZoom.contribution.ts | 12 ++-- yarn.lock | 64 +++++++++---------- 7 files changed, 123 insertions(+), 119 deletions(-) diff --git a/package.json b/package.json index 4ab6051a9c3..f81cebc2e64 100644 --- a/package.json +++ b/package.json @@ -80,14 +80,14 @@ "@vscode/windows-mutex": "^0.4.4", "@vscode/windows-process-tree": "^0.5.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-canvas": "0.6.0-beta.15", - "@xterm/addon-image": "0.7.0-beta.13", - "@xterm/addon-search": "0.14.0-beta.15", - "@xterm/addon-serialize": "0.12.0-beta.15", - "@xterm/addon-unicode11": "0.7.0-beta.15", - "@xterm/addon-webgl": "0.17.0-beta.15", - "@xterm/headless": "5.4.0-beta.15", - "@xterm/xterm": "5.4.0-beta.15", + "@xterm/addon-canvas": "0.6.0-beta.16", + "@xterm/addon-image": "0.7.0-beta.14", + "@xterm/addon-search": "0.14.0-beta.16", + "@xterm/addon-serialize": "0.12.0-beta.16", + "@xterm/addon-unicode11": "0.7.0-beta.16", + "@xterm/addon-webgl": "0.17.0-beta.16", + "@xterm/headless": "5.4.0-beta.16", + "@xterm/xterm": "5.4.0-beta.16", "graceful-fs": "4.2.11", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", diff --git a/remote/package.json b/remote/package.json index 7ad2a056aca..bd4af31cee3 100644 --- a/remote/package.json +++ b/remote/package.json @@ -13,14 +13,14 @@ "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.5.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-canvas": "0.6.0-beta.15", - "@xterm/addon-image": "0.7.0-beta.13", - "@xterm/addon-search": "0.14.0-beta.15", - "@xterm/addon-serialize": "0.12.0-beta.15", - "@xterm/addon-unicode11": "0.7.0-beta.15", - "@xterm/addon-webgl": "0.17.0-beta.15", - "@xterm/headless": "5.4.0-beta.15", - "@xterm/xterm": "5.4.0-beta.15", + "@xterm/addon-canvas": "0.6.0-beta.16", + "@xterm/addon-image": "0.7.0-beta.14", + "@xterm/addon-search": "0.14.0-beta.16", + "@xterm/addon-serialize": "0.12.0-beta.16", + "@xterm/addon-unicode11": "0.7.0-beta.16", + "@xterm/addon-webgl": "0.17.0-beta.16", + "@xterm/headless": "5.4.0-beta.16", + "@xterm/xterm": "5.4.0-beta.16", "cookie": "^0.4.0", "graceful-fs": "4.2.11", "http-proxy-agent": "^7.0.0", diff --git a/remote/web/package.json b/remote/web/package.json index af8dbf3de8d..b8c60f5b9c9 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -7,13 +7,13 @@ "@microsoft/1ds-post-js": "^3.2.13", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/vscode-languagedetection": "1.0.21", - "@xterm/addon-canvas": "0.6.0-beta.15", - "@xterm/addon-image": "0.7.0-beta.13", - "@xterm/addon-search": "0.14.0-beta.15", - "@xterm/addon-serialize": "0.12.0-beta.15", - "@xterm/addon-unicode11": "0.7.0-beta.15", - "@xterm/addon-webgl": "0.17.0-beta.15", - "@xterm/xterm": "5.4.0-beta.15", + "@xterm/addon-canvas": "0.6.0-beta.16", + "@xterm/addon-image": "0.7.0-beta.14", + "@xterm/addon-search": "0.14.0-beta.16", + "@xterm/addon-serialize": "0.12.0-beta.16", + "@xterm/addon-unicode11": "0.7.0-beta.16", + "@xterm/addon-webgl": "0.17.0-beta.16", + "@xterm/xterm": "5.4.0-beta.16", "jschardet": "3.0.0", "tas-client-umd": "0.1.8", "vscode-oniguruma": "1.7.0", diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index c2a90e562ae..dcc351a36dc 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -48,40 +48,40 @@ resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.21.tgz#89b48f293f6aa3341bb888c1118d16ff13b032d3" integrity sha512-zSUH9HYCw5qsCtd7b31yqkpaCU6jhtkKLkvOOA8yTrIRfBSOFb8PPhgmMicD7B/m+t4PwOJXzU1XDtrM9Fd3/g== -"@xterm/addon-canvas@0.6.0-beta.15": - version "0.6.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-canvas/-/addon-canvas-0.6.0-beta.15.tgz#ac800c3e8a1a26eeb0f76e36dabc342a840a1e0b" - integrity sha512-P5E+ywLTGG+Ii48Q3TZyK6aOzkYnoghJnUiyCb67g7zva3nDjw8Q4kKMlOrvZl6RHsLkSBwwLjOvUvg1nNOusg== +"@xterm/addon-canvas@0.6.0-beta.16": + version "0.6.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-canvas/-/addon-canvas-0.6.0-beta.16.tgz#d22ba7f1b211882215c5206ca07ce177378a898f" + integrity sha512-o89xcm0Tqy1ksEYMq3EIqxJNDUWJBaS9QUggc7i5vKUL2unw9TMa5IiiNzc3CsBOlBQDlITwEXoHDEbOMxoZPQ== -"@xterm/addon-image@0.7.0-beta.13": - version "0.7.0-beta.13" - resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.7.0-beta.13.tgz#bb854ecc3c2c9363804ca5c2d386e4298ffff425" - integrity sha512-q57H1ONHJ5e14XEN0MsjnvB3MdlsyVVjwAJfjWjESJFZT2e2qxyc2kflvXcTiBkLC4RCfnYchvU6PjgHJll3jw== +"@xterm/addon-image@0.7.0-beta.14": + version "0.7.0-beta.14" + resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.7.0-beta.14.tgz#39b123dd0a0390766aff631cf43cb2e51b3b2174" + integrity sha512-oCOIupROzkb5p2vZarY6HrX74OqvtbmjnkC6uuGEJXQ75XL2CX+uTUl2DlgeSTvvR0S8ZVB3hQlp4hrtoNNelA== -"@xterm/addon-search@0.14.0-beta.15": - version "0.14.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.14.0-beta.15.tgz#48ed3f0899cdfe3310058aa46dc03b7e40269742" - integrity sha512-HFiyJgHD8wnhYZLF3Dy5J4dWMhpCp6WR1IEoT3PchV3c6s52Sc8GCL/eJtequ8Rai5b7x/o0gNxBLzDL5dODnA== +"@xterm/addon-search@0.14.0-beta.16": + version "0.14.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.14.0-beta.16.tgz#5fa21d2b993970e8ced1e0ada3dcca5f7581c314" + integrity sha512-e6l5jCJIULQ6nzRcc0gp9obZsqd76qubAr0HZF6Ebxf3KOGRz4UX6g+kgt6RB1liWgG94WD8vI1rGB1z5bMSEg== -"@xterm/addon-serialize@0.12.0-beta.15": - version "0.12.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.12.0-beta.15.tgz#ca69f732490ae4512c312c4c0edf239d575390d0" - integrity sha512-SREdfJZ2eafeg846mYM8akjgezc+b+hN/a+UkvI/IOStE4kJXwNWQXSGPfmn+9UNzRxTYUEmjT+nbadE9M+9yg== +"@xterm/addon-serialize@0.12.0-beta.16": + version "0.12.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.12.0-beta.16.tgz#68c4d68dba7ff17a231650cc0d07dcc77721877b" + integrity sha512-F6ngtvTC5VDLn585uJro7V1xjM43TbjPQjQ6Fn0Uic3+dsQrbPFxZmNZuQOjMZDoYj/febFsuspKjXdpoxo21w== -"@xterm/addon-unicode11@0.7.0-beta.15": - version "0.7.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.7.0-beta.15.tgz#3127bd0e0ba611ac7f1a72417c449dd6e234f054" - integrity sha512-6ZpYy3OMokO0CSmHrhvqbLVZg2iMDGGVeaYqPhe3+Ga5t9y1mSRXjKkKpXiQQYbEpiGcLd6cKfyfSzejw8v4tg== +"@xterm/addon-unicode11@0.7.0-beta.16": + version "0.7.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.7.0-beta.16.tgz#c4c640cb119290e1d0a6401ac018aba1d71287f9" + integrity sha512-sP81NX13madSeATjlBReZbaay17DgatR7dZP6OF8aMyJf6cBVaHMYjTipyw3NnsmjUtBfLc3Alu+JKv8NFteiw== -"@xterm/addon-webgl@0.17.0-beta.15": - version "0.17.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.17.0-beta.15.tgz#19700e78bf86bec21e5d2049ea4f488a70db7960" - integrity sha512-w/sszGoGk4X1QniYP+T/NGYz83TXIIoSgWUVeThYgNM2QZjKxymBbMn2VAVAPS4WEEGMCKFNJaeskc0k9pgmzA== +"@xterm/addon-webgl@0.17.0-beta.16": + version "0.17.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.17.0-beta.16.tgz#75466614bf8ea02a3fcb0900df48724c2344d081" + integrity sha512-+/eTLvSgYjvRX7oAKfpCDZdotrE8P/asCKXQtXjkbOtYRToI7kWEYfJzfgdFKFgDLKOpDdgY6Bgq384wEewlTA== -"@xterm/xterm@5.4.0-beta.15": - version "5.4.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.4.0-beta.15.tgz#d76f3f92730f27dc960db415f36361a1ba751c54" - integrity sha512-jtOJLaEwjmgciM3VEmwvb1S5jLD14jRkg234qPq4H//JJ+D8fTwRblON5T2ccpcClpVGaW4Ro5g/XPuFuQ8dvw== +"@xterm/xterm@5.4.0-beta.16": + version "5.4.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.4.0-beta.16.tgz#eb00506e56ba78c587fcacbada096c2af3693992" + integrity sha512-ARzWYQ8LfuZIn47TS8c+XKQhn/1ZVvbHdwlpolZIrT2pTarP+71U1b6cSpF7fV+OIV6tAPA8+q4g/1ZKHuOX8g== jschardet@3.0.0: version "3.0.0" diff --git a/remote/yarn.lock b/remote/yarn.lock index cb041430f53..6963a8f9a5f 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -114,45 +114,45 @@ resolved "https://registry.yarnpkg.com/@vscode/windows-registry/-/windows-registry-1.1.0.tgz#03dace7c29c46f658588b9885b9580e453ad21f9" integrity sha512-5AZzuWJpGscyiMOed0IuyEwt6iKmV5Us7zuwCDCFYMIq7tsvooO9BUiciywsvuthGz6UG4LSpeDeCxvgMVhnIw== -"@xterm/addon-canvas@0.6.0-beta.15": - version "0.6.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-canvas/-/addon-canvas-0.6.0-beta.15.tgz#ac800c3e8a1a26eeb0f76e36dabc342a840a1e0b" - integrity sha512-P5E+ywLTGG+Ii48Q3TZyK6aOzkYnoghJnUiyCb67g7zva3nDjw8Q4kKMlOrvZl6RHsLkSBwwLjOvUvg1nNOusg== +"@xterm/addon-canvas@0.6.0-beta.16": + version "0.6.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-canvas/-/addon-canvas-0.6.0-beta.16.tgz#d22ba7f1b211882215c5206ca07ce177378a898f" + integrity sha512-o89xcm0Tqy1ksEYMq3EIqxJNDUWJBaS9QUggc7i5vKUL2unw9TMa5IiiNzc3CsBOlBQDlITwEXoHDEbOMxoZPQ== -"@xterm/addon-image@0.7.0-beta.13": - version "0.7.0-beta.13" - resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.7.0-beta.13.tgz#bb854ecc3c2c9363804ca5c2d386e4298ffff425" - integrity sha512-q57H1ONHJ5e14XEN0MsjnvB3MdlsyVVjwAJfjWjESJFZT2e2qxyc2kflvXcTiBkLC4RCfnYchvU6PjgHJll3jw== +"@xterm/addon-image@0.7.0-beta.14": + version "0.7.0-beta.14" + resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.7.0-beta.14.tgz#39b123dd0a0390766aff631cf43cb2e51b3b2174" + integrity sha512-oCOIupROzkb5p2vZarY6HrX74OqvtbmjnkC6uuGEJXQ75XL2CX+uTUl2DlgeSTvvR0S8ZVB3hQlp4hrtoNNelA== -"@xterm/addon-search@0.14.0-beta.15": - version "0.14.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.14.0-beta.15.tgz#48ed3f0899cdfe3310058aa46dc03b7e40269742" - integrity sha512-HFiyJgHD8wnhYZLF3Dy5J4dWMhpCp6WR1IEoT3PchV3c6s52Sc8GCL/eJtequ8Rai5b7x/o0gNxBLzDL5dODnA== +"@xterm/addon-search@0.14.0-beta.16": + version "0.14.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.14.0-beta.16.tgz#5fa21d2b993970e8ced1e0ada3dcca5f7581c314" + integrity sha512-e6l5jCJIULQ6nzRcc0gp9obZsqd76qubAr0HZF6Ebxf3KOGRz4UX6g+kgt6RB1liWgG94WD8vI1rGB1z5bMSEg== -"@xterm/addon-serialize@0.12.0-beta.15": - version "0.12.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.12.0-beta.15.tgz#ca69f732490ae4512c312c4c0edf239d575390d0" - integrity sha512-SREdfJZ2eafeg846mYM8akjgezc+b+hN/a+UkvI/IOStE4kJXwNWQXSGPfmn+9UNzRxTYUEmjT+nbadE9M+9yg== +"@xterm/addon-serialize@0.12.0-beta.16": + version "0.12.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.12.0-beta.16.tgz#68c4d68dba7ff17a231650cc0d07dcc77721877b" + integrity sha512-F6ngtvTC5VDLn585uJro7V1xjM43TbjPQjQ6Fn0Uic3+dsQrbPFxZmNZuQOjMZDoYj/febFsuspKjXdpoxo21w== -"@xterm/addon-unicode11@0.7.0-beta.15": - version "0.7.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.7.0-beta.15.tgz#3127bd0e0ba611ac7f1a72417c449dd6e234f054" - integrity sha512-6ZpYy3OMokO0CSmHrhvqbLVZg2iMDGGVeaYqPhe3+Ga5t9y1mSRXjKkKpXiQQYbEpiGcLd6cKfyfSzejw8v4tg== +"@xterm/addon-unicode11@0.7.0-beta.16": + version "0.7.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.7.0-beta.16.tgz#c4c640cb119290e1d0a6401ac018aba1d71287f9" + integrity sha512-sP81NX13madSeATjlBReZbaay17DgatR7dZP6OF8aMyJf6cBVaHMYjTipyw3NnsmjUtBfLc3Alu+JKv8NFteiw== -"@xterm/addon-webgl@0.17.0-beta.15": - version "0.17.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.17.0-beta.15.tgz#19700e78bf86bec21e5d2049ea4f488a70db7960" - integrity sha512-w/sszGoGk4X1QniYP+T/NGYz83TXIIoSgWUVeThYgNM2QZjKxymBbMn2VAVAPS4WEEGMCKFNJaeskc0k9pgmzA== +"@xterm/addon-webgl@0.17.0-beta.16": + version "0.17.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.17.0-beta.16.tgz#75466614bf8ea02a3fcb0900df48724c2344d081" + integrity sha512-+/eTLvSgYjvRX7oAKfpCDZdotrE8P/asCKXQtXjkbOtYRToI7kWEYfJzfgdFKFgDLKOpDdgY6Bgq384wEewlTA== -"@xterm/headless@5.4.0-beta.15": - version "5.4.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.4.0-beta.15.tgz#04826e48635fdf2b5f89727534d577fc35699194" - integrity sha512-mtN4yEV2e/Nx9KBDLeQIdC5Dux5g3lEeX1nWafLEG1MRNBXts9Y5yp/x0oUZUN73zqr4LxlC+4h5JHrdXxaIZA== +"@xterm/headless@5.4.0-beta.16": + version "5.4.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.4.0-beta.16.tgz#d12097c6c2082f14f5650169471eb120ed7600e7" + integrity sha512-5GTEzrZzpjfoQrFexULq20Mqc5jbTmhkTBYk0XaE4jeZVdCvsw1yiZNDVj7/66cKOmhQMCxV809p2jQZ/BJ0ww== -"@xterm/xterm@5.4.0-beta.15": - version "5.4.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.4.0-beta.15.tgz#d76f3f92730f27dc960db415f36361a1ba751c54" - integrity sha512-jtOJLaEwjmgciM3VEmwvb1S5jLD14jRkg234qPq4H//JJ+D8fTwRblON5T2ccpcClpVGaW4Ro5g/XPuFuQ8dvw== +"@xterm/xterm@5.4.0-beta.16": + version "5.4.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.4.0-beta.16.tgz#eb00506e56ba78c587fcacbada096c2af3693992" + integrity sha512-ARzWYQ8LfuZIn47TS8c+XKQhn/1ZVvbHdwlpolZIrT2pTarP+71U1b6cSpF7fV+OIV6tAPA8+q4g/1ZKHuOX8g== agent-base@^7.0.1, agent-base@^7.0.2, agent-base@^7.1.0: version "7.1.0" diff --git a/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts b/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts index 7c574c18841..81ca2c249c1 100644 --- a/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts @@ -5,10 +5,9 @@ import type { Terminal as RawXtermTerminal } from '@xterm/xterm'; import { Event } from 'vs/base/common/event'; -import { EventType, addDisposableListener } from 'vs/base/browser/dom'; import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement'; -import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { isMacintosh } from 'vs/base/common/platform'; import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { IDetachedTerminalInstance, ITerminalContribution, ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -67,7 +66,8 @@ class TerminalMouseWheelZoomContribution extends Disposable implements ITerminal let gestureHasZoomModifiers = false; let gestureAccumulatedDelta = 0; - this._listener.value = addDisposableListener(raw.element!, EventType.MOUSE_WHEEL, (browserEvent: IMouseWheelEvent) => { + raw.attachCustomWheelEventHandler((e: WheelEvent) => { + const browserEvent = e as any as IMouseWheelEvent; if (classifier.isPhysicalMouseWheel()) { if (hasMouseWheelZoomModifiers(browserEvent)) { const delta = browserEvent.deltaY > 0 ? -1 : 1; @@ -76,6 +76,7 @@ class TerminalMouseWheelZoomContribution extends Disposable implements ITerminal // EditorZoom.setZoomLevel(zoomLevel + delta); browserEvent.preventDefault(); browserEvent.stopPropagation(); + return false; } } else { // we consider mousewheel events that occur within 50ms of each other to be part of the same gesture @@ -102,9 +103,12 @@ class TerminalMouseWheelZoomContribution extends Disposable implements ITerminal gestureAccumulatedDelta += browserEvent.deltaY; browserEvent.preventDefault(); browserEvent.stopPropagation(); + return false; } } - }, { passive: false }); + return true; + }); + this._listener.value = toDisposable(() => raw.attachCustomWheelEventHandler(() => true)); } } diff --git a/yarn.lock b/yarn.lock index 77b6bc68c41..88e8a13ac21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1675,45 +1675,45 @@ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.1.tgz#34bdc31727a1889198855913db2f270ace6d7bf8" integrity sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw== -"@xterm/addon-canvas@0.6.0-beta.15": - version "0.6.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-canvas/-/addon-canvas-0.6.0-beta.15.tgz#ac800c3e8a1a26eeb0f76e36dabc342a840a1e0b" - integrity sha512-P5E+ywLTGG+Ii48Q3TZyK6aOzkYnoghJnUiyCb67g7zva3nDjw8Q4kKMlOrvZl6RHsLkSBwwLjOvUvg1nNOusg== +"@xterm/addon-canvas@0.6.0-beta.16": + version "0.6.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-canvas/-/addon-canvas-0.6.0-beta.16.tgz#d22ba7f1b211882215c5206ca07ce177378a898f" + integrity sha512-o89xcm0Tqy1ksEYMq3EIqxJNDUWJBaS9QUggc7i5vKUL2unw9TMa5IiiNzc3CsBOlBQDlITwEXoHDEbOMxoZPQ== -"@xterm/addon-image@0.7.0-beta.13": - version "0.7.0-beta.13" - resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.7.0-beta.13.tgz#bb854ecc3c2c9363804ca5c2d386e4298ffff425" - integrity sha512-q57H1ONHJ5e14XEN0MsjnvB3MdlsyVVjwAJfjWjESJFZT2e2qxyc2kflvXcTiBkLC4RCfnYchvU6PjgHJll3jw== +"@xterm/addon-image@0.7.0-beta.14": + version "0.7.0-beta.14" + resolved "https://registry.yarnpkg.com/@xterm/addon-image/-/addon-image-0.7.0-beta.14.tgz#39b123dd0a0390766aff631cf43cb2e51b3b2174" + integrity sha512-oCOIupROzkb5p2vZarY6HrX74OqvtbmjnkC6uuGEJXQ75XL2CX+uTUl2DlgeSTvvR0S8ZVB3hQlp4hrtoNNelA== -"@xterm/addon-search@0.14.0-beta.15": - version "0.14.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.14.0-beta.15.tgz#48ed3f0899cdfe3310058aa46dc03b7e40269742" - integrity sha512-HFiyJgHD8wnhYZLF3Dy5J4dWMhpCp6WR1IEoT3PchV3c6s52Sc8GCL/eJtequ8Rai5b7x/o0gNxBLzDL5dODnA== +"@xterm/addon-search@0.14.0-beta.16": + version "0.14.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-search/-/addon-search-0.14.0-beta.16.tgz#5fa21d2b993970e8ced1e0ada3dcca5f7581c314" + integrity sha512-e6l5jCJIULQ6nzRcc0gp9obZsqd76qubAr0HZF6Ebxf3KOGRz4UX6g+kgt6RB1liWgG94WD8vI1rGB1z5bMSEg== -"@xterm/addon-serialize@0.12.0-beta.15": - version "0.12.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.12.0-beta.15.tgz#ca69f732490ae4512c312c4c0edf239d575390d0" - integrity sha512-SREdfJZ2eafeg846mYM8akjgezc+b+hN/a+UkvI/IOStE4kJXwNWQXSGPfmn+9UNzRxTYUEmjT+nbadE9M+9yg== +"@xterm/addon-serialize@0.12.0-beta.16": + version "0.12.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-serialize/-/addon-serialize-0.12.0-beta.16.tgz#68c4d68dba7ff17a231650cc0d07dcc77721877b" + integrity sha512-F6ngtvTC5VDLn585uJro7V1xjM43TbjPQjQ6Fn0Uic3+dsQrbPFxZmNZuQOjMZDoYj/febFsuspKjXdpoxo21w== -"@xterm/addon-unicode11@0.7.0-beta.15": - version "0.7.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.7.0-beta.15.tgz#3127bd0e0ba611ac7f1a72417c449dd6e234f054" - integrity sha512-6ZpYy3OMokO0CSmHrhvqbLVZg2iMDGGVeaYqPhe3+Ga5t9y1mSRXjKkKpXiQQYbEpiGcLd6cKfyfSzejw8v4tg== +"@xterm/addon-unicode11@0.7.0-beta.16": + version "0.7.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-unicode11/-/addon-unicode11-0.7.0-beta.16.tgz#c4c640cb119290e1d0a6401ac018aba1d71287f9" + integrity sha512-sP81NX13madSeATjlBReZbaay17DgatR7dZP6OF8aMyJf6cBVaHMYjTipyw3NnsmjUtBfLc3Alu+JKv8NFteiw== -"@xterm/addon-webgl@0.17.0-beta.15": - version "0.17.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.17.0-beta.15.tgz#19700e78bf86bec21e5d2049ea4f488a70db7960" - integrity sha512-w/sszGoGk4X1QniYP+T/NGYz83TXIIoSgWUVeThYgNM2QZjKxymBbMn2VAVAPS4WEEGMCKFNJaeskc0k9pgmzA== +"@xterm/addon-webgl@0.17.0-beta.16": + version "0.17.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/addon-webgl/-/addon-webgl-0.17.0-beta.16.tgz#75466614bf8ea02a3fcb0900df48724c2344d081" + integrity sha512-+/eTLvSgYjvRX7oAKfpCDZdotrE8P/asCKXQtXjkbOtYRToI7kWEYfJzfgdFKFgDLKOpDdgY6Bgq384wEewlTA== -"@xterm/headless@5.4.0-beta.15": - version "5.4.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.4.0-beta.15.tgz#04826e48635fdf2b5f89727534d577fc35699194" - integrity sha512-mtN4yEV2e/Nx9KBDLeQIdC5Dux5g3lEeX1nWafLEG1MRNBXts9Y5yp/x0oUZUN73zqr4LxlC+4h5JHrdXxaIZA== +"@xterm/headless@5.4.0-beta.16": + version "5.4.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/headless/-/headless-5.4.0-beta.16.tgz#d12097c6c2082f14f5650169471eb120ed7600e7" + integrity sha512-5GTEzrZzpjfoQrFexULq20Mqc5jbTmhkTBYk0XaE4jeZVdCvsw1yiZNDVj7/66cKOmhQMCxV809p2jQZ/BJ0ww== -"@xterm/xterm@5.4.0-beta.15": - version "5.4.0-beta.15" - resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.4.0-beta.15.tgz#d76f3f92730f27dc960db415f36361a1ba751c54" - integrity sha512-jtOJLaEwjmgciM3VEmwvb1S5jLD14jRkg234qPq4H//JJ+D8fTwRblON5T2ccpcClpVGaW4Ro5g/XPuFuQ8dvw== +"@xterm/xterm@5.4.0-beta.16": + version "5.4.0-beta.16" + resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.4.0-beta.16.tgz#eb00506e56ba78c587fcacbada096c2af3693992" + integrity sha512-ARzWYQ8LfuZIn47TS8c+XKQhn/1ZVvbHdwlpolZIrT2pTarP+71U1b6cSpF7fV+OIV6tAPA8+q4g/1ZKHuOX8g== "@xtuc/ieee754@^1.2.0": version "1.2.0" From 04224e809844bd3289f322767d8fef2494781ec1 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Dec 2023 05:45:46 -0800 Subject: [PATCH 55/80] Correct strings --- .../contrib/terminal/common/terminalConfiguration.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 8913ae57c39..bb9975e6338 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -646,8 +646,8 @@ const terminalConfiguration: IConfigurationNode = { }, [TerminalSettingId.MouseWheelZoom]: { markdownDescription: isMacintosh - ? localize('terminal.integrated.mouseWheelZoom.mac', "Zoom the font of the editor when using mouse wheel and holding `Cmd`.") - : localize('terminal.integrated.mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`."), + ? localize('terminal.integrated.mouseWheelZoom.mac', "Zoom the font of the terminal when using mouse wheel and holding `Cmd`.") + : localize('terminal.integrated.mouseWheelZoom', "Zoom the font of the terminal when using mouse wheel and holding `Ctrl`."), type: 'boolean', default: false }, From 93ae54738e9366ad7884e784376da613c8b6289c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Dec 2023 05:46:55 -0800 Subject: [PATCH 56/80] Fix editor.mouseWheelZoom string on mac Fixes #200635 --- src/vs/editor/common/config/editorOptions.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index bfbba22c406..ca0256ab299 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -5600,7 +5600,11 @@ export const EditorOptions = { )), mouseWheelZoom: register(new EditorBooleanOption( EditorOption.mouseWheelZoom, 'mouseWheelZoom', false, - { markdownDescription: nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`.") } + { + markdownDescription: platform.isMacintosh + ? nls.localize('mouseWheelZoom.mac', "Zoom the font of the editor when using mouse wheel and holding `Cmd`.") + : nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`.") + } )), multiCursorMergeOverlapping: register(new EditorBooleanOption( EditorOption.multiCursorMergeOverlapping, 'multiCursorMergeOverlapping', true, From d25b735c3a2530336b808234a14bb3b97b8d8316 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Dec 2023 05:54:26 -0800 Subject: [PATCH 57/80] Remove logs --- .../browser/terminal.mouseWheelZoom.contribution.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts b/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts index 81ca2c249c1..a5c36779ef0 100644 --- a/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/mouseWheelZoom/browser/terminal.mouseWheelZoom.contribution.ts @@ -71,7 +71,6 @@ class TerminalMouseWheelZoomContribution extends Disposable implements ITerminal if (classifier.isPhysicalMouseWheel()) { if (hasMouseWheelZoomModifiers(browserEvent)) { const delta = browserEvent.deltaY > 0 ? -1 : 1; - console.log('delta', delta); this._configurationService.updateValue(TerminalSettingId.FontSize, this._getConfigFontSize() + delta); // EditorZoom.setZoomLevel(zoomLevel + delta); browserEvent.preventDefault(); @@ -93,9 +92,6 @@ class TerminalMouseWheelZoomContribution extends Disposable implements ITerminal gestureAccumulatedDelta += browserEvent.deltaY; if (gestureHasZoomModifiers) { - - console.log('set', gestureStartFontSize + gestureAccumulatedDelta / 5); - const deltaAbs = Math.ceil(Math.abs(gestureAccumulatedDelta / 5)); const deltaDirection = gestureAccumulatedDelta > 0 ? -1 : 1; const delta = deltaAbs * deltaDirection; From 55cca47484dba9cc4315a9238bf52f36b574a23d Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Tue, 12 Dec 2023 15:30:19 +0100 Subject: [PATCH 58/80] Fixes #141229 --- .../unicodeHighlighter/browser/unicodeHighlighter.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts index eea1de6f65b..f44fc76e0bd 100644 --- a/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts +++ b/src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts @@ -405,6 +405,8 @@ export class UnicodeHighlighterHover implements IHoverPart { } } +const configureUnicodeHighlightOptionsStr = nls.localize('unicodeHighlight.configureUnicodeHighlightOptions', 'Configure Unicode Highlight Options'); + export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipant { public readonly hoverOrdinal: number = 5; @@ -498,7 +500,7 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa const markdown = new MarkdownString('', true) .appendMarkdown(reason) .appendText(' ') - .appendLink(uri, adjustSettings); + .appendLink(uri, adjustSettings, configureUnicodeHighlightOptionsStr); result.push(new MarkdownHover(this, d.range, [markdown], false, index++)); } return result; @@ -767,7 +769,7 @@ export class ShowExcludeOptions extends EditorAction { const result = await quickPickService.pick( options, - { title: nls.localize('unicodeHighlight.configureUnicodeHighlightOptions', 'Configure Unicode Highlight Options') } + { title: configureUnicodeHighlightOptionsStr } ); if (result) { From a622c731d780d0075604d034d92ecaca7be9b62e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 12 Dec 2023 07:03:20 -0800 Subject: [PATCH 59/80] Max out terminal canvas width to 4096px Fixes #134623 --- .../workbench/contrib/terminal/browser/terminalInstance.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 2bde3849f36..efdb8aea0c2 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -98,8 +98,7 @@ const enum Constants { DefaultCols = 80, DefaultRows = 30, - MaxSupportedCols = 5000, - MaxCanvasWidth = 8000 + MaxCanvasWidth = 4096 } let xtermConstructor: Promise | undefined; @@ -1975,8 +1974,10 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._initDimensions(); await this._resize(); } else { + const font = this.xterm ? this.xterm.getFont() : this._configHelper.getFont(dom.getWindow(this.domElement)); + const maxColsForTexture = Math.floor(Constants.MaxCanvasWidth / (font.charWidth ?? 20)); // Fixed columns should be at least xterm.js' regular column count - const proposedCols = Math.max(this.maxCols, Math.min(this.xterm.getLongestViewportWrappedLineLength(), Constants.MaxSupportedCols)); + const proposedCols = Math.max(this.maxCols, Math.min(this.xterm.getLongestViewportWrappedLineLength(), maxColsForTexture)); // Don't switch to fixed dimensions if the content already fits as it makes the scroll // bar look bad being off the edge if (proposedCols > this.xterm.raw.cols) { From 2380ef77cba3e69c0e2303db1f132c940987056b Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Dec 2023 16:20:13 +0100 Subject: [PATCH 60/80] fix https://github.com/microsoft/vscode-copilot-release/issues/577 (#200650) fyi @roblourens this also affects panel chat --- src/vs/workbench/contrib/chat/browser/chatInputPart.ts | 7 ++++++- .../contrib/inlineChat/browser/inlineChatWidget.ts | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index fa83b4d919d..68d027868f2 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -246,7 +246,12 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge options.cursorWidth = 1; options.wrappingStrategy = 'advanced'; options.bracketPairColorization = { enabled: false }; - options.suggest = { showIcons: false }; + options.suggest = { + showIcons: false, + showSnippets: false, + showWords: true, + showStatusBar: false, + }; options.scrollbar = { ...(options.scrollbar ?? {}), vertical: 'hidden' }; this._inputEditorElement = dom.append(inputContainer, $('.interactive-input-editor')); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 82968e83c6f..b28e36e1a66 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -109,6 +109,7 @@ export const _inputEditorOptions: IEditorConstructionOptions = { suggest: { showIcons: false, showSnippets: false, + showWords: true, showStatusBar: false, }, wordWrap: 'on', From 40753f6dba99dea1090fa9afc385d97f539dd4a1 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Tue, 12 Dec 2023 16:20:39 +0100 Subject: [PATCH 61/80] fix #200515 (#200651) include padding in width calculation --- src/vs/workbench/browser/parts/paneCompositePart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/paneCompositePart.ts b/src/vs/workbench/browser/parts/paneCompositePart.ts index 5a1c52707c9..a534c3492e0 100644 --- a/src/vs/workbench/browser/parts/paneCompositePart.ts +++ b/src/vs/workbench/browser/parts/paneCompositePart.ts @@ -480,7 +480,7 @@ export abstract class AbstractPaneCompositePart extends CompositePart Date: Tue, 12 Dec 2023 07:30:37 -0800 Subject: [PATCH 62/80] Fix terminal resize commands when in side bar Fixes #140873 --- src/vs/workbench/contrib/terminal/browser/terminalGroup.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts b/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts index 65dbfe1b4fc..e0b14265066 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts @@ -67,8 +67,11 @@ class SplitPaneContainer extends Disposable { if ((isHorizontal && this.orientation !== Orientation.HORIZONTAL) || (!isHorizontal && this.orientation !== Orientation.VERTICAL)) { // Resize the entire pane as a whole - if ((this.orientation === Orientation.HORIZONTAL && direction === Direction.Down) || - (this.orientation === Orientation.VERTICAL && direction === Direction.Right)) { + if ( + (this.orientation === Orientation.HORIZONTAL && direction === Direction.Down) || + (part === Parts.SIDEBAR_PART && direction === Direction.Left) || + (part === Parts.AUXILIARYBAR_PART && direction === Direction.Right) + ) { amount *= -1; } From 04c01c089d3ad1970a7cc5f01c3b693b7c5365d7 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Dec 2023 16:33:18 +0100 Subject: [PATCH 63/80] wrap API-events per extension so that blaming and telemetry-ignoring/redirecting is possible (#200657) fixes https://github.com/microsoft/vscode/issues/184132 --- .../workbench/api/common/extHost.api.impl.ts | 149 ++++++++++-------- .../workbench/api/common/extHostDocuments.ts | 9 +- .../workbench/api/common/extHostNotebook.ts | 9 +- .../api/common/extHostNotebookEditors.ts | 5 +- .../api/common/extHostTextEditors.ts | 13 +- 5 files changed, 100 insertions(+), 85 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 5219bce72fd..ff3e1babd78 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -232,6 +232,25 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return function (extension: IExtensionDescription, extensionInfo: IExtensionRegistries, configProvider: ExtHostConfigProvider): typeof vscode { + // Wraps an event with error handling and telemetry so that we know what extension fails + // handling events. This will prevent us from reporting this as "our" error-telemetry and + // allows for better blaming + function _asExtensionEvent(actual: vscode.Event): vscode.Event { + return (listener, thisArgs, disposables) => { + const handle = actual(e => { + try { + listener.call(thisArgs, e); + } catch (err) { + errors.onUnexpectedExternalError(new Error(`[ExtensionListenerError] Extension '${extension.identifier.value}' FAILED to handle event`, { cause: err })); + extHostTelemetry.onExtensionError(extension.identifier, err); + } + }); + disposables?.push(handle); + return handle; + }; + } + + // Check document selectors for being overly generic. Technically this isn't a problem but // in practice many extensions say they support `fooLang` but need fs-access to do so. Those // extension should specify then the `file`-scheme, e.g. `{ scheme: 'fooLang', language: 'fooLang' }` @@ -276,8 +295,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension, 'authSession'); return !!(await extHostAuthentication.getSession(extension, providerId, scopes, { silent: true } as any)); }, - get onDidChangeSessions(): Event { - return extHostAuthentication.onDidChangeSessions; + get onDidChangeSessions(): vscode.Event { + return _asExtensionEvent(extHostAuthentication.onDidChangeSessions); }, registerAuthenticationProvider(id: string, label: string, provider: vscode.AuthenticationProvider, options?: vscode.AuthenticationProviderOptions): vscode.Disposable { return extHostAuthentication.registerAuthenticationProvider(id, label, provider, options); @@ -344,21 +363,21 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostTerminalService.getDefaultShell(false); }, get onDidChangeShell() { - return extHostTerminalService.onDidChangeShell; + return _asExtensionEvent(extHostTerminalService.onDidChangeShell); }, get isTelemetryEnabled() { return extHostTelemetry.getTelemetryConfiguration(); }, - get onDidChangeTelemetryEnabled(): Event { - return extHostTelemetry.onDidChangeTelemetryEnabled; + get onDidChangeTelemetryEnabled(): vscode.Event { + return _asExtensionEvent(extHostTelemetry.onDidChangeTelemetryEnabled); }, get telemetryConfiguration(): vscode.TelemetryConfiguration { checkProposedApiEnabled(extension, 'telemetry'); return extHostTelemetry.getTelemetryDetails(); }, - get onDidChangeTelemetryConfiguration(): Event { + get onDidChangeTelemetryConfiguration(): vscode.Event { checkProposedApiEnabled(extension, 'telemetry'); - return extHostTelemetry.onDidChangeTelemetryConfiguration; + return _asExtensionEvent(extHostTelemetry.onDidChangeTelemetryConfiguration); }, get isNewAppInstall() { return isNewAppInstall(initData.telemetryInfo.firstSessionDate); @@ -402,7 +421,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostLogService.getLevel(); }, get onDidChangeLogLevel() { - return extHostLogService.onDidChangeLogLevel; + return _asExtensionEvent(extHostLogService.onDidChangeLogLevel); }, registerIssueUriRequestHandler(handler: vscode.IssueUriRequestHandler) { checkProposedApiEnabled(extension, 'handleIssueUri'); @@ -441,7 +460,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, get onDidChangeTestResults() { checkProposedApiEnabled(extension, 'testObserver'); - return extHostTesting.onResultsChanged; + return _asExtensionEvent(extHostTesting.onResultsChanged); }, get testResults() { checkProposedApiEnabled(extension, 'testObserver'); @@ -490,9 +509,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, get onDidChange() { if (isProposedApiEnabled(extension, 'extensionsAny')) { - return Event.any(extensionInfo.mine.onDidChange, extensionInfo.all.onDidChange); + return _asExtensionEvent(Event.any(extensionInfo.mine.onDidChange, extensionInfo.all.onDidChange)); } - return extensionInfo.mine.onDidChange; + return _asExtensionEvent(extensionInfo.mine.onDidChange); } }; @@ -502,7 +521,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostDiagnostics.createDiagnosticCollection(extension.identifier, name); }, get onDidChangeDiagnostics() { - return extHostDiagnostics.onDidChangeDiagnostics; + return _asExtensionEvent(extHostDiagnostics.onDidChangeDiagnostics); }, getDiagnostics: (resource?: vscode.Uri) => { return extHostDiagnostics.getDiagnostics(resource); @@ -666,52 +685,52 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostEditors.createTextEditorDecorationType(extension, options); }, onDidChangeActiveTextEditor(listener, thisArg?, disposables?) { - return extHostEditors.onDidChangeActiveTextEditor(listener, thisArg, disposables); + return _asExtensionEvent(extHostEditors.onDidChangeActiveTextEditor)(listener, thisArg, disposables); }, onDidChangeVisibleTextEditors(listener, thisArg, disposables) { - return extHostEditors.onDidChangeVisibleTextEditors(listener, thisArg, disposables); + return _asExtensionEvent(extHostEditors.onDidChangeVisibleTextEditors)(listener, thisArg, disposables); }, onDidChangeTextEditorSelection(listener: (e: vscode.TextEditorSelectionChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { - return extHostEditors.onDidChangeTextEditorSelection(listener, thisArgs, disposables); + return _asExtensionEvent(extHostEditors.onDidChangeTextEditorSelection)(listener, thisArgs, disposables); }, onDidChangeTextEditorOptions(listener: (e: vscode.TextEditorOptionsChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { - return extHostEditors.onDidChangeTextEditorOptions(listener, thisArgs, disposables); + return _asExtensionEvent(extHostEditors.onDidChangeTextEditorOptions)(listener, thisArgs, disposables); }, onDidChangeTextEditorVisibleRanges(listener: (e: vscode.TextEditorVisibleRangesChangeEvent) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) { - return extHostEditors.onDidChangeTextEditorVisibleRanges(listener, thisArgs, disposables); + return _asExtensionEvent(extHostEditors.onDidChangeTextEditorVisibleRanges)(listener, thisArgs, disposables); }, onDidChangeTextEditorViewColumn(listener, thisArg?, disposables?) { - return extHostEditors.onDidChangeTextEditorViewColumn(listener, thisArg, disposables); + return _asExtensionEvent(extHostEditors.onDidChangeTextEditorViewColumn)(listener, thisArg, disposables); }, onDidCloseTerminal(listener, thisArg?, disposables?) { - return extHostTerminalService.onDidCloseTerminal(listener, thisArg, disposables); + return _asExtensionEvent(extHostTerminalService.onDidCloseTerminal)(listener, thisArg, disposables); }, onDidOpenTerminal(listener, thisArg?, disposables?) { - return extHostTerminalService.onDidOpenTerminal(listener, thisArg, disposables); + return _asExtensionEvent(extHostTerminalService.onDidOpenTerminal)(listener, thisArg, disposables); }, onDidChangeActiveTerminal(listener, thisArg?, disposables?) { - return extHostTerminalService.onDidChangeActiveTerminal(listener, thisArg, disposables); + return _asExtensionEvent(extHostTerminalService.onDidChangeActiveTerminal)(listener, thisArg, disposables); }, onDidChangeTerminalDimensions(listener, thisArg?, disposables?) { checkProposedApiEnabled(extension, 'terminalDimensions'); - return extHostTerminalService.onDidChangeTerminalDimensions(listener, thisArg, disposables); + return _asExtensionEvent(extHostTerminalService.onDidChangeTerminalDimensions)(listener, thisArg, disposables); }, onDidChangeTerminalState(listener, thisArg?, disposables?) { - return extHostTerminalService.onDidChangeTerminalState(listener, thisArg, disposables); + return _asExtensionEvent(extHostTerminalService.onDidChangeTerminalState)(listener, thisArg, disposables); }, onDidWriteTerminalData(listener, thisArg?, disposables?) { checkProposedApiEnabled(extension, 'terminalDataWriteEvent'); - return extHostTerminalService.onDidWriteTerminalData(listener, thisArg, disposables); + return _asExtensionEvent(extHostTerminalService.onDidWriteTerminalData)(listener, thisArg, disposables); }, onDidExecuteTerminalCommand(listener, thisArg?, disposables?) { checkProposedApiEnabled(extension, 'terminalExecuteCommandEvent'); - return extHostTerminalService.onDidExecuteTerminalCommand(listener, thisArg, disposables); + return _asExtensionEvent(extHostTerminalService.onDidExecuteTerminalCommand)(listener, thisArg, disposables); }, get state() { return extHostWindow.getState(extension); }, onDidChangeWindowState(listener, thisArg?, disposables?) { - return extHostWindow.onDidChangeWindowState(listener, thisArg, disposables); + return _asExtensionEvent(extHostWindow.onDidChangeWindowState)(listener, thisArg, disposables); }, showInformationMessage(message: string, ...rest: Array) { return >extHostMessageService.showMessage(extension, Severity.Info, message, rest[0], >rest.slice(1)); @@ -822,7 +841,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostTheming.activeColorTheme; }, onDidChangeActiveColorTheme(listener, thisArg?, disposables?) { - return extHostTheming.onDidChangeActiveColorTheme(listener, thisArg, disposables); + return _asExtensionEvent(extHostTheming.onDidChangeActiveColorTheme)(listener, thisArg, disposables); }, registerWebviewViewProvider(viewId: string, provider: vscode.WebviewViewProvider, options?: { webviewOptions?: { @@ -835,19 +854,19 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostNotebook.activeNotebookEditor; }, onDidChangeActiveNotebookEditor(listener, thisArgs?, disposables?) { - return extHostNotebook.onDidChangeActiveNotebookEditor(listener, thisArgs, disposables); + return _asExtensionEvent(extHostNotebook.onDidChangeActiveNotebookEditor)(listener, thisArgs, disposables); }, get visibleNotebookEditors() { return extHostNotebook.visibleNotebookEditors; }, get onDidChangeVisibleNotebookEditors() { - return extHostNotebook.onDidChangeVisibleNotebookEditors; + return _asExtensionEvent(extHostNotebook.onDidChangeVisibleNotebookEditors); }, onDidChangeNotebookEditorSelection(listener, thisArgs?, disposables?) { - return extHostNotebookEditors.onDidChangeNotebookEditorSelection(listener, thisArgs, disposables); + return _asExtensionEvent(extHostNotebookEditors.onDidChangeNotebookEditorSelection)(listener, thisArgs, disposables); }, onDidChangeNotebookEditorVisibleRanges(listener, thisArgs?, disposables?) { - return extHostNotebookEditors.onDidChangeNotebookEditorVisibleRanges(listener, thisArgs, disposables); + return _asExtensionEvent(extHostNotebookEditors.onDidChangeNotebookEditorVisibleRanges)(listener, thisArgs, disposables); }, showNotebookDocument(document, options?) { return extHostNotebook.showNotebookDocument(document, options); @@ -907,7 +926,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostWorkspace.updateWorkspaceFolders(extension, index, deleteCount || 0, ...workspaceFoldersToAdd); }, onDidChangeWorkspaceFolders: function (listener, thisArgs?, disposables?) { - return extHostWorkspace.onDidChangeWorkspace(listener, thisArgs, disposables); + return _asExtensionEvent(extHostWorkspace.onDidChangeWorkspace)(listener, thisArgs, disposables); }, asRelativePath: (pathOrUri, includeWorkspace?) => { return extHostWorkspace.getRelativePath(pathOrUri, includeWorkspace); @@ -991,19 +1010,19 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }); }, onDidOpenTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidAddDocument(listener, thisArgs, disposables); + return _asExtensionEvent(extHostDocuments.onDidAddDocument)(listener, thisArgs, disposables); }, onDidCloseTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidRemoveDocument(listener, thisArgs, disposables); + return _asExtensionEvent(extHostDocuments.onDidRemoveDocument)(listener, thisArgs, disposables); }, onDidChangeTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidChangeDocument(listener, thisArgs, disposables); + return _asExtensionEvent(extHostDocuments.onDidChangeDocument)(listener, thisArgs, disposables); }, onDidSaveTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocuments.onDidSaveDocument(listener, thisArgs, disposables); + return _asExtensionEvent(extHostDocuments.onDidSaveDocument)(listener, thisArgs, disposables); }, onWillSaveTextDocument: (listener, thisArgs?, disposables?) => { - return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables); + return _asExtensionEvent(extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension))(listener, thisArgs, disposables); }, get notebookDocuments(): vscode.NotebookDocument[] { return extHostNotebook.notebookDocuments.map(d => d.apiNotebook); @@ -1021,25 +1040,25 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostNotebook.getNotebookDocument(uri).apiNotebook; }, onDidSaveNotebookDocument(listener, thisArg, disposables) { - return extHostNotebookDocuments.onDidSaveNotebookDocument(listener, thisArg, disposables); + return _asExtensionEvent(extHostNotebookDocuments.onDidSaveNotebookDocument)(listener, thisArg, disposables); }, onDidChangeNotebookDocument(listener, thisArg, disposables) { - return extHostNotebookDocuments.onDidChangeNotebookDocument(listener, thisArg, disposables); + return _asExtensionEvent(extHostNotebookDocuments.onDidChangeNotebookDocument)(listener, thisArg, disposables); }, onWillSaveNotebookDocument(listener, thisArg, disposables) { - return extHostNotebookDocumentSaveParticipant.getOnWillSaveNotebookDocumentEvent(extension)(listener, thisArg, disposables); + return _asExtensionEvent(extHostNotebookDocumentSaveParticipant.getOnWillSaveNotebookDocumentEvent(extension))(listener, thisArg, disposables); }, - get onDidOpenNotebookDocument(): Event { - return extHostNotebook.onDidOpenNotebookDocument; + get onDidOpenNotebookDocument() { + return _asExtensionEvent(extHostNotebook.onDidOpenNotebookDocument); }, - get onDidCloseNotebookDocument(): Event { - return extHostNotebook.onDidCloseNotebookDocument; + get onDidCloseNotebookDocument() { + return _asExtensionEvent(extHostNotebook.onDidCloseNotebookDocument); }, registerNotebookSerializer(viewType: string, serializer: vscode.NotebookSerializer, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) { return extHostNotebook.registerNotebookSerializer(extension, viewType, serializer, options, isProposedApiEnabled(extension, 'notebookLiveShare') ? registration : undefined); }, onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => { - return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables); + return _asExtensionEvent(configProvider.onDidChangeConfiguration)(listener, thisArgs, disposables); }, getConfiguration(section?: string, scope?: vscode.ConfigurationScope | null): vscode.WorkspaceConfiguration { scope = arguments.length === 1 ? undefined : scope; @@ -1084,22 +1103,22 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extensionService.getRemoteExecServer(authority); }, onDidCreateFiles: (listener, thisArg, disposables) => { - return extHostFileSystemEvent.onDidCreateFile(listener, thisArg, disposables); + return _asExtensionEvent(extHostFileSystemEvent.onDidCreateFile)(listener, thisArg, disposables); }, onDidDeleteFiles: (listener, thisArg, disposables) => { - return extHostFileSystemEvent.onDidDeleteFile(listener, thisArg, disposables); + return _asExtensionEvent(extHostFileSystemEvent.onDidDeleteFile)(listener, thisArg, disposables); }, onDidRenameFiles: (listener, thisArg, disposables) => { - return extHostFileSystemEvent.onDidRenameFile(listener, thisArg, disposables); + return _asExtensionEvent(extHostFileSystemEvent.onDidRenameFile)(listener, thisArg, disposables); }, onWillCreateFiles: (listener: (e: vscode.FileWillCreateEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { - return extHostFileSystemEvent.getOnWillCreateFileEvent(extension)(listener, thisArg, disposables); + return _asExtensionEvent(extHostFileSystemEvent.getOnWillCreateFileEvent(extension))(listener, thisArg, disposables); }, onWillDeleteFiles: (listener: (e: vscode.FileWillDeleteEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { - return extHostFileSystemEvent.getOnWillDeleteFileEvent(extension)(listener, thisArg, disposables); + return _asExtensionEvent(extHostFileSystemEvent.getOnWillDeleteFileEvent(extension))(listener, thisArg, disposables); }, onWillRenameFiles: (listener: (e: vscode.FileWillRenameEvent) => any, thisArg?: any, disposables?: vscode.Disposable[]) => { - return extHostFileSystemEvent.getOnWillRenameFileEvent(extension)(listener, thisArg, disposables); + return _asExtensionEvent(extHostFileSystemEvent.getOnWillRenameFileEvent(extension))(listener, thisArg, disposables); }, openTunnel: (forward: vscode.TunnelOptions) => { checkProposedApiEnabled(extension, 'tunnels'); @@ -1116,7 +1135,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, onDidChangeTunnels: (listener, thisArg?, disposables?) => { checkProposedApiEnabled(extension, 'tunnels'); - return extHostTunnelService.onDidChangeTunnels(listener, thisArg, disposables); + return _asExtensionEvent(extHostTunnelService.onDidChangeTunnels)(listener, thisArg, disposables); }, registerPortAttributesProvider: (portSelector: vscode.PortAttributesSelector, provider: vscode.PortAttributesProvider) => { checkProposedApiEnabled(extension, 'portsAttributes'); @@ -1138,7 +1157,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostWorkspace.requestWorkspaceTrust(options); }, onDidGrantWorkspaceTrust: (listener, thisArgs?, disposables?) => { - return extHostWorkspace.onDidGrantWorkspaceTrust(listener, thisArgs, disposables); + return _asExtensionEvent(extHostWorkspace.onDidGrantWorkspaceTrust)(listener, thisArgs, disposables); }, registerEditSessionIdentityProvider: (scheme: string, provider: vscode.EditSessionIdentityProvider) => { checkProposedApiEnabled(extension, 'editSessionIdentityProvider'); @@ -1146,7 +1165,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, onWillCreateEditSessionIdentity: (listener, thisArgs?, disposables?) => { checkProposedApiEnabled(extension, 'editSessionIdentityProvider'); - return extHostWorkspace.getOnWillCreateEditSessionIdentityEvent(extension)(listener, thisArgs, disposables); + return _asExtensionEvent(extHostWorkspace.getOnWillCreateEditSessionIdentityEvent(extension))(listener, thisArgs, disposables); }, registerCanonicalUriProvider: (scheme: string, provider: vscode.CanonicalUriProvider) => { checkProposedApiEnabled(extension, 'canonicalUriProvider'); @@ -1193,23 +1212,23 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostDebugService.stackFrameFocus; }, onDidStartDebugSession(listener, thisArg?, disposables?) { - return extHostDebugService.onDidStartDebugSession(listener, thisArg, disposables); + return _asExtensionEvent(extHostDebugService.onDidStartDebugSession)(listener, thisArg, disposables); }, onDidTerminateDebugSession(listener, thisArg?, disposables?) { - return extHostDebugService.onDidTerminateDebugSession(listener, thisArg, disposables); + return _asExtensionEvent(extHostDebugService.onDidTerminateDebugSession)(listener, thisArg, disposables); }, onDidChangeActiveDebugSession(listener, thisArg?, disposables?) { - return extHostDebugService.onDidChangeActiveDebugSession(listener, thisArg, disposables); + return _asExtensionEvent(extHostDebugService.onDidChangeActiveDebugSession)(listener, thisArg, disposables); }, onDidReceiveDebugSessionCustomEvent(listener, thisArg?, disposables?) { - return extHostDebugService.onDidReceiveDebugSessionCustomEvent(listener, thisArg, disposables); + return _asExtensionEvent(extHostDebugService.onDidReceiveDebugSessionCustomEvent)(listener, thisArg, disposables); }, onDidChangeBreakpoints(listener, thisArgs?, disposables?) { - return extHostDebugService.onDidChangeBreakpoints(listener, thisArgs, disposables); + return _asExtensionEvent(extHostDebugService.onDidChangeBreakpoints)(listener, thisArgs, disposables); }, onDidChangeStackFrameFocus(listener, thisArg?, disposables?) { checkProposedApiEnabled(extension, 'debugFocus'); - return extHostDebugService.onDidChangeStackFrameFocus(listener, thisArg, disposables); + return _asExtensionEvent(extHostDebugService.onDidChangeStackFrameFocus)(listener, thisArg, disposables); }, registerDebugConfigurationProvider(debugType: string, provider: vscode.DebugConfigurationProvider, triggerKind?: vscode.DebugConfigurationProviderTriggerKind) { return extHostDebugService.registerDebugConfigurationProvider(debugType, provider, triggerKind || DebugConfigurationProviderTriggerKind.Initial); @@ -1254,16 +1273,16 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I return extHostTask.taskExecutions; }, onDidStartTask: (listeners, thisArgs?, disposables?) => { - return extHostTask.onDidStartTask(listeners, thisArgs, disposables); + return _asExtensionEvent(extHostTask.onDidStartTask)(listeners, thisArgs, disposables); }, onDidEndTask: (listeners, thisArgs?, disposables?) => { - return extHostTask.onDidEndTask(listeners, thisArgs, disposables); + return _asExtensionEvent(extHostTask.onDidEndTask)(listeners, thisArgs, disposables); }, onDidStartTaskProcess: (listeners, thisArgs?, disposables?) => { - return extHostTask.onDidStartTaskProcess(listeners, thisArgs, disposables); + return _asExtensionEvent(extHostTask.onDidStartTaskProcess)(listeners, thisArgs, disposables); }, onDidEndTaskProcess: (listeners, thisArgs?, disposables?) => { - return extHostTask.onDidEndTaskProcess(listeners, thisArgs, disposables); + return _asExtensionEvent(extHostTask.onDidEndTaskProcess)(listeners, thisArgs, disposables); } }; @@ -1288,7 +1307,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, onDidChangeNotebookCellExecutionState(listener, thisArgs?, disposables?) { checkProposedApiEnabled(extension, 'notebookCellExecutionState'); - return extHostNotebookKernels.onDidChangeNotebookCellExecutionState(listener, thisArgs, disposables); + return _asExtensionEvent(extHostNotebookKernels.onDidChangeNotebookCellExecutionState)(listener, thisArgs, disposables); } }; diff --git a/src/vs/workbench/api/common/extHostDocuments.ts b/src/vs/workbench/api/common/extHostDocuments.ts index b02174f245b..c9e1dad81b0 100644 --- a/src/vs/workbench/api/common/extHostDocuments.ts +++ b/src/vs/workbench/api/common/extHostDocuments.ts @@ -15,14 +15,13 @@ import type * as vscode from 'vscode'; import { assertIsDefined } from 'vs/base/common/types'; import { deepFreeze } from 'vs/base/common/objects'; import { TextDocumentChangeReason } from 'vs/workbench/api/common/extHostTypes'; -import { onUnexpectedExternalError } from 'vs/base/common/errors'; export class ExtHostDocuments implements ExtHostDocumentsShape { - private readonly _onDidAddDocument = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidRemoveDocument = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidChangeDocument = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidSaveDocument = new Emitter({ onListenerError: onUnexpectedExternalError }); + private readonly _onDidAddDocument = new Emitter(); + private readonly _onDidRemoveDocument = new Emitter(); + private readonly _onDidChangeDocument = new Emitter(); + private readonly _onDidSaveDocument = new Emitter(); readonly onDidAddDocument: Event = this._onDidAddDocument.event; readonly onDidRemoveDocument: Event = this._onDidRemoveDocument.event; diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index 1d682d9cb78..98ac090b242 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -28,7 +28,6 @@ import { SerializableObjectWithBuffers } from 'vs/workbench/services/extensions/ import type * as vscode from 'vscode'; import { ExtHostCell, ExtHostNotebookDocument } from './extHostNotebookDocument'; import { ExtHostNotebookEditor } from './extHostNotebookEditor'; -import { onUnexpectedExternalError } from 'vs/base/common/errors'; import { IExtHostConsumerFileSystem } from 'vs/workbench/api/common/extHostFileSystemConsumer'; import { filter } from 'vs/base/common/objects'; import { Schemas } from 'vs/base/common/network'; @@ -51,7 +50,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { private readonly _editors = new Map(); private readonly _commandsConverter: CommandsConverter; - private readonly _onDidChangeActiveNotebookEditor = new Emitter({ onListenerError: onUnexpectedExternalError }); + private readonly _onDidChangeActiveNotebookEditor = new Emitter(); readonly onDidChangeActiveNotebookEditor = this._onDidChangeActiveNotebookEditor.event; private _activeNotebookEditor: ExtHostNotebookEditor | undefined; @@ -63,12 +62,12 @@ export class ExtHostNotebookController implements ExtHostNotebookShape { return this._visibleNotebookEditors.map(editor => editor.apiEditor); } - private _onDidOpenNotebookDocument = new Emitter({ onListenerError: onUnexpectedExternalError }); + private _onDidOpenNotebookDocument = new Emitter(); onDidOpenNotebookDocument: Event = this._onDidOpenNotebookDocument.event; - private _onDidCloseNotebookDocument = new Emitter({ onListenerError: onUnexpectedExternalError }); + private _onDidCloseNotebookDocument = new Emitter(); onDidCloseNotebookDocument: Event = this._onDidCloseNotebookDocument.event; - private _onDidChangeVisibleNotebookEditors = new Emitter({ onListenerError: onUnexpectedExternalError }); + private _onDidChangeVisibleNotebookEditors = new Emitter(); onDidChangeVisibleNotebookEditors = this._onDidChangeVisibleNotebookEditors.event; private _statusBarCache = new Cache('NotebookCellStatusBarCache'); diff --git a/src/vs/workbench/api/common/extHostNotebookEditors.ts b/src/vs/workbench/api/common/extHostNotebookEditors.ts index 99da029fe29..5073d92c5e0 100644 --- a/src/vs/workbench/api/common/extHostNotebookEditors.ts +++ b/src/vs/workbench/api/common/extHostNotebookEditors.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { onUnexpectedExternalError } from 'vs/base/common/errors'; import { Emitter } from 'vs/base/common/event'; import { ILogService } from 'vs/platform/log/common/log'; import { ExtHostNotebookEditorsShape, INotebookEditorPropertiesChangeData, INotebookEditorViewColumnInfo } from 'vs/workbench/api/common/extHost.protocol'; @@ -14,8 +13,8 @@ import type * as vscode from 'vscode'; export class ExtHostNotebookEditors implements ExtHostNotebookEditorsShape { - private readonly _onDidChangeNotebookEditorSelection = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidChangeNotebookEditorVisibleRanges = new Emitter({ onListenerError: onUnexpectedExternalError }); + private readonly _onDidChangeNotebookEditorSelection = new Emitter(); + private readonly _onDidChangeNotebookEditorVisibleRanges = new Emitter(); readonly onDidChangeNotebookEditorSelection = this._onDidChangeNotebookEditorSelection.event; readonly onDidChangeNotebookEditorVisibleRanges = this._onDidChangeNotebookEditorVisibleRanges.event; diff --git a/src/vs/workbench/api/common/extHostTextEditors.ts b/src/vs/workbench/api/common/extHostTextEditors.ts index 553c655631f..7ab8d65df53 100644 --- a/src/vs/workbench/api/common/extHostTextEditors.ts +++ b/src/vs/workbench/api/common/extHostTextEditors.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as arrays from 'vs/base/common/arrays'; -import { onUnexpectedExternalError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ExtHostEditorsShape, IEditorPropertiesChangeData, IMainContext, ITextDocumentShowOptions, ITextEditorPositionData, MainContext, MainThreadTextEditorsShape } from 'vs/workbench/api/common/extHost.protocol'; @@ -16,12 +15,12 @@ import * as vscode from 'vscode'; export class ExtHostEditors implements ExtHostEditorsShape { - private readonly _onDidChangeTextEditorSelection = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidChangeTextEditorOptions = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidChangeTextEditorVisibleRanges = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidChangeTextEditorViewColumn = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidChangeActiveTextEditor = new Emitter({ onListenerError: onUnexpectedExternalError }); - private readonly _onDidChangeVisibleTextEditors = new Emitter({ onListenerError: onUnexpectedExternalError }); + private readonly _onDidChangeTextEditorSelection = new Emitter(); + private readonly _onDidChangeTextEditorOptions = new Emitter(); + private readonly _onDidChangeTextEditorVisibleRanges = new Emitter(); + private readonly _onDidChangeTextEditorViewColumn = new Emitter(); + private readonly _onDidChangeActiveTextEditor = new Emitter(); + private readonly _onDidChangeVisibleTextEditors = new Emitter(); readonly onDidChangeTextEditorSelection: Event = this._onDidChangeTextEditorSelection.event; readonly onDidChangeTextEditorOptions: Event = this._onDidChangeTextEditorOptions.event; From b1cffad15337da6a68b8893fee07019af927904a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 12 Dec 2023 17:21:40 +0100 Subject: [PATCH 64/80] Fixing incorrect color range calculation (#200626) * fixing incorrect color new range calculation --- .../browser/colorHoverParticipant.ts | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts b/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts index 98c6b85ab55..e37a442f643 100644 --- a/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts +++ b/src/vs/editor/contrib/colorPicker/browser/colorHoverParticipant.ts @@ -7,7 +7,7 @@ import { AsyncIterableObject } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Color, RGBA } from 'vs/base/common/color'; import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { IModelDecoration, ITextModel, TrackedRangeStickiness } from 'vs/editor/common/model'; @@ -207,7 +207,7 @@ function renderHoverParts(participant: ColorHoverParticipant | StandaloneColorPi disposables.add(model.onColorFlushed(async (color: Color) => { await _updateColorPresentations(editorModel, model, color, range, colorHover); editorUpdatedByColorPicker = true; - range = _updateEditorModel(editor, range, model, context); + range = _updateEditorModel(editor, range, model); })); } disposables.add(model.onDidChangeColor((color: Color) => { @@ -224,30 +224,19 @@ function renderHoverParts(participant: ColorHoverParticipant | StandaloneColorPi return disposables; } -function _updateEditorModel(editor: ICodeEditor, range: Range, model: ColorPickerModel, context?: IEditorHoverRenderContext) { - let newRange: Range; +function _updateEditorModel(editor: IActiveCodeEditor, range: Range, model: ColorPickerModel): Range { const textEdits: ISingleEditOperation[] = []; - if (model.presentation.textEdit) { - textEdits.push(model.presentation.textEdit); - newRange = new Range( - model.presentation.textEdit.range.startLineNumber, - model.presentation.textEdit.range.startColumn, - model.presentation.textEdit.range.endLineNumber, - model.presentation.textEdit.range.endColumn - ); - const trackedRange = editor.getModel()!._setTrackedRange(null, newRange, TrackedRangeStickiness.GrowsOnlyWhenTypingAfter); - newRange = editor.getModel()!._getTrackedRange(trackedRange) || newRange; - } else { - textEdits.push({ range, text: model.presentation.label, forceMoveMarkers: false }); - newRange = range.setEndPosition(range.endLineNumber, range.startColumn + model.presentation.label.length); - } + const edit = model.presentation.textEdit ?? { range, text: model.presentation.label, forceMoveMarkers: false }; + textEdits.push(edit); if (model.presentation.additionalTextEdits) { textEdits.push(...model.presentation.additionalTextEdits); } + const replaceRange = Range.lift(edit.range); + const trackedRange = editor.getModel()._setTrackedRange(null, replaceRange, TrackedRangeStickiness.GrowsOnlyWhenTypingAfter); editor.executeEdits('colorpicker', textEdits); editor.pushUndoStop(); - return newRange; + return editor.getModel()._getTrackedRange(trackedRange) ?? replaceRange; } async function _updateColorPresentations(editorModel: ITextModel, colorPickerModel: ColorPickerModel, color: Color, range: Range, colorHover: ColorHover | StandaloneColorPickerHover) { From b70a276229cf575deaca9dcb8ced39af6a86bbbc Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Dec 2023 17:29:48 +0100 Subject: [PATCH 65/80] fix https://github.com/microsoft/vscode/issues/196663 (#200662) --- .../suggest/browser/suggestController.ts | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/suggest/browser/suggestController.ts b/src/vs/editor/contrib/suggest/browser/suggestController.ts index 5c2c332a8aa..fb837e61172 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestController.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestController.ts @@ -45,6 +45,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { basename, extname } from 'vs/base/common/resources'; import { hash } from 'vs/base/common/hash'; import { WindowIdleValue, getWindow } from 'vs/base/browser/dom'; +import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; // sticky suggest widget which doesn't disappear on focus out and such const _sticky = false @@ -53,7 +54,12 @@ const _sticky = false class LineSuffix { - private readonly _marker: string[] | undefined; + private readonly _decorationOptions = ModelDecorationOptions.register({ + description: 'suggest-line-suffix', + stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges + }); + + private _marker: string | undefined; constructor(private readonly _model: ITextModel, private readonly _position: IPosition) { // spy on what's happening right of the cursor. two cases: @@ -63,16 +69,21 @@ class LineSuffix { if (maxColumn !== _position.column) { const offset = _model.getOffsetAt(_position); const end = _model.getPositionAt(offset + 1); - this._marker = _model.deltaDecorations([], [{ - range: Range.fromPositions(_position, end), - options: { description: 'suggest-line-suffix', stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges } - }]); + _model.changeDecorations(accessor => { + if (this._marker) { + accessor.removeDecoration(this._marker); + } + this._marker = accessor.addDecoration(Range.fromPositions(_position, end), this._decorationOptions); + }); } } dispose(): void { if (this._marker && !this._model.isDisposed()) { - this._model.deltaDecorations(this._marker, []); + this._model.changeDecorations(accessor => { + accessor.removeDecoration(this._marker!); + this._marker = undefined; + }); } } @@ -84,7 +95,7 @@ class LineSuffix { // read the marker (in case suggest was triggered at line end) or compare // the cursor to the line end. if (this._marker) { - const range = this._model.getDecorationRange(this._marker[0]); + const range = this._model.getDecorationRange(this._marker); const end = this._model.getOffsetAt(range!.getStartPosition()); return end - this._model.getOffsetAt(position); } else { From aec76644e1b6fcd2a98e214c7330fc957935536e Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 12 Dec 2023 09:04:26 -0800 Subject: [PATCH 66/80] tunnels: slight wording fix on preventSleep (#200664) Fixes https://github.com/microsoft/vscode-remote-release/issues/9161 --- .../remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts b/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts index e67233a33ba..a1123af8777 100644 --- a/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts +++ b/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts @@ -807,7 +807,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis default: '' }, [CONFIGURATION_KEY_PREVENT_SLEEP]: { - description: localize('remoteTunnelAccess.preventSleep', "Prevent the computer from sleeping when remote tunnel access is turned on."), + description: localize('remoteTunnelAccess.preventSleep', "Prevent this computer from sleeping when remote tunnel access is turned on."), type: 'boolean', scope: ConfigurationScope.APPLICATION, default: false, From dc3b949a175d12f1621adff080da0c6e0b4a880f Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 12 Dec 2023 09:13:15 -0800 Subject: [PATCH 67/80] testing: fix case sensitivity in file coverage (#200666) File Explorer does not show the coverage bar Fixes #200604 --- src/vs/workbench/api/browser/mainThreadTesting.ts | 2 +- .../workbench/contrib/testing/common/testCoverageService.ts | 2 +- src/vs/workbench/contrib/testing/common/testTypes.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTesting.ts b/src/vs/workbench/api/browser/mainThreadTesting.ts index d6babee621e..26e050fbc4d 100644 --- a/src/vs/workbench/api/browser/mainThreadTesting.ts +++ b/src/vs/workbench/api/browser/mainThreadTesting.ts @@ -136,7 +136,7 @@ export class MainThreadTesting extends Disposable implements MainThreadTestingSh const fn = available ? ((token: CancellationToken) => TestCoverage.load(taskId, { provideFileCoverage: async token => await this.proxy.$provideFileCoverage(runId, taskId, token) - .then(c => c.map(IFileCoverage.deserialize)), + .then(c => c.map(u => IFileCoverage.deserialize(this.uriIdentityService, u))), resolveFileCoverage: (i, token) => this.proxy.$resolveFileCoverage(runId, taskId, i, token) .then(d => d.map(CoverageDetails.deserialize)), }, token)) : undefined; diff --git a/src/vs/workbench/contrib/testing/common/testCoverageService.ts b/src/vs/workbench/contrib/testing/common/testCoverageService.ts index 49ce599a75f..9e5b175eb7e 100644 --- a/src/vs/workbench/contrib/testing/common/testCoverageService.ts +++ b/src/vs/workbench/contrib/testing/common/testCoverageService.ts @@ -85,7 +85,7 @@ export class TestCoverageService extends Disposable implements ITestCoverageServ this._isOpenKey.set(true); } catch (e) { if (!cts.token.isCancellationRequested) { - this.notificationService.error(localize('testCoverageError', 'Failed to load test coverage: {}', String(e))); + this.notificationService.error(localize('testCoverageError', 'Failed to load test coverage: {0}', String(e))); } return; } diff --git a/src/vs/workbench/contrib/testing/common/testTypes.ts b/src/vs/workbench/contrib/testing/common/testTypes.ts index 883b00fa5f9..3c57f2b0a53 100644 --- a/src/vs/workbench/contrib/testing/common/testTypes.ts +++ b/src/vs/workbench/contrib/testing/common/testTypes.ts @@ -571,12 +571,12 @@ export namespace IFileCoverage { uri: original.uri.toJSON(), }); - export const deserialize = (serialized: Serialized): IFileCoverage => ({ + export const deserialize = (uriIdentity: ITestUriCanonicalizer, serialized: Serialized): IFileCoverage => ({ statement: serialized.statement, branch: serialized.branch, function: serialized.function, details: serialized.details?.map(CoverageDetails.deserialize), - uri: URI.from(serialized.uri), + uri: uriIdentity.asCanonicalUri(URI.revive(serialized.uri)), }); } From 40f2a588ceae4b90f58882daf2e8605acf7f47bc Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Tue, 12 Dec 2023 17:53:31 +0000 Subject: [PATCH 68/80] Show the devcontainer label value specified in portsAttributes within the port notification instead of "your application" (#200667) Fixes #192684 --- .../contrib/remote/browser/remoteExplorer.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts index 0b2e539e42f..e45714ecbc8 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts @@ -385,8 +385,11 @@ class OnAutoForwardedAction extends Disposable { }); } - private basicMessage(tunnel: RemoteTunnel) { - return nls.localize('remote.tunnelsView.automaticForward', "Your application running on port {0} is available. ", + private async basicMessage(tunnel: RemoteTunnel) { + const properties = await this.remoteExplorerService.tunnelModel.getAttributes([{ host: tunnel.tunnelRemoteHost, port: tunnel.tunnelRemotePort }], false); + const label = properties?.get(tunnel.tunnelRemotePort)?.label; + return nls.localize('remote.tunnelsView.automaticForward', "Your application{0} running on port {1} is available. ", + label ? ` (${label})` : '', tunnel.tunnelRemotePort); } @@ -402,7 +405,7 @@ class OnAutoForwardedAction extends Disposable { } this.lastNotification?.close(); - let message = this.basicMessage(tunnel); + let message = await this.basicMessage(tunnel); const choices = [this.openBrowserChoice(tunnel)]; if (!isWeb || openPreviewEnabledContext.getValue(this.contextKeyService)) { choices.push(this.openPreviewChoice(tunnel)); @@ -481,7 +484,7 @@ class OnAutoForwardedAction extends Disposable { this.lastNotification?.close(); this.lastShownPort = newTunnel.tunnelRemotePort; this.lastNotification = this.notificationService.prompt(Severity.Info, - this.basicMessage(newTunnel) + this.linkMessage(), + await this.basicMessage(newTunnel) + this.linkMessage(), [this.openBrowserChoice(newTunnel), this.openPreviewChoice(tunnel)], { neverShowAgain: { id: 'remote.tunnelsView.autoForwardNeverShow', isSecondary: true } }); this.lastNotification.onDidClose(() => { From 61c287694312de77559284cb084367d1d024a45c Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Tue, 12 Dec 2023 10:55:13 -0800 Subject: [PATCH 69/80] default to showing notebook symbols in the goto view (#200670) --- .../contrib/notebook/browser/contrib/outline/notebookOutline.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts index 6caea2905b1..67ac4131d0d 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline.ts @@ -424,7 +424,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis }, [NotebookSetting.gotoSymbolsAllSymbols]: { type: 'boolean', - default: false, + default: true, markdownDescription: localize('notebook.gotoSymbols.showAllSymbols', "When enabled the Go to Symbol Quick Pick will display full code symbols from the notebook, as well as Markdown headers.") }, } From fec4c8e5bbfeca9c856017c4a9c714f3d69ab4f7 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 12 Dec 2023 11:39:31 -0800 Subject: [PATCH 70/80] Fix types on `CopyPasteController.get` (#200600) Fixes #200597 --- src/vs/editor/contrib/clipboard/browser/clipboard.ts | 2 +- .../contrib/dropOrPasteInto/browser/copyPasteController.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/clipboard/browser/clipboard.ts b/src/vs/editor/contrib/clipboard/browser/clipboard.ts index 08a834a6655..8ca27d4fbae 100644 --- a/src/vs/editor/contrib/clipboard/browser/clipboard.ts +++ b/src/vs/editor/contrib/clipboard/browser/clipboard.ts @@ -229,7 +229,7 @@ if (PasteAction) { if (focusedEditor && focusedEditor.hasTextFocus()) { const result = focusedEditor.getContainerDomNode().ownerDocument.execCommand('paste'); if (result) { - return CopyPasteController.get(focusedEditor).finishedPaste(); + return CopyPasteController.get(focusedEditor)?.finishedPaste() ?? Promise.resolve(); } else if (platform.isWeb) { // Use the clipboard service if document.execCommand('paste') was not successful return (async () => { diff --git a/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts b/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts index eba9b5f0f43..59281b6154e 100644 --- a/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts +++ b/src/vs/editor/contrib/dropOrPasteInto/browser/copyPasteController.ts @@ -51,8 +51,8 @@ export class CopyPasteController extends Disposable implements IEditorContributi public static readonly ID = 'editor.contrib.copyPasteActionController'; - public static get(editor: ICodeEditor): CopyPasteController { - return editor.getContribution(CopyPasteController.ID)!; + public static get(editor: ICodeEditor): CopyPasteController | null { + return editor.getContribution(CopyPasteController.ID); } private readonly _editor: ICodeEditor; From 1972a1847d722ea6e8ca256b1e4b539506b7cdd1 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Tue, 12 Dec 2023 11:55:58 -0800 Subject: [PATCH 71/80] chore: bump work notebook milestone (#200677) --- .vscode/notebooks/my-work.github-issues | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.vscode/notebooks/my-work.github-issues b/.vscode/notebooks/my-work.github-issues index 5de4a3e1144..c6e8ee4b20e 100644 --- a/.vscode/notebooks/my-work.github-issues +++ b/.vscode/notebooks/my-work.github-issues @@ -7,7 +7,7 @@ { "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\n// current milestone name\n$MILESTONE=milestone:\"November 2023\"\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\r\n// current milestone name\r\n$MILESTONE=milestone:\"December / January 2024\"\r\n" }, { "kind": 1, @@ -17,7 +17,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE assignee:@me is:open\n" + "value": "$REPOS $MILESTONE assignee:@me is:open\r\n" }, { "kind": 1, @@ -32,7 +32,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS assignee:@me is:open label:bug\n" + "value": "$REPOS assignee:@me is:open label:bug\r\n" }, { "kind": 1, @@ -42,7 +42,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS assignee:@me is:open label:debt,engineering\n" + "value": "$REPOS assignee:@me is:open label:debt,engineering\r\n" }, { "kind": 1, @@ -52,7 +52,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS assignee:@me is:open label:perf,perf-startup,perf-bloat,freeze-slow-crash-leak\n" + "value": "$REPOS assignee:@me is:open label:perf,perf-startup,perf-bloat,freeze-slow-crash-leak\r\n" }, { "kind": 1, @@ -62,12 +62,12 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS assignee:@me is:open label:feature-request milestone:Backlog sort:reactions-+1-desc\n" + "value": "$REPOS assignee:@me is:open label:feature-request milestone:Backlog sort:reactions-+1-desc\r\n" }, { "kind": 2, "language": "github-issues", - "value": "$REPOS assignee:@me is:open milestone:\"Backlog Candidates\"\n" + "value": "$REPOS assignee:@me is:open milestone:\"Backlog Candidates\"\r\n" }, { "kind": 1, @@ -82,7 +82,7 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode is:open assignee:@me label:triage-needed\n" + "value": "repo:microsoft/vscode is:open assignee:@me label:triage-needed\r\n" }, { "kind": 1, @@ -92,7 +92,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\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\r\n" }, { "kind": 1, @@ -112,7 +112,7 @@ { "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, @@ -122,7 +122,7 @@ { "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" }, { "kind": 1, @@ -137,7 +137,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS author:@me is:open is:pr review:approved\n" + "value": "$REPOS author:@me is:open is:pr review:approved\r\n" }, { "kind": 1, @@ -147,7 +147,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS author:@me is:open is:pr review:required\n" + "value": "$REPOS author:@me is:open is:pr review:required\r\n" }, { "kind": 1, @@ -157,6 +157,6 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS author:@me is:open is:pr review:changes_requested\n" + "value": "$REPOS author:@me is:open is:pr review:changes_requested\r\n" } ] \ No newline at end of file From 298b07637a190e4fdefdda788bd5a615e2d54bf3 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Tue, 12 Dec 2023 13:13:54 -0800 Subject: [PATCH 72/80] remove console log message (#200684) --- extensions/notebook-renderers/src/linkify.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/notebook-renderers/src/linkify.ts b/extensions/notebook-renderers/src/linkify.ts index c625c5fdba5..99760213d8b 100644 --- a/extensions/notebook-renderers/src/linkify.ts +++ b/extensions/notebook-renderers/src/linkify.ts @@ -57,7 +57,6 @@ export class LinkDetector { * and added as a child of the returned . */ linkify(text: string, options: LinkOptions, splitLines?: boolean): HTMLElement { - console.log('linkifyiiiiiing', JSON.stringify(options)); if (splitLines) { const lines = text.split('\n'); for (let i = 0; i < lines.length - 1; i++) { From 358f15fb9bbcd59d83984d9ffca6fdbd82ea5866 Mon Sep 17 00:00:00 2001 From: Simon Siefke Date: Wed, 13 Dec 2023 00:13:57 +0100 Subject: [PATCH 73/80] fix: memory leak when scrolling in notebook (#200447) * fix: memory leak when scrolling in notebook * remove unused code * remove unused code * remove unused code --- src/vs/platform/actions/browser/menuEntryActionViewItem.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index e0081e27068..15abc82b4be 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -381,11 +381,11 @@ export class DropdownWithDefaultActionViewItem extends BaseActionViewItem { }; this._dropdown = new DropdownMenuActionViewItem(submenuAction, submenuAction.actions, this._contextMenuService, dropdownOptions); - this._dropdown.actionRunner.onDidRun((e: IRunEvent) => { + this._register(this._dropdown.actionRunner.onDidRun((e: IRunEvent) => { if (e.action instanceof MenuItemAction) { this.update(e.action); } - }); + })); } private update(lastAction: MenuItemAction): void { From b5b6a80c1bca2ff29b79c545a25ee0fd69d4d38c Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 13 Dec 2023 02:19:46 +0100 Subject: [PATCH 74/80] auto save - treat `autoSaveWhenNoErrors` as `AutoSaveMode.AFTER_LONG_DELAY` (#200676) * auto save - treat `autoSaveWhenNoErrors` as `AutoSaveMode.AFTER_LONG_DELAY` * . --- .../browser/parts/editor/editorActions.ts | 4 +- .../browser/parts/editor/editorAutoSave.ts | 2 +- .../files/browser/editors/fileEditorInput.ts | 4 +- .../browser/editors/textFileEditorTracker.ts | 4 +- .../files/browser/views/openEditorsView.ts | 4 +- .../files/common/dirtyFilesIndicator.ts | 4 +- .../notebook/common/notebookEditorInput.ts | 4 +- .../search/browser/anythingQuickAccess.ts | 4 +- src/vs/workbench/electron-sandbox/window.ts | 4 +- .../common/filesConfigurationService.ts | 190 ++++++++++-------- .../test/common/workbenchTestServices.ts | 1 + 11 files changed, 120 insertions(+), 105 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 1c4bc5a1de5..d85ed1ac82d 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -605,14 +605,14 @@ abstract class AbstractCloseAllAction extends Action2 { // Editor will be saved on focus change when a // dialog appears, so just track that separate - else if (filesConfigurationService.getAutoSaveMode(editor) === AutoSaveMode.ON_FOCUS_CHANGE && !editor.hasCapability(EditorInputCapabilities.Untitled)) { + else if (!editor.hasCapability(EditorInputCapabilities.Untitled) && filesConfigurationService.getAutoSaveMode(editor) === AutoSaveMode.ON_FOCUS_CHANGE) { dirtyAutoSaveOnFocusChangeEditors.add({ editor, groupId }); } // Windows, Linux: editor will be saved on window change // when a native dialog appears, so just track that separate // (see https://github.com/microsoft/vscode/issues/134250) - else if ((isNative && (isWindows || isLinux)) && filesConfigurationService.getAutoSaveMode(editor) === AutoSaveMode.ON_WINDOW_CHANGE && !editor.hasCapability(EditorInputCapabilities.Untitled)) { + else if ((isNative && (isWindows || isLinux)) && !editor.hasCapability(EditorInputCapabilities.Untitled) && filesConfigurationService.getAutoSaveMode(editor) === AutoSaveMode.ON_WINDOW_CHANGE) { dirtyAutoSaveOnWindowChangeEditors.add({ editor, groupId }); } diff --git a/src/vs/workbench/browser/parts/editor/editorAutoSave.ts b/src/vs/workbench/browser/parts/editor/editorAutoSave.ts index 2a46e06fe18..dbeecadc665 100644 --- a/src/vs/workbench/browser/parts/editor/editorAutoSave.ts +++ b/src/vs/workbench/browser/parts/editor/editorAutoSave.ts @@ -90,7 +90,7 @@ export class EditorAutoSave extends Disposable implements IWorkbenchContribution } } - private maybeTriggerAutoSave(reason: SaveReason, editorIdentifier?: IEditorIdentifier): void { + private maybeTriggerAutoSave(reason: SaveReason.WINDOW_CHANGE | SaveReason.FOCUS_CHANGE, editorIdentifier?: IEditorIdentifier): void { if (editorIdentifier) { if ( !editorIdentifier.editor.isDirty() || diff --git a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts index 27bd12ecde4..210542f1d71 100644 --- a/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts +++ b/src/vs/workbench/contrib/files/browser/editors/fileEditorInput.ts @@ -16,7 +16,7 @@ import { IReference, dispose, DisposableStore } from 'vs/base/common/lifecycle'; import { ITextModelService } from 'vs/editor/common/services/resolverService'; import { FILE_EDITOR_INPUT_ID, TEXT_FILE_EDITOR_ID, BINARY_FILE_EDITOR_ID } from 'vs/workbench/contrib/files/common/files'; import { ILabelService } from 'vs/platform/label/common/label'; -import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { isEqual } from 'vs/base/common/resources'; import { Event } from 'vs/base/common/event'; @@ -318,7 +318,7 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements // and it could result in bad UX where an editor can be closed even though // it shows up as dirty and has not finished saving yet. - if (this.filesConfigurationService.getAutoSaveMode(this) === AutoSaveMode.AFTER_SHORT_DELAY) { + if (this.filesConfigurationService.isShortAutoSaveDelayConfigured(this)) { return true; // a short auto save is configured, treat this as being saved } diff --git a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts index a007ccd3f0a..89bc7247633 100644 --- a/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts +++ b/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.ts @@ -13,7 +13,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { RunOnceWorker } from 'vs/base/common/async'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { FILE_EDITOR_INPUT_ID } from 'vs/workbench/contrib/files/common/files'; import { Schemas } from 'vs/base/common/network'; import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; @@ -69,7 +69,7 @@ export class TextFileEditorTracker extends Disposable implements IWorkbenchContr return false; // resource must not be pending to save } - if (resource.scheme !== Schemas.untitled && this.filesConfigurationService.getAutoSaveMode(resource) === AutoSaveMode.AFTER_SHORT_DELAY && !fileModel?.hasState(TextFileEditorModelState.ERROR)) { + if (resource.scheme !== Schemas.untitled && !fileModel?.hasState(TextFileEditorModelState.ERROR) && this.filesConfigurationService.isShortAutoSaveDelayConfigured(resource)) { // leave models auto saved after short delay unless // the save resulted in an error and not for untitled // that are not auto-saved anyway diff --git a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts index ff0d15555ed..b2d1f3df98a 100644 --- a/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts +++ b/src/vs/workbench/contrib/files/browser/views/openEditorsView.ts @@ -39,7 +39,7 @@ import { memoize } from 'vs/base/common/decorators'; import { ElementsDragAndDropData, NativeDragAndDropData } from 'vs/base/browser/ui/list/listView'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IWorkingCopy, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopy'; -import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IViewDescriptorService } from 'vs/workbench/common/views'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { Orientation } from 'vs/base/browser/ui/splitview/splitview'; @@ -460,7 +460,7 @@ export class OpenEditorsView extends ViewPane { private updateDirtyIndicator(workingCopy?: IWorkingCopy): void { if (workingCopy) { const gotDirty = workingCopy.isDirty(); - if (gotDirty && !(workingCopy.capabilities & WorkingCopyCapabilities.Untitled) && this.filesConfigurationService.getAutoSaveMode(workingCopy.resource) === AutoSaveMode.AFTER_SHORT_DELAY) { + if (gotDirty && !(workingCopy.capabilities & WorkingCopyCapabilities.Untitled) && this.filesConfigurationService.isShortAutoSaveDelayConfigured(workingCopy.resource)) { return; // do not indicate dirty of working copies that are auto saved after short delay } } diff --git a/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts index a47b38b7521..dc28ee8d9ed 100644 --- a/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts +++ b/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.ts @@ -11,7 +11,7 @@ import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService'; import { IWorkingCopy, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopy'; -import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; export class DirtyFilesIndicator extends Disposable implements IWorkbenchContribution { private readonly badgeHandle = this._register(new MutableDisposable()); @@ -42,7 +42,7 @@ export class DirtyFilesIndicator extends Disposable implements IWorkbenchContrib private onWorkingCopyDidChangeDirty(workingCopy: IWorkingCopy): void { const gotDirty = workingCopy.isDirty(); - if (gotDirty && !(workingCopy.capabilities & WorkingCopyCapabilities.Untitled) && this.filesConfigurationService.getAutoSaveMode(workingCopy.resource) === AutoSaveMode.AFTER_SHORT_DELAY) { + if (gotDirty && !(workingCopy.capabilities & WorkingCopyCapabilities.Untitled) && this.filesConfigurationService.isShortAutoSaveDelayConfigured(workingCopy.resource)) { return; // do not indicate dirty of working copies that are auto saved after short delay } diff --git a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts index d2bddd601c3..7add5409fe2 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookEditorInput.ts @@ -24,7 +24,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { IWorkingCopyIdentifier } from 'vs/workbench/services/workingCopy/common/workingCopy'; import { NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider'; import { NotebookPerfMarks } from 'vs/workbench/contrib/notebook/common/notebookPerformance'; -import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { localize } from 'vs/nls'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; @@ -181,7 +181,7 @@ export class NotebookEditorInput extends AbstractResourceEditorInput { } // if a short auto save is configured, treat this as being saved - return this.filesConfigurationService.getAutoSaveMode(this) === AutoSaveMode.AFTER_SHORT_DELAY; + return this.filesConfigurationService.isShortAutoSaveDelayConfigured(this); } override async save(group: GroupIdentifier, options?: ISaveOptions): Promise { diff --git a/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts b/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts index 4d1b57f4b97..95387f053bd 100644 --- a/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/anythingQuickAccess.ts @@ -37,7 +37,7 @@ import { FileQueryCacheState } from 'vs/workbench/contrib/search/common/cacheSta import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IEditorOptions, IResourceEditorInput, ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { Schemas } from 'vs/base/common/network'; -import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; +import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; import { ResourceMap } from 'vs/base/common/map'; import { SymbolsQuickAccessProvider } from 'vs/workbench/contrib/search/browser/symbolsQuickAccess'; import { AnythingQuickAccessProviderRunOptions, DefaultQuickAccessFilterValue, Extensions, IQuickAccessRegistry } from 'vs/platform/quickinput/common/quickAccess'; @@ -963,7 +963,7 @@ export class AnythingQuickAccessProvider extends PickerQuickAccessProvider { const gotDirty = workingCopy.isDirty(); - if (gotDirty && !(workingCopy.capabilities & WorkingCopyCapabilities.Untitled) && this.filesConfigurationService.getAutoSaveMode(workingCopy.resource) === AutoSaveMode.AFTER_SHORT_DELAY) { + if (gotDirty && !(workingCopy.capabilities & WorkingCopyCapabilities.Untitled) && this.filesConfigurationService.isShortAutoSaveDelayConfigured(workingCopy.resource)) { return; // do not indicate dirty of working copies that are auto saved after short delay } diff --git a/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts b/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts index f2fdb93492f..0a226c4f592 100644 --- a/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts +++ b/src/vs/workbench/services/filesConfiguration/common/filesConfigurationService.ts @@ -30,9 +30,9 @@ import { IStringDictionary } from 'vs/base/common/collections'; export const AutoSaveAfterShortDelayContext = new RawContextKey('autoSaveAfterShortDelayContext', false, true); export interface IAutoSaveConfiguration { + autoSave?: 'afterDelay' | 'onFocusChange' | 'onWindowChange'; autoSaveDelay?: number; - autoSaveFocusChange?: boolean; - autoSaveApplicationChange?: boolean; + autoSaveWorkspaceFilesOnly?: boolean; autoSaveWhenNoErrors?: boolean; } @@ -54,9 +54,11 @@ export interface IFilesConfigurationService { readonly onDidChangeAutoSaveConfiguration: Event; - getAutoSaveConfiguration(resourceoOrEditor: EditorInput | URI | undefined): IAutoSaveConfiguration; + getAutoSaveConfiguration(resourceOrEditor: EditorInput | URI | undefined): IAutoSaveConfiguration; - getAutoSaveMode(resourceoOrEditor: EditorInput | URI | undefined): AutoSaveMode; + isShortAutoSaveDelayConfigured(resourceOrEditor: EditorInput | URI | undefined): boolean; + + getAutoSaveMode(resourceOrEditor: EditorInput | URI | undefined): AutoSaveMode; toggleAutoSave(): Promise; @@ -133,7 +135,7 @@ export class FilesConfigurationService extends Disposable implements IFilesConfi const configuration = configurationService.getValue(); - this.currentGlobalAutoSaveConfiguration = this.computeAutoSaveConfiguration(undefined, configuration.files); + this.currentGlobalAutoSaveConfiguration = this.computeAutoSaveConfiguration(configuration.files); this.currentFilesAssociationConfiguration = configuration?.files?.associations; this.currentHotExitConfiguration = configuration?.files?.hotExit || HotExitConfiguration.ON_EXIT; @@ -240,7 +242,7 @@ export class FilesConfigurationService extends Disposable implements IFilesConfi protected onFilesConfigurationChange(configuration: IFilesConfiguration, fromEvent: boolean): void { // Auto Save - this.currentGlobalAutoSaveConfiguration = this.computeAutoSaveConfiguration(undefined, configuration.files); + this.currentGlobalAutoSaveConfiguration = this.computeAutoSaveConfiguration(configuration.files); this.autoSaveConfigurationCache.clear(); this.autoSaveAfterShortDelayContext.set(this.getAutoSaveMode(undefined) === AutoSaveMode.AFTER_SHORT_DELAY); if (fromEvent) { @@ -274,93 +276,12 @@ export class FilesConfigurationService extends Disposable implements IFilesConfi } } - private computeAutoSaveConfiguration( - resource: URI | undefined = undefined, - filesConfiguration: IFilesConfigurationNode - ): IAutoSaveConfiguration { - let autoSaveDelay: number | undefined; - let autoSaveFocusChange: boolean | undefined; - let autoSaveApplicationChange: boolean | undefined; - - switch (filesConfiguration.autoSave ?? FilesConfigurationService.DEFAULT_AUTO_SAVE_MODE) { - case AutoSaveConfiguration.AFTER_DELAY: - autoSaveDelay = typeof filesConfiguration.autoSaveDelay === 'number' ? filesConfiguration.autoSaveDelay : FilesConfigurationService.DEFAULT_AUTO_SAVE_DELAY; - autoSaveFocusChange = undefined; - autoSaveApplicationChange = undefined; - break; - - case AutoSaveConfiguration.ON_FOCUS_CHANGE: - autoSaveDelay = undefined; - autoSaveFocusChange = true; - autoSaveApplicationChange = undefined; - break; - - case AutoSaveConfiguration.ON_WINDOW_CHANGE: - autoSaveDelay = undefined; - autoSaveFocusChange = undefined; - autoSaveApplicationChange = true; - break; - - default: - autoSaveDelay = undefined; - autoSaveFocusChange = undefined; - autoSaveApplicationChange = undefined; - break; - } - - if (typeof autoSaveDelay === 'number' || autoSaveFocusChange || autoSaveApplicationChange) { - if ( - (filesConfiguration.autoSaveWorkspaceFilesOnly && resource && !this.contextService.isInsideWorkspace(resource)) || - (filesConfiguration.autoSaveWhenNoErrors && resource && this.markerService.read({ resource, take: 1, severities: MarkerSeverity.Error }).length > 0) - ) { - autoSaveDelay = undefined; - autoSaveFocusChange = undefined; - autoSaveApplicationChange = undefined; - } - } - - const autoSaveConfiguration: IAutoSaveConfiguration = Object.create(null); - if (typeof autoSaveDelay === 'number') { - autoSaveConfiguration.autoSaveDelay = autoSaveDelay; - } - if (typeof autoSaveFocusChange === 'boolean') { - autoSaveConfiguration.autoSaveFocusChange = autoSaveFocusChange; - } - if (typeof autoSaveApplicationChange === 'boolean') { - autoSaveConfiguration.autoSaveApplicationChange = autoSaveApplicationChange; - } - if (filesConfiguration.autoSaveWhenNoErrors) { - autoSaveConfiguration.autoSaveWhenNoErrors = true; - } - - return autoSaveConfiguration; - } - - getAutoSaveMode(resourceOrEditor: EditorInput | URI | undefined): AutoSaveMode { - const autoSaveConfiguration = this.getAutoSaveConfiguration(resourceOrEditor); - if (autoSaveConfiguration?.autoSaveFocusChange) { - return AutoSaveMode.ON_FOCUS_CHANGE; - } - - if (autoSaveConfiguration?.autoSaveApplicationChange) { - return AutoSaveMode.ON_WINDOW_CHANGE; - } - - if (typeof autoSaveConfiguration?.autoSaveDelay === 'number' && autoSaveConfiguration?.autoSaveDelay >= 0) { - return autoSaveConfiguration?.autoSaveDelay <= FilesConfigurationService.DEFAULT_AUTO_SAVE_DELAY ? AutoSaveMode.AFTER_SHORT_DELAY : AutoSaveMode.AFTER_LONG_DELAY; - } - - return AutoSaveMode.OFF; - } - getAutoSaveConfiguration(resourceOrEditor: EditorInput | URI | undefined): IAutoSaveConfiguration { const resource = this.toResource(resourceOrEditor); if (resource) { let resourceAutoSaveConfiguration = this.autoSaveConfigurationCache.get(resource); if (!resourceAutoSaveConfiguration) { - const resourcesFilesConfiguration = this.textResourceConfigurationService.getValue(resource, 'files'); - resourceAutoSaveConfiguration = this.computeAutoSaveConfiguration(resource, resourcesFilesConfiguration); - + resourceAutoSaveConfiguration = this.computeAutoSaveConfiguration(this.textResourceConfigurationService.getValue(resource, 'files')); this.autoSaveConfigurationCache.set(resource, resourceAutoSaveConfiguration); } @@ -370,6 +291,44 @@ export class FilesConfigurationService extends Disposable implements IFilesConfi return this.currentGlobalAutoSaveConfiguration; } + private computeAutoSaveConfiguration(filesConfiguration: IFilesConfigurationNode): IAutoSaveConfiguration { + let autoSave: 'afterDelay' | 'onFocusChange' | 'onWindowChange' | undefined; + let autoSaveDelay: number | undefined; + let autoSaveWorkspaceFilesOnly: boolean | undefined; + let autoSaveWhenNoErrors: boolean | undefined; + + switch (filesConfiguration.autoSave ?? FilesConfigurationService.DEFAULT_AUTO_SAVE_MODE) { + case AutoSaveConfiguration.AFTER_DELAY: { + autoSave = 'afterDelay'; + autoSaveDelay = typeof filesConfiguration.autoSaveDelay === 'number' && filesConfiguration.autoSaveDelay >= 0 ? filesConfiguration.autoSaveDelay : FilesConfigurationService.DEFAULT_AUTO_SAVE_DELAY; + break; + } + + case AutoSaveConfiguration.ON_FOCUS_CHANGE: + autoSave = 'onFocusChange'; + break; + + case AutoSaveConfiguration.ON_WINDOW_CHANGE: + autoSave = 'onWindowChange'; + break; + } + + if (filesConfiguration.autoSaveWorkspaceFilesOnly === true) { + autoSaveWorkspaceFilesOnly = true; + } + + if (filesConfiguration.autoSaveWhenNoErrors === true) { + autoSaveWhenNoErrors = true; + } + + return { + autoSave, + autoSaveDelay, + autoSaveWorkspaceFilesOnly, + autoSaveWhenNoErrors + }; + } + private toResource(resourceOrEditor: EditorInput | URI | undefined): URI | undefined { if (resourceOrEditor instanceof EditorInput) { return EditorResourceAccessor.getOriginalUri(resourceOrEditor, { supportSideBySide: SideBySideEditor.PRIMARY }); @@ -378,6 +337,61 @@ export class FilesConfigurationService extends Disposable implements IFilesConfi return resourceOrEditor; } + isShortAutoSaveDelayConfigured(resourceOrEditor: EditorInput | URI | undefined): boolean { + const autoSaveConfiguration = this.getAutoSaveConfiguration(resourceOrEditor); + if ( + autoSaveConfiguration.autoSave !== 'afterDelay' || + typeof autoSaveConfiguration.autoSaveDelay !== 'number' || + autoSaveConfiguration.autoSaveDelay > FilesConfigurationService.DEFAULT_AUTO_SAVE_DELAY || + autoSaveConfiguration.autoSaveWhenNoErrors + ) { + // We can avoid the call to `doGetAutoSaveMode` by checking + // the configuration for some properties that clearly indicate + // that the short auto save delay cannot apply. + return false; + } + + return this.doGetAutoSaveMode(resourceOrEditor, autoSaveConfiguration) === AutoSaveMode.AFTER_SHORT_DELAY; + } + + getAutoSaveMode(resourceOrEditor: EditorInput | URI | undefined): AutoSaveMode { + return this.doGetAutoSaveMode(resourceOrEditor, this.getAutoSaveConfiguration(resourceOrEditor)); + } + + private doGetAutoSaveMode(resourceOrEditor: EditorInput | URI | undefined, autoSaveConfiguration: IAutoSaveConfiguration): AutoSaveMode { + if (typeof autoSaveConfiguration.autoSave === 'undefined') { + return AutoSaveMode.OFF; + } + + const resource = this.toResource(resourceOrEditor); + if (resource) { + if (autoSaveConfiguration.autoSaveWorkspaceFilesOnly && !this.contextService.isInsideWorkspace(resource)) { + return AutoSaveMode.OFF; + } + + if (autoSaveConfiguration.autoSaveWhenNoErrors && this.markerService.read({ resource, take: 1, severities: MarkerSeverity.Error }).length > 0) { + return AutoSaveMode.OFF; + } + } + + switch (autoSaveConfiguration.autoSave) { + case 'afterDelay': + if (typeof autoSaveConfiguration.autoSaveDelay === 'number' && autoSaveConfiguration.autoSaveDelay <= FilesConfigurationService.DEFAULT_AUTO_SAVE_DELAY) { + // Explicitly mark auto save configurations as long running + // if they are configured to not run when there are errors. + // The rationale here is that errors may come in after auto + // save has been scheduled and then further delay the auto + // save until resolved. + return autoSaveConfiguration.autoSaveWhenNoErrors ? AutoSaveMode.AFTER_LONG_DELAY : AutoSaveMode.AFTER_SHORT_DELAY; + } + return AutoSaveMode.AFTER_LONG_DELAY; + case 'onFocusChange': + return AutoSaveMode.ON_FOCUS_CHANGE; + case 'onWindowChange': + return AutoSaveMode.ON_WINDOW_CHANGE; + } + } + async toggleAutoSave(): Promise { const currentSetting = this.configurationService.getValue('files.autoSave'); diff --git a/src/vs/workbench/test/common/workbenchTestServices.ts b/src/vs/workbench/test/common/workbenchTestServices.ts index 1da814d83db..8e11e49cb86 100644 --- a/src/vs/workbench/test/common/workbenchTestServices.ts +++ b/src/vs/workbench/test/common/workbenchTestServices.ts @@ -319,6 +319,7 @@ export const NullFilesConfigurationService = new class implements IFilesConfigur getAutoSaveConfiguration(): IAutoSaveConfiguration { throw new Error('Method not implemented.'); } getAutoSaveMode(): AutoSaveMode { throw new Error('Method not implemented.'); } + isShortAutoSaveDelayConfigured(): boolean { throw new Error('Method not implemented.'); } toggleAutoSave(): Promise { throw new Error('Method not implemented.'); } isReadonly(resource: URI, stat?: IBaseFileStat | undefined): boolean { return false; } async updateReadonly(resource: URI, readonly: boolean | 'toggle' | 'reset'): Promise { } From 948f6a1aafeba94e605f5ba0f0a5bda33ea61a00 Mon Sep 17 00:00:00 2001 From: Isabel Duan Date: Tue, 12 Dec 2023 17:23:10 -0800 Subject: [PATCH 75/80] fix typescript/54492: check if file rename changes extension (#200220) check if file extension has been changed --- .../src/languageFeatures/rename.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extensions/typescript-language-features/src/languageFeatures/rename.ts b/extensions/typescript-language-features/src/languageFeatures/rename.ts index 3dcca16f5b2..19dc5b93c99 100644 --- a/extensions/typescript-language-features/src/languageFeatures/rename.ts +++ b/extensions/typescript-language-features/src/languageFeatures/rename.ts @@ -85,7 +85,7 @@ class TypeScriptRenameProvider implements vscode.RenameProvider { } if (renameInfo.fileToRename) { - const edits = await this.renameFile(renameInfo.fileToRename, newName, token); + const edits = await this.renameFile(renameInfo.fileToRename, renameInfo.fullDisplayName, newName, token); if (edits) { return edits; } else { @@ -170,13 +170,17 @@ class TypeScriptRenameProvider implements vscode.RenameProvider { private async renameFile( fileToRename: string, + fullDisplayName: string, newName: string, token: vscode.CancellationToken, ): Promise { - // Make sure we preserve file extension if none provided + // Make sure we preserve file extension if extension is unchanged or none provided if (!path.extname(newName)) { newName += path.extname(fileToRename); } + else if (path.extname(newName) === path.extname(fullDisplayName)) { + newName = newName.slice(0, newName.length - path.extname(newName).length) + path.extname(fileToRename); + } const dirname = path.dirname(fileToRename); const newFilePath = path.join(dirname, newName); From 6ef5ce0108f782ff3e78f91b35cdea304872f16f Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 12 Dec 2023 17:29:24 -0800 Subject: [PATCH 76/80] testing: fix explorer input uses wrong background color (#200699) Sidebar has styling that sets the monaco editor background color. Fixes #198301 --- .../browser/suggestEnabledInput/suggestEnabledInput.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.css b/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.css index 299f2e37e3a..0c378f88922 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.css +++ b/src/vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput.css @@ -26,5 +26,5 @@ .suggest-input-container .monaco-editor, .suggest-input-container .monaco-editor .lines-content { - background: none; + background: none !important; } From 2fb2fe81e9a0b89f49c4619d31298220b577546a Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Tue, 12 Dec 2023 17:42:44 -0800 Subject: [PATCH 77/80] Update keybinding label css for action widget (#200700) changed keybinding css to match quick pick --- src/vs/platform/actionWidget/browser/actionWidget.css | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vs/platform/actionWidget/browser/actionWidget.css b/src/vs/platform/actionWidget/browser/actionWidget.css index 91c30bdab12..2354e1af5cd 100644 --- a/src/vs/platform/actionWidget/browser/actionWidget.css +++ b/src/vs/platform/actionWidget/browser/actionWidget.css @@ -110,6 +110,17 @@ text-overflow: ellipsis; } +.action-widget .monaco-list-row.action .monaco-keybinding > .monaco-keybinding-key { + background-color: var(--vscode-keybindingLabel-background); + color: var(--vscode-keybindingLabel-foreground); + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: var(--vscode-keybindingLabel-border); + border-bottom-color: var(--vscode-keybindingLabel-bottomBorder); + box-shadow: inset 0 -1px 0 var(--vscode-widget-shadow); +} + /* Action bar */ .action-widget .action-widget-action-bar { From 27da9227bfb9c3dc0df3af8c47da72807cf97de6 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 13 Dec 2023 08:09:56 +0100 Subject: [PATCH 78/80] Refactor menu's css seems missing (#198881) (#200711) --- src/vs/base/browser/ui/contextview/contextview.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index 60eed5be4a8..239cc4171a2 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -159,8 +159,8 @@ export class ContextView extends Disposable { const usedShadowDOM = this.useShadowDOM; this.useShadowDOM = domPosition === ContextViewDOMPosition.FIXED_SHADOW; - if (container === this.container && usedShadowDOM !== this.useShadowDOM) { - return; // container is the same and now shadow DOM usage has changed + if (container === this.container && usedShadowDOM === this.useShadowDOM) { + return; // container is the same and no shadow DOM usage has changed } if (this.container) { From f87fb292c3af22e51a7f5c628496cd8d6fd9ecd5 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 13 Dec 2023 16:27:54 +0900 Subject: [PATCH 79/80] ci: fix missing auth token for cli build (#200714) --- build/azure-pipelines/cli/cli-compile-and-publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/azure-pipelines/cli/cli-compile-and-publish.yml b/build/azure-pipelines/cli/cli-compile-and-publish.yml index 0fd3abfd6d8..4f0623b84fc 100644 --- a/build/azure-pipelines/cli/cli-compile-and-publish.yml +++ b/build/azure-pipelines/cli/cli-compile-and-publish.yml @@ -64,6 +64,7 @@ steps: env: CARGO_NET_GIT_FETCH_WITH_CLI: true VSCODE_CLI_COMMIT: $(Build.SourceVersion) + GITHUB_TOKEN: "$(github-distro-mixin-password)" ${{ each pair in parameters.VSCODE_CLI_ENV }}: ${{ pair.key }}: ${{ pair.value }} From 5da45d17d14a7e159a72a594198535112baa9298 Mon Sep 17 00:00:00 2001 From: Benjamin Simmonds <44439583+benibenj@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:32:59 +0100 Subject: [PATCH 80/80] remove highlight for panel (#200717) --- src/vs/workbench/browser/parts/paneCompositePart.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/paneCompositePart.ts b/src/vs/workbench/browser/parts/paneCompositePart.ts index a534c3492e0..df6b3d312d9 100644 --- a/src/vs/workbench/browser/parts/paneCompositePart.ts +++ b/src/vs/workbench/browser/parts/paneCompositePart.ts @@ -306,7 +306,6 @@ export abstract class AbstractPaneCompositePart extends CompositePart this.keybindingService.lookupKeybinding(action.id), anchorAlignmentProvider: () => this.getTitleAreaDropDownAnchorAlignment(), - highlightToggledItems: true, toggleMenuTitle: localize('moreActions', "More Actions...") }));