From 13ac4f2de288322b1fd31415e3a0b8c9bc43ea07 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 27 Sep 2024 09:58:39 -0700 Subject: [PATCH 01/27] node-pty@1.1.0-beta22 Brings back fix that was reverted for #75141 --- package-lock.json | 8 ++++---- package.json | 2 +- remote/package-lock.json | 8 ++++---- remote/package.json | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9b1e05da4fe0f..eba45e7f70782 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "open": "^8.4.2", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", @@ -13520,9 +13520,9 @@ } }, "node_modules/node-pty": { - "version": "1.1.0-beta21", - "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta21.tgz", - "integrity": "sha512-FYpnY9g8qMQLTpqyeY9NVli6YfCWwvG6v6gmaDBbPjlc1VMp/+Zivq0SStDrRr1aciGnFCZzpL0BzdMnmbDnAw==", + "version": "1.1.0-beta22", + "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta22.tgz", + "integrity": "sha512-CpT334H2oAIULlENvd9U+VBW4ZL+G3clOnpXYzUIurlPCLnl/9xen/KDHBLRcwhZuWcHxIrsCxR1TDCdVDtr0w==", "hasInstallScript": true, "dependencies": { "node-addon-api": "^7.1.0" diff --git a/package.json b/package.json index abe31e186bf95..d3645e40ac1af 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "open": "^8.4.2", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", diff --git a/remote/package-lock.json b/remote/package-lock.json index 58725751af9ee..eb3933f95b9b8 100644 --- a/remote/package-lock.json +++ b/remote/package-lock.json @@ -35,7 +35,7 @@ "kerberos": "2.1.1", "minimist": "^1.2.6", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", @@ -748,9 +748,9 @@ } }, "node_modules/node-pty": { - "version": "1.1.0-beta21", - "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta21.tgz", - "integrity": "sha512-FYpnY9g8qMQLTpqyeY9NVli6YfCWwvG6v6gmaDBbPjlc1VMp/+Zivq0SStDrRr1aciGnFCZzpL0BzdMnmbDnAw==", + "version": "1.1.0-beta22", + "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta22.tgz", + "integrity": "sha512-CpT334H2oAIULlENvd9U+VBW4ZL+G3clOnpXYzUIurlPCLnl/9xen/KDHBLRcwhZuWcHxIrsCxR1TDCdVDtr0w==", "hasInstallScript": true, "dependencies": { "node-addon-api": "^7.1.0" diff --git a/remote/package.json b/remote/package.json index c107b048e45c0..8438309e46d65 100644 --- a/remote/package.json +++ b/remote/package.json @@ -30,7 +30,7 @@ "kerberos": "2.1.1", "minimist": "^1.2.6", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", From 71cabbe74c99fb5da97661e11f1a3f4c1a833632 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 27 Sep 2024 10:40:35 -0700 Subject: [PATCH 02/27] Startup perf don't await pty host connection on web Fixes #229944 --- .../workbench/contrib/performance/browser/perfviewEditor.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts index 5592e4db6c93e..d8fa3638e55dc 100644 --- a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts @@ -30,6 +30,7 @@ import { ITextResourceConfigurationService } from '../../../../editor/common/ser import { Registry } from '../../../../platform/registry/common/platform.js'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, getWorkbenchContribution } from '../../../common/contributions.js'; import { ICustomEditorLabelService } from '../../../services/editor/common/customEditorLabelService.js'; +import { IRemoteAgentService } from '../../../services/remote/common/remoteAgentService.js'; export class PerfviewContrib { @@ -111,6 +112,7 @@ class PerfModelContentProvider implements ITextModelContentProvider { @ITimerService private readonly _timerService: ITimerService, @IExtensionService private readonly _extensionService: IExtensionService, @IProductService private readonly _productService: IProductService, + @IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService, @ITerminalService private readonly _terminalService: ITerminalService ) { } @@ -138,7 +140,8 @@ class PerfModelContentProvider implements ITextModelContentProvider { this._timerService.whenReady(), this._lifecycleService.when(LifecyclePhase.Eventually), this._extensionService.whenInstalledExtensionsRegistered(), - this._terminalService.whenConnected + // The terminal service never connects to the pty host on the web + isWeb && this._remoteAgentService.getConnection() === null ? Promise.resolve() : this._terminalService.whenConnected ]).then(() => { if (this._model && !this._model.isDisposed()) { From e57ad41cfeb0aaa1d1155fd7fe866f1be6f481b1 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 27 Sep 2024 12:00:03 -0700 Subject: [PATCH 03/27] Limit top level functions in notebook webview preloads (#229998) --- .eslintplugin/code-limited-top-functions.ts | 70 +++++++++++++++++++++ .eslintrc.json | 9 +++ 2 files changed, 79 insertions(+) create mode 100644 .eslintplugin/code-limited-top-functions.ts diff --git a/.eslintplugin/code-limited-top-functions.ts b/.eslintplugin/code-limited-top-functions.ts new file mode 100644 index 0000000000000..97eef9a6e9d78 --- /dev/null +++ b/.eslintplugin/code-limited-top-functions.ts @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as eslint from 'eslint'; +import { dirname, relative } from 'path'; +import minimatch from 'minimatch'; + +export = new class implements eslint.Rule.RuleModule { + + readonly meta: eslint.Rule.RuleMetaData = { + messages: { + layerbreaker: 'You are only allowed to define limited top level functions.' + }, + schema: { + type: "array", + items: { + type: "object", + additionalProperties: { + type: "array", + items: { + type: "string" + } + } + } + } + }; + + create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener { + let fileRelativePath = relative(dirname(__dirname), context.getFilename()); + if (!fileRelativePath.endsWith('/')) { + fileRelativePath += '/'; + } + const ruleArgs = >context.options[0]; + + const matchingKey = Object.keys(ruleArgs).find(key => fileRelativePath.startsWith(key) || minimatch(fileRelativePath, key)); + if (!matchingKey) { + // nothing + return {}; + } + + const restrictedFunctions = ruleArgs[matchingKey]; + + return { + FunctionDeclaration: (node: any) => { + const isTopLevel = node.parent.type === 'Program'; + const functionName = node.id.name; + if (isTopLevel && !restrictedFunctions.includes(node.id.name)) { + context.report({ + node, + message: `Top-level function '${functionName}' is restricted in this file. Allowed functions are: ${restrictedFunctions.join(', ')}.` + }); + } + }, + ExportNamedDeclaration(node: any) { + if (node.declaration && node.declaration.type === 'FunctionDeclaration') { + const functionName = node.declaration.id.name; + const isTopLevel = node.parent.type === 'Program'; + if (isTopLevel && !restrictedFunctions.includes(node.declaration.id.name)) { + context.report({ + node, + message: `Top-level function '${functionName}' is restricted in this file. Allowed functions are: ${restrictedFunctions.join(', ')}.` + }); + } + } + } + } + } +}; diff --git a/.eslintrc.json b/.eslintrc.json index e5294d9351cd3..27a94df6dcce2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1203,6 +1203,15 @@ "**/*" ] } + ], + "local/code-limited-top-functions": [ + "error", + { + "src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts": [ + "webviewPreloads", + "preloadsScriptStr" + ] + } ] } } From 2192418b5d3712b7db59eae7d865e616c4b2838b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 27 Sep 2024 12:11:27 -0700 Subject: [PATCH 04/27] Get correct mouse cursor y regardless of MouseEvent.target Fixes #229965 --- .../commandGuide/browser/terminal.commandGuide.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts b/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts index 7051364ea44ff..a3735285f8573 100644 --- a/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts @@ -80,7 +80,7 @@ class TerminalCommandGuideContribution extends Disposable implements ITerminalCo if (!rect) { return; } - const mouseCursorY = Math.floor(e.offsetY / (rect.height / xterm.raw.rows)); + const mouseCursorY = Math.floor((e.clientY - rect.top) / (rect.height / xterm.raw.rows)); const command = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.getCommandForLine(xterm.raw.buffer.active.viewportY + mouseCursorY); if (command && 'getOutput' in command) { xterm.markTracker.showCommandGuide(command); From ad90d1a20760d466bc7313bec99793a67dea5ab0 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 27 Sep 2024 12:13:35 -0700 Subject: [PATCH 05/27] Prefer remoteAuthority check over remote agent null Follow up on #229944, see #229992 --- src/vs/workbench/contrib/performance/browser/perfviewEditor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts index d8fa3638e55dc..37559fe0aa3ee 100644 --- a/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts +++ b/src/vs/workbench/contrib/performance/browser/perfviewEditor.ts @@ -141,7 +141,7 @@ class PerfModelContentProvider implements ITextModelContentProvider { this._lifecycleService.when(LifecyclePhase.Eventually), this._extensionService.whenInstalledExtensionsRegistered(), // The terminal service never connects to the pty host on the web - isWeb && this._remoteAgentService.getConnection() === null ? Promise.resolve() : this._terminalService.whenConnected + isWeb && !this._remoteAgentService.getConnection()?.remoteAuthority ? Promise.resolve() : this._terminalService.whenConnected ]).then(() => { if (this._model && !this._model.isDisposed()) { From 8f86741073a40977965c2945055fbc9437c0c0b8 Mon Sep 17 00:00:00 2001 From: Peng Lyu Date: Fri, 27 Sep 2024 12:18:29 -0700 Subject: [PATCH 06/27] Fix ##229995. Exclude empty editor hint in notebook diff editor (#230001) --- .../contrib/notebook/browser/diff/notebookDiffList.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffList.ts b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffList.ts index 154a29b9173ee..dd7de68ed52be 100644 --- a/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffList.ts +++ b/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffList.ts @@ -33,6 +33,7 @@ import { IAccessibilityService } from '../../../../../platform/accessibility/com import { localize } from '../../../../../nls.js'; import { IEditorConstructionOptions } from '../../../../../editor/browser/config/editorConfiguration.js'; import { IDiffEditorConstructionOptions } from '../../../../../editor/browser/editorBrowser.js'; +import { EditorExtensionsRegistry } from '../../../../../editor/browser/editorExtensions.js'; export class NotebookCellTextDiffListDelegate implements IListVirtualDelegate { private readonly lineHeight: number; @@ -607,7 +608,9 @@ function buildDiffEditorWidget(instantiationService: IInstantiationService, note function buildSourceEditor(instantiationService: IInstantiationService, notebookEditor: INotebookTextDiffEditor, sourceContainer: HTMLElement, options: IEditorConstructionOptions = {}) { const editorContainer = DOM.append(sourceContainer, DOM.$('.editor-container')); - + const skipContributions = [ + 'editor.contrib.emptyTextEditorHint' + ]; const editor = instantiationService.createInstance(CodeEditorWidget, editorContainer, { ...fixedEditorOptions, glyphMargin: false, @@ -618,7 +621,9 @@ function buildSourceEditor(instantiationService: IInstantiationService, notebook automaticLayout: false, overflowWidgetsDomNode: notebookEditor.getOverflowContainerDomNode(), readOnly: true, - }, {}); + }, { + contributions: EditorExtensionsRegistry.getEditorContributions().filter(c => skipContributions.indexOf(c.id) === -1) + }); return { editor, editorContainer }; } From e0ca49c84aae9afbf9dac924e99dad3b27c0ce83 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 27 Sep 2024 12:26:54 -0700 Subject: [PATCH 07/27] Improve lifecycle management in TerminalLinks.ts --- .../links/browser/terminalLink.ts | 47 +++++++------------ 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts index d9bd159bfc9a3..228d047f4b254 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLink.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import type { IViewportRange, IBufferRange, ILink, ILinkDecorations, Terminal } from '@xterm/xterm'; -import { DisposableStore } from '../../../../../base/common/lifecycle.js'; +import { Disposable, DisposableStore, MutableDisposable } from '../../../../../base/common/lifecycle.js'; import * as dom from '../../../../../base/browser/dom.js'; import { RunOnceScheduler } from '../../../../../base/common/async.js'; import { convertBufferRangeToViewport } from './terminalLinkHelpers.js'; @@ -16,12 +16,11 @@ import type { URI } from '../../../../../base/common/uri.js'; import type { IParsedLink } from './terminalLinkParsing.js'; import type { IHoverAction } from '../../../../../base/browser/ui/hover/hover.js'; -export class TerminalLink extends DisposableStore implements ILink { +export class TerminalLink extends Disposable implements ILink { decorations: ILinkDecorations; - asyncActivate: Promise | undefined; - private _tooltipScheduler: RunOnceScheduler | undefined; - private _hoverListeners: DisposableStore | undefined; + private readonly _tooltipScheduler: MutableDisposable = this._register(new MutableDisposable()); + private readonly _hoverListeners = this._register(new MutableDisposable()); private readonly _onInvalidated = new Emitter(); get onInvalidated(): Event { return this._onInvalidated.event; } @@ -50,38 +49,28 @@ export class TerminalLink extends DisposableStore implements ILink { }; } - override dispose(): void { - super.dispose(); - this._hoverListeners?.dispose(); - this._hoverListeners = undefined; - this._tooltipScheduler?.dispose(); - this._tooltipScheduler = undefined; - } - activate(event: MouseEvent | undefined, text: string): void { - // Trigger the xterm.js callback synchronously but track the promise resolution so we can - // use it in tests - this.asyncActivate = this._activateCallback(event, text); + this._activateCallback(event, text); } hover(event: MouseEvent, text: string): void { const w = dom.getWindow(event); const d = w.document; // Listen for modifier before handing it off to the hover to handle so it gets disposed correctly - this._hoverListeners = new DisposableStore(); - this._hoverListeners.add(dom.addDisposableListener(d, 'keydown', e => { + const hoverListeners = this._hoverListeners.value = new DisposableStore(); + hoverListeners.add(dom.addDisposableListener(d, 'keydown', e => { if (!e.repeat && this._isModifierDown(e)) { this._enableDecorations(); } })); - this._hoverListeners.add(dom.addDisposableListener(d, 'keyup', e => { + hoverListeners.add(dom.addDisposableListener(d, 'keyup', e => { if (!e.repeat && !this._isModifierDown(e)) { this._disableDecorations(); } })); // Listen for when the terminal renders on the same line as the link - this._hoverListeners.add(this._xterm.onRender(e => { + hoverListeners.add(this._xterm.onRender(e => { const viewportRangeY = this.range.start.y - this._viewportY; if (viewportRangeY >= e.start && viewportRangeY <= e.end) { this._onInvalidated.fire(); @@ -91,7 +80,7 @@ export class TerminalLink extends DisposableStore implements ILink { // Only show the tooltip and highlight for high confidence links (not word/search workspace // links). Feedback was that this makes using the terminal overly noisy. if (this._isHighConfidenceLink) { - this._tooltipScheduler = new RunOnceScheduler(() => { + this._tooltipScheduler.value = new RunOnceScheduler(() => { this._tooltipCallback( this, convertBufferRangeToViewport(this.range, this._viewportY), @@ -99,15 +88,13 @@ export class TerminalLink extends DisposableStore implements ILink { this._isHighConfidenceLink ? () => this._disableDecorations() : undefined ); // Clear out scheduler until next hover event - this._tooltipScheduler?.dispose(); - this._tooltipScheduler = undefined; + this._tooltipScheduler.clear(); }, this._configurationService.getValue('workbench.hover.delay')); - this.add(this._tooltipScheduler); - this._tooltipScheduler.schedule(); + this._tooltipScheduler.value.schedule(); } const origin = { x: event.pageX, y: event.pageY }; - this._hoverListeners.add(dom.addDisposableListener(d, dom.EventType.MOUSE_MOVE, e => { + hoverListeners.add(dom.addDisposableListener(d, dom.EventType.MOUSE_MOVE, e => { // Update decorations if (this._isModifierDown(e)) { this._enableDecorations(); @@ -119,16 +106,14 @@ export class TerminalLink extends DisposableStore implements ILink { if (Math.abs(e.pageX - origin.x) > w.devicePixelRatio * 2 || Math.abs(e.pageY - origin.y) > w.devicePixelRatio * 2) { origin.x = e.pageX; origin.y = e.pageY; - this._tooltipScheduler?.schedule(); + this._tooltipScheduler.value?.schedule(); } })); } leave(): void { - this._hoverListeners?.dispose(); - this._hoverListeners = undefined; - this._tooltipScheduler?.dispose(); - this._tooltipScheduler = undefined; + this._hoverListeners.clear(); + this._tooltipScheduler.clear(); } private _enableDecorations(): void { From aa0b6bb15ada0b4af2ac610122761239ec2c9b7c Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 27 Sep 2024 12:31:21 -0700 Subject: [PATCH 08/27] feat: collapse codeblocks in editing sessions (#230005) --- .../chatMarkdownContentPart.ts | 21 +++++++++++++++++-- .../chat/browser/chatInlineAnchorWidget.ts | 12 +++++++++-- .../chatMarkdownDecorationsRenderer.ts | 2 +- .../browser/media/chatInlineAnchorWidget.css | 9 ++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatMarkdownContentPart.ts b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatMarkdownContentPart.ts index 552f7522e7676..1d7731a17b704 100644 --- a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatMarkdownContentPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatMarkdownContentPart.ts @@ -26,6 +26,8 @@ import { IChatProgressRenderableResponseContent } from '../../common/chatModel.j import { isRequestVM, isResponseVM } from '../../common/chatViewModel.js'; import { CodeBlockModelCollection } from '../../common/codeBlockModelCollection.js'; import { URI } from '../../../../../base/common/uri.js'; +import { IEditorService } from '../../../../services/editor/common/editorService.js'; +import { InlineAnchorWidget } from '../chatInlineAnchorWidget.js'; const $ = dom.$; @@ -52,7 +54,8 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP rendererOptions: IChatListItemRendererOptions, @IContextKeyService contextKeyService: IContextKeyService, @ITextModelService private readonly textModelService: ITextModelService, - @IInstantiationService instantiationService: IInstantiationService, + @IInstantiationService private readonly instantiationService: IInstantiationService, + @IEditorService private readonly editorService: IEditorService, ) { super(); @@ -132,6 +135,7 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP this.codeBlockModelCollection.update(data.element.sessionId, data.element, data.codeBlockIndex, { text, languageId: data.languageId }).then((e) => { // Update the existing object's codemapperUri this.codeblocks[data.codeBlockIndex].codemapperUri = e.codemapperUri; + this._onDidChangeHeight.fire(); }); } @@ -145,7 +149,20 @@ export class ChatMarkdownContentPart extends Disposable implements IChatContentP } layout(width: number): void { - this.allRefs.forEach(ref => ref.object.layout(width)); + this.allRefs.forEach((ref, index) => { + const codeblockModel = this.codeblocks[index]; + if (codeblockModel.codemapperUri) { + const fileWidgetAnchor = $('.chat-codeblock'); + this._register(this.instantiationService.createInstance(InlineAnchorWidget, fileWidgetAnchor, { uri: codeblockModel.codemapperUri }, { handleClick: (uri) => this.editorService.openEditor({ resource: uri }) })); + const existingCodeblock = ref.object.element.parentElement?.querySelector('.chat-codeblock'); + if (!existingCodeblock) { + ref.object.element.parentElement?.appendChild(fileWidgetAnchor); + ref.object.element.style.display = 'none'; + } + } else { + ref.object.layout(width); + } + }); } addDisposable(disposable: IDisposable): void { diff --git a/src/vs/workbench/contrib/chat/browser/chatInlineAnchorWidget.ts b/src/vs/workbench/contrib/chat/browser/chatInlineAnchorWidget.ts index bb24ba0946c53..41a39c9aa88ae 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInlineAnchorWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInlineAnchorWidget.ts @@ -40,9 +40,12 @@ import { IChatWidgetService } from './chat.js'; export class InlineAnchorWidget extends Disposable { + public static readonly className = 'chat-inline-anchor-widget'; + constructor( - element: HTMLAnchorElement, + element: HTMLAnchorElement | HTMLElement, data: ContentRefData, + options: { handleClick?: (uri: URI) => void } = {}, @IContextKeyService originalContextKeyService: IContextKeyService, @IContextMenuService contextMenuService: IContextMenuService, @IFileService fileService: IFileService, @@ -60,7 +63,10 @@ export class InlineAnchorWidget extends Disposable { const contextKeyService = this._register(originalContextKeyService.createScoped(element)); const anchorId = new Lazy(generateUuid); - element.classList.add('chat-inline-anchor-widget', 'show-file-icons'); + element.classList.add(InlineAnchorWidget.className, 'show-file-icons'); + if (options.handleClick) { + element.classList.add('clickable'); + } let iconText: string; let iconClasses: string[]; @@ -128,6 +134,8 @@ export class InlineAnchorWidget extends Disposable { .catch(() => { }); this._register(dom.addDisposableListener(element, 'click', () => { + options.handleClick?.(location.uri); + telemetryService.publicLog2<{ anchorId: string; }, { diff --git a/src/vs/workbench/contrib/chat/browser/chatMarkdownDecorationsRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatMarkdownDecorationsRenderer.ts index 79555a8099fe2..43ed2cc5a5bf6 100644 --- a/src/vs/workbench/contrib/chat/browser/chatMarkdownDecorationsRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatMarkdownDecorationsRenderer.ts @@ -246,7 +246,7 @@ export class ChatMarkdownDecorationsRenderer extends Disposable { return; } - store.add(this.instantiationService.createInstance(InlineAnchorWidget, a, data)); + store.add(this.instantiationService.createInstance(InlineAnchorWidget, a, data, undefined)); } private renderResourceWidget(name: string, args: IDecorationWidgetArgs | undefined, store: DisposableStore): HTMLElement { diff --git a/src/vs/workbench/contrib/chat/browser/media/chatInlineAnchorWidget.css b/src/vs/workbench/contrib/chat/browser/media/chatInlineAnchorWidget.css index 751bbdf6350f0..fc672aae75fbc 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chatInlineAnchorWidget.css +++ b/src/vs/workbench/contrib/chat/browser/media/chatInlineAnchorWidget.css @@ -9,6 +9,15 @@ margin: 0 1px; padding: 1px 3px; text-wrap: nowrap; + width: fit-content; +} + +.chat-inline-anchor-widget .icon-label { + padding-right: 3px; +} + +.chat-inline-anchor-widget .clickable { + cursor: pointer; } .interactive-item-container .value .rendered-markdown .chat-inline-anchor-widget { From f74d65ef2c9c86215b74b681a5a5d1750106ae93 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Sep 2024 12:50:23 -0700 Subject: [PATCH 09/27] Adopt `preparePasteEdits` for js/ts update imports on paste (#230007) Client side of https://github.com/microsoft/TypeScript/pull/60053 --- .../package.nls.json | 2 +- .../src/languageFeatures/copyPaste.ts | 29 ++++++++++++++++--- .../src/tsServer/api.ts | 1 - .../src/tsServer/protocol/protocol.d.ts | 13 +++++++++ .../src/typescriptService.ts | 1 + 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/extensions/typescript-language-features/package.nls.json b/extensions/typescript-language-features/package.nls.json index d9c4ddb2a65b8..21506b11ede96 100644 --- a/extensions/typescript-language-features/package.nls.json +++ b/extensions/typescript-language-features/package.nls.json @@ -236,7 +236,7 @@ "configuration.tsserver.web.projectWideIntellisense.suppressSemanticErrors": "Suppresses semantic errors on web even when project wide IntelliSense is enabled. This is always on when project wide IntelliSense is not enabled or available. See `#typescript.tsserver.web.projectWideIntellisense.enabled#`", "configuration.tsserver.web.typeAcquisition.enabled": "Enable/disable package acquisition on the web. This enables IntelliSense for imported packages. Requires `#typescript.tsserver.web.projectWideIntellisense.enabled#`. Currently not supported for Safari.", "configuration.tsserver.nodePath": "Run TS Server on a custom Node installation. This can be a path to a Node executable, or 'node' if you want VS Code to detect a Node installation.", - "configuration.updateImportsOnPaste": "Automatically update imports when pasting code. Requires TypeScript 5.6+.", + "configuration.updateImportsOnPaste": "Automatically update imports when pasting code. Requires TypeScript 5.7+.", "configuration.expandableHover": "(Experimental) Enable/disable expanding on hover.", "walkthroughs.nodejsWelcome.title": "Get started with JavaScript and Node.js", "walkthroughs.nodejsWelcome.description": "Make the most of Visual Studio Code's first-class JavaScript experience.", diff --git a/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts b/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts index 3e2e61a8a52c3..debf060d0ea58 100644 --- a/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts +++ b/extensions/typescript-language-features/src/languageFeatures/copyPaste.ts @@ -50,7 +50,24 @@ class DocumentPasteProvider implements vscode.DocumentPasteEditProvider { private readonly _client: ITypeScriptServiceClient, ) { } - prepareDocumentPaste(document: vscode.TextDocument, ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken) { + async prepareDocumentPaste(document: vscode.TextDocument, ranges: readonly vscode.Range[], dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken) { + if (!this.isEnabled(document)) { + return; + } + + const file = this._client.toOpenTsFilePath(document); + if (!file) { + return; + } + + const response = await this._client.execute('preparePasteEdits', { + file, + copiedTextSpan: ranges.map(typeConverters.Range.toTextSpan), + }, token); + if (token.isCancellationRequested || response.type !== 'response' || !response.body) { + return; + } + dataTransfer.set(DocumentPasteProvider.metadataMimeType, new vscode.DataTransferItem(new CopyMetadata(document.uri, ranges).toJSON())); } @@ -62,8 +79,7 @@ class DocumentPasteProvider implements vscode.DocumentPasteEditProvider { _context: vscode.DocumentPasteEditContext, token: vscode.CancellationToken, ): Promise { - const config = vscode.workspace.getConfiguration(this._modeId, document.uri); - if (!config.get(settingId, false)) { + if (!this.isEnabled(document)) { return; } @@ -127,12 +143,17 @@ class DocumentPasteProvider implements vscode.DocumentPasteEditProvider { return metadata ? CopyMetadata.fromJSON(metadata) : undefined; } + + private isEnabled(document: vscode.TextDocument) { + const config = vscode.workspace.getConfiguration(this._modeId, document.uri); + return config.get(settingId, false); + } } export function register(selector: DocumentSelector, language: LanguageDescription, client: ITypeScriptServiceClient) { return conditionalRegistration([ requireSomeCapability(client, ClientCapability.Semantic), - requireMinVersion(client, API.v560), + requireMinVersion(client, API.v570), requireGlobalConfiguration(language.id, settingId), ], () => { return vscode.languages.registerDocumentPasteEditProvider(selector.semantic, new DocumentPasteProvider(language.id, client), { diff --git a/extensions/typescript-language-features/src/tsServer/api.ts b/extensions/typescript-language-features/src/tsServer/api.ts index 7b6d160952ee2..4ddc29944f0a4 100644 --- a/extensions/typescript-language-features/src/tsServer/api.ts +++ b/extensions/typescript-language-features/src/tsServer/api.ts @@ -28,7 +28,6 @@ export class API { public static readonly v520 = API.fromSimpleString('5.2.0'); public static readonly v544 = API.fromSimpleString('5.4.4'); public static readonly v540 = API.fromSimpleString('5.4.0'); - public static readonly v550 = API.fromSimpleString('5.5.0'); public static readonly v560 = API.fromSimpleString('5.6.0'); public static readonly v570 = API.fromSimpleString('5.7.0'); diff --git a/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts index 747e7c22e3724..cd70b6b7d41c3 100644 --- a/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts +++ b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts @@ -19,5 +19,18 @@ declare module '../../../../node_modules/typescript/lib/typescript' { interface Response { readonly _serverType?: ServerType; } + + //#region PreparePasteEdits + interface PreparePasteEditsRequest extends FileRequest { + command: 'preparePasteEdits'; + arguments: PreparePasteEditsRequestArgs; + } + interface PreparePasteEditsRequestArgs extends FileRequestArgs { + copiedTextSpan: TextSpan[]; + } + interface PreparePasteEditsResponse extends Response { + body: boolean; + } + //#endregion } } diff --git a/extensions/typescript-language-features/src/typescriptService.ts b/extensions/typescript-language-features/src/typescriptService.ts index 931b287df03e1..90528ee47dc8c 100644 --- a/extensions/typescript-language-features/src/typescriptService.ts +++ b/extensions/typescript-language-features/src/typescriptService.ts @@ -78,6 +78,7 @@ interface StandardTsServerRequests { 'linkedEditingRange': [Proto.FileLocationRequestArgs, Proto.LinkedEditingRangeResponse]; 'mapCode': [Proto.MapCodeRequestArgs, Proto.MapCodeResponse]; 'getPasteEdits': [Proto.GetPasteEditsRequestArgs, Proto.GetPasteEditsResponse]; + 'preparePasteEdits': [Proto.PreparePasteEditsRequestArgs, Proto.PreparePasteEditsResponse]; } interface NoResponseTsServerRequests { From 626fc7d3984bbe3b4fb1a77c85960dffd5102d57 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Sep 2024 12:50:52 -0700 Subject: [PATCH 10/27] Make sure we delete new TS internal file names too (#230011) https://github.com/microsoft/TypeScript/pull/59720 --- extensions/postinstall.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extensions/postinstall.mjs b/extensions/postinstall.mjs index 04e54dd6e2cab..f073aa720c91f 100644 --- a/extensions/postinstall.mjs +++ b/extensions/postinstall.mjs @@ -26,7 +26,10 @@ function processRoot() { function processLib() { const toDelete = new Set([ 'tsc.js', + '_tsc.js', + 'typescriptServices.js', + '_typescriptServices.js', ]); const libRoot = path.join(root, 'lib'); From 6ec2c7e634cdeb23693f3833e9b7e78328bdd07c Mon Sep 17 00:00:00 2001 From: Justin Su Date: Fri, 27 Sep 2024 17:41:18 -0400 Subject: [PATCH 11/27] Fix "in none full screen mode" typo (#229914) --- src/vs/workbench/electron-sandbox/desktop.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index f6bae665b130d..72527bf9ba539 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -251,7 +251,7 @@ import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL } from '../../platform/window/electron-s ], 'default': isLinux ? 'never' : 'auto', 'scope': ConfigurationScope.APPLICATION, - 'markdownDescription': localize('window.customTitleBarVisibility', "Adjust when the custom title bar should be shown. The custom title bar can be hidden when in full screen mode with `windowed`. The custom title bar can only be hidden in none full screen mode with `never` when {0} is set to `native`.", '`#window.titleBarStyle#`'), + 'markdownDescription': localize('window.customTitleBarVisibility', "Adjust when the custom title bar should be shown. The custom title bar can be hidden when in full screen mode with `windowed`. The custom title bar can only be hidden in non full screen mode with `never` when {0} is set to `native`.", '`#window.titleBarStyle#`'), }, 'window.dialogStyle': { 'type': 'string', From 1d3cc0a9bc720565b6d1ce673dfea1f08fc7f769 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 27 Sep 2024 14:43:15 -0700 Subject: [PATCH 12/27] fix: New Edit Session doesn't work if panel chat is active (#230021) --- .../workbench/contrib/chat/browser/actions/chatClearActions.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts index cb5c64f760b2e..c9c0311cc8d95 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts @@ -19,6 +19,7 @@ import { ChatEditorInput } from '../chatEditorInput.js'; import { ChatViewPane } from '../chatViewPane.js'; import { CONTEXT_IN_CHAT_SESSION, CONTEXT_CHAT_ENABLED, CONTEXT_CHAT_EDITING_PARTICIPANT_REGISTERED } from '../../common/chatContextKeys.js'; import { IViewsService } from '../../../../services/views/common/viewsService.js'; +import { ChatAgentLocation } from '../../common/chatAgents.js'; export const ACTION_ID_NEW_CHAT = `workbench.action.chat.newChat`; @@ -139,7 +140,7 @@ export function registerNewChatActions() { const viewsService = accessor.get(IViewsService); let widget = widgetService.lastFocusedWidget; - if (!widget) { + if (!widget || widget.location !== ChatAgentLocation.EditingSession) { const chatView = await viewsService.openView(EDITS_VIEW_ID) as ChatViewPane; widget = chatView.widget; } From 2fd1512a579e4f41c76305a90d7011f4a5aea7a0 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Sat, 28 Sep 2024 00:31:11 +0200 Subject: [PATCH 13/27] SCM - first colored badge is being rendered independently (#230022) --- .../contrib/scm/browser/scmHistoryViewPane.ts | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts index 4de2e1841eb22..ff5fc1818fafb 100644 --- a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts @@ -365,17 +365,27 @@ class HistoryItemRenderer implements ITreeRenderer { const labelConfig = this._badgesConfig.read(reader); - const firstColoredRef = historyItem.references?.find(ref => ref.color); templateData.labelContainer.textContent = ''; + const references = historyItem.references ? + historyItem.references.slice(0) : []; + + // If the first reference is colored, we render it + // separately since we have to show the description + // for the first colored reference. + if (references.length > 0 && references[0].color) { + this._renderBadge(references[0], true, templateData); + + // Remove the rendered reference from the collection + references.splice(0, 1); + } + // Group history item references by color - const historyItemRefsByColor = groupBy2( - (historyItem.references ?? []), - ref => ref.color ? ref.color : ''); + const historyItemRefsByColor = groupBy2(references, ref => ref.color ? ref.color : ''); for (const [key, historyItemRefs] of Object.entries(historyItemRefsByColor)) { - // Skip badges with no color + // If needed skip badges with no color if (key === '' && labelConfig !== 'all') { continue; } @@ -387,7 +397,7 @@ class HistoryItemRenderer implements ITreeRenderer Date: Fri, 27 Sep 2024 16:11:17 -0700 Subject: [PATCH 14/27] Try converting absolute icon font sizes to relative values (#229440) Fixes #229128 --- .../themes/browser/fileIconThemeData.ts | 29 +++++++++++++++++-- .../themes/common/fileIconThemeSchema.ts | 2 +- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts index bb3c6a2ac975a..f7f38038aeb67 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -395,12 +395,14 @@ export class FileIconThemeLoader { const fonts = iconThemeDocument.fonts; const fontSizes = new Map(); if (Array.isArray(fonts)) { - const defaultFontSize = fonts[0].size || '150%'; + const defaultFontSize = this.tryNormalizeFontSize(fonts[0].size) || '150%'; fonts.forEach(font => { const src = font.src.map(l => `${asCSSUrl(resolvePath(l.path))} format('${l.format}')`).join(', '); cssRules.push(`@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; font-display: block; }`); - if (font.size !== undefined && font.size !== defaultFontSize) { - fontSizes.set(font.id, font.size); + + const fontSize = this.tryNormalizeFontSize(font.size); + if (fontSize !== undefined && fontSize !== defaultFontSize) { + fontSizes.set(font.id, fontSize); } }); cssRules.push(`.show-file-icons .file-icon::before, .show-file-icons .folder-icon::before, .show-file-icons .rootfolder-icon::before { font-family: '${fonts[0].id}'; font-size: ${defaultFontSize}; }`); @@ -455,6 +457,27 @@ export class FileIconThemeLoader { return result; } + /** + * Try converting absolute font sizes to relative values. + * + * This allows them to be scaled nicely depending on where they are used. + */ + private tryNormalizeFontSize(size: string | undefined): string | undefined { + if (!size) { + return undefined; + } + + const defaultFontSizeInPx = 13; + + if (size.endsWith('px')) { + const value = parseInt(size, 10); + if (!isNaN(value)) { + return Math.round((value / defaultFontSizeInPx) * 100) + '%'; + } + } + + return size; + } } function handleParentFolder(key: string, selectors: string[]): string { diff --git a/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts b/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts index a8f07fb74a4f1..4d18093f41e14 100644 --- a/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts +++ b/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts @@ -185,7 +185,7 @@ const schema: IJSONSchema = { }, size: { type: 'string', - description: nls.localize('schema.font-size', 'The default size of the font. See https://developer.mozilla.org/en-US/docs/Web/CSS/font-size for valid values.'), + description: nls.localize('schema.font-size', 'The default size of the font. We strongly recommend using a percentage value, for example: 125%.'), pattern: fontSizeRegex } }, From 77677ac4b56358ecf8aefb5b1565aeb0ee717548 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Sep 2024 16:11:30 -0700 Subject: [PATCH 15/27] Force /help response to stream (#230026) * Force /help response to stream It just looks nicer this way Fix microsoft/vscode-copilot#8591 * Tweak comment --- src/vs/workbench/contrib/chat/browser/chat.contribution.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index bec60f8fd124a..dda6330c614ac 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { timeout } from '../../../../base/common/async.js'; import { MarkdownString, isMarkdownString } from '../../../../base/common/htmlContent.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; import { Schemas } from '../../../../base/common/network.js'; @@ -263,6 +264,11 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable { progress.report({ content: new MarkdownString(defaultAgent.metadata.helpTextPostfix), kind: 'markdownContent' }); } } + + // Without this, the response will be done before it renders and so it will not stream. This ensures that if the response starts + // rendering during the next 200ms, then it will be streamed. Once it starts streaming, the whole response streams even after + // it has received all response data has been received. + await timeout(200); })); } } From 64708fe61d7190ee194c2085383a6e3a7ca79a00 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Sat, 28 Sep 2024 01:13:28 +0200 Subject: [PATCH 16/27] SCM Graph - add counter to badges (#230025) * SCM - first colored badge is being rendered independently * SCM Graph - added badge count * Cleanup code --- .../contrib/scm/browser/media/scm.css | 6 ++++ .../contrib/scm/browser/scmHistoryViewPane.ts | 31 +++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/media/scm.css b/src/vs/workbench/contrib/scm/browser/media/scm.css index 0c72ca522f9ae..4ba122fa37019 100644 --- a/src/vs/workbench/contrib/scm/browser/media/scm.css +++ b/src/vs/workbench/contrib/scm/browser/media/scm.css @@ -168,6 +168,12 @@ line-height: 18px; } +.scm-view .monaco-list-row .history-item > .label-container > .label > .count { + font-size: 12px; + margin-left: 0; + padding-left: 4px; +} + .scm-view .monaco-list-row .history-item > .label-container > .label > .codicon { font-size: 14px; color: inherit !important; diff --git a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts index ff5fc1818fafb..5ad747852ecf8 100644 --- a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts @@ -375,7 +375,7 @@ class HistoryItemRenderer implements ITreeRenderer 0 && references[0].color) { - this._renderBadge(references[0], true, templateData); + this._renderBadge([references[0]], true, templateData); // Remove the rendered reference from the collection references.splice(0, 1); @@ -385,7 +385,7 @@ class HistoryItemRenderer implements ITreeRenderer ref.color ? ref.color : ''); for (const [key, historyItemRefs] of Object.entries(historyItemRefsByColor)) { - // If needed skip badges with no color + // If needed skip badges without a color if (key === '' && labelConfig !== 'all') { continue; } @@ -393,35 +393,40 @@ class HistoryItemRenderer implements ITreeRenderer ThemeIcon.isThemeIcon(ref.icon) ? ref.icon.id : ''); for (const [key, historyItemRefs] of Object.entries(historyItemRefByIconId)) { - if (key === '' || historyItemRefs.length === 0) { + // Skip badges without an icon + if (key === '') { continue; } - this._renderBadge(historyItemRefs[0], false, templateData); + this._renderBadge(historyItemRefs, false, templateData); } } })); } - private _renderBadge(historyItemRef: ISCMHistoryItemRef, showDescription: boolean, templateData: HistoryItemTemplate): void { - if (!ThemeIcon.isThemeIcon(historyItemRef.icon)) { + private _renderBadge(historyItemRefs: ISCMHistoryItemRef[], showDescription: boolean, templateData: HistoryItemTemplate): void { + if (historyItemRefs.length === 0 || !ThemeIcon.isThemeIcon(historyItemRefs[0].icon)) { return; } const elements = h('div.label', { style: { - color: historyItemRef.color ? asCssVariable(historyItemHoverLabelForeground) : asCssVariable(foreground), - backgroundColor: historyItemRef.color ? asCssVariable(historyItemRef.color) : asCssVariable(historyItemHoverDefaultLabelBackground) + color: historyItemRefs[0].color ? asCssVariable(historyItemHoverLabelForeground) : asCssVariable(foreground), + backgroundColor: historyItemRefs[0].color ? asCssVariable(historyItemRefs[0].color) : asCssVariable(historyItemHoverDefaultLabelBackground) } }, [ + h('div.count@count', { + style: { display: historyItemRefs.length > 1 ? '' : 'none' } + }), h('div.icon@icon'), - h('div.description@description') + h('div.description@description', { + style: { display: showDescription ? '' : 'none' } + }) ]); - elements.icon.classList.add(...ThemeIcon.asClassNameArray(historyItemRef.icon)); - - elements.description.textContent = historyItemRef.name; - elements.description.style.display = showDescription ? '' : 'none'; + elements.count.textContent = historyItemRefs.length.toString(); + elements.icon.classList.add(...ThemeIcon.asClassNameArray(historyItemRefs[0].icon)); + elements.description.textContent = historyItemRefs[0].name; append(templateData.labelContainer, elements.root); } From 6bbcad9bdd2b6c03d050cdcd10d7c0094647d6d7 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Sep 2024 16:18:17 -0700 Subject: [PATCH 17/27] Fix chat cancel button order (#230015) (#230027) Fix #230013 --- .../contrib/chat/browser/actions/chatExecuteActions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts index fdff4f2c19797..94d12546a42c3 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts @@ -167,7 +167,7 @@ export class CancelAction extends Action2 { menu: { id: MenuId.ChatExecute, when: CONTEXT_CHAT_REQUEST_IN_PROGRESS, - order: 2, + order: 4, group: 'navigation', }, keybinding: { From ef69ffe1cb99ccc77683cd293b4cc7fd56b3dc70 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Sep 2024 16:18:40 -0700 Subject: [PATCH 18/27] Correctly pass user selected LM for intent detection (#230014) (#230028) Fix #229616 --- .../workbench/api/common/extHost.api.impl.ts | 2 +- .../api/common/extHostChatAgents2.ts | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 2e335cbaa5da6..8c04da5bb7c44 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1454,7 +1454,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, registerChatParticipantDetectionProvider(provider: vscode.ChatParticipantDetectionProvider) { checkProposedApiEnabled(extension, 'chatParticipantAdditions'); - return extHostChatAgents2.registerChatParticipantDetectionProvider(provider); + return extHostChatAgents2.registerChatParticipantDetectionProvider(extension, provider); }, }; diff --git a/src/vs/workbench/api/common/extHostChatAgents2.ts b/src/vs/workbench/api/common/extHostChatAgents2.ts index cc1ecb1291290..c31f91957d7fb 100644 --- a/src/vs/workbench/api/common/extHostChatAgents2.ts +++ b/src/vs/workbench/api/common/extHostChatAgents2.ts @@ -285,7 +285,7 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS private readonly _proxy: MainThreadChatAgentsShape2; private static _participantDetectionProviderIdPool = 0; - private readonly _participantDetectionProviders = new Map(); + private readonly _participantDetectionProviders = new Map(); private readonly _sessionDisposables: DisposableMap = this._register(new DisposableMap()); private readonly _completionDisposables: DisposableMap = this._register(new DisposableMap()); @@ -323,9 +323,9 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS return agent.apiAgent; } - registerChatParticipantDetectionProvider(provider: vscode.ChatParticipantDetectionProvider): vscode.Disposable { + registerChatParticipantDetectionProvider(extension: IExtensionDescription, provider: vscode.ChatParticipantDetectionProvider): vscode.Disposable { const handle = ExtHostChatAgents2._participantDetectionProviderIdPool++; - this._participantDetectionProviders.set(handle, provider); + this._participantDetectionProviders.set(handle, new ExtHostParticipantDetector(extension, provider)); this._proxy.$registerChatParticipantDetectionProvider(handle); return toDisposable(() => { this._participantDetectionProviders.delete(handle); @@ -336,13 +336,18 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS async $detectChatParticipant(handle: number, requestDto: Dto, context: { history: IChatAgentHistoryEntryDto[] }, options: { location: ChatAgentLocation; participants?: vscode.ChatParticipantMetadata[] }, token: CancellationToken): Promise { const { request, location, history } = await this._createRequest(requestDto, context); - const provider = this._participantDetectionProviders.get(handle); - if (!provider) { + const detector = this._participantDetectionProviders.get(handle); + if (!detector) { return undefined; } - return provider.provideParticipantDetection( - typeConvert.ChatAgentRequest.to(request, location), + const extRequest = typeConvert.ChatAgentRequest.to(request, location); + if (request.userSelectedModelId && isProposedApiEnabled(detector.extension, 'chatParticipantAdditions')) { + extRequest.userSelectedModel = await this._languageModels.getLanguageModelByIdentifier(detector.extension, request.userSelectedModelId); + } + + return detector.provider.provideParticipantDetection( + extRequest, { history }, { participants: options.participants, location: typeConvert.ChatLocation.to(options.location) }, token @@ -588,6 +593,13 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS } } +class ExtHostParticipantDetector { + constructor( + public readonly extension: IExtensionDescription, + public readonly provider: vscode.ChatParticipantDetectionProvider, + ) { } +} + class ExtHostChatAgent { private _followupProvider: vscode.ChatFollowupProvider | undefined; From 05016c9fc16b123d0426ac416504869fdcad8e25 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 27 Sep 2024 16:23:34 -0700 Subject: [PATCH 19/27] Avoid setting a negative padding on the chat welcome view container (#229996) (#230029) The layout here is a bit weird to avoid shifting when followups appear. If the followups wrap, then the layout is messed up because negative padding is not allowed. I might try to simplify this for next month. Fix microsoft/vscode-copilot#8749 --- src/vs/workbench/contrib/chat/browser/chatWidget.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 13849afedf0ad..3de9f7c3bf16e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -984,7 +984,7 @@ export class ChatWidget extends Disposable implements IChatWidget { this.tree.getHTMLElement().style.height = `${listHeight}px`; // Push the welcome message down so it doesn't change position when followups appear - const followupsOffset = 100 - this.inputPart.followupsHeight; + const followupsOffset = Math.max(100 - this.inputPart.followupsHeight, 0); this.welcomeMessageContainer.style.height = `${listHeight - followupsOffset}px`; this.welcomeMessageContainer.style.paddingBottom = `${followupsOffset}px`; this.renderer.layout(width); From 7112c83572c26b5a6f6f2fd9aca207cbcd324198 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Fri, 27 Sep 2024 16:29:13 -0700 Subject: [PATCH 20/27] Expand context menu for attachments list (#230030) --- src/vs/platform/actions/common/actions.ts | 1 + .../chatReferencesContentPart.ts | 143 ++++++++++++------ .../files/browser/fileActions.contribution.ts | 30 ++++ .../fileActions.contribution.ts | 9 ++ 4 files changed, 133 insertions(+), 50 deletions(-) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 0c4cf7598cc44..b49b11c86872f 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -230,6 +230,7 @@ export class MenuId { static readonly ChatInlineResourceAnchorContext = new MenuId('ChatInlineResourceAnchorContext'); static readonly ChatInlineSymbolAnchorContext = new MenuId('ChatInlineSymbolAnchorContext'); static readonly ChatCommandCenter = new MenuId('ChatCommandCenter'); + static readonly ChatAttachmentsContext = new MenuId('ChatAttachmentsContext'); static readonly AccessibleView = new MenuId('AccessibleView'); static readonly MultiDiffEditorFileToolbar = new MenuId('MultiDiffEditorFileToolbar'); static readonly DiffEditorHunkToolbar = new MenuId('DiffEditorHunkToolbar'); diff --git a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts index 2ca9d305f544d..0c31726d04843 100644 --- a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts @@ -6,6 +6,7 @@ import * as dom from '../../../../../base/browser/dom.js'; import { Button } from '../../../../../base/browser/ui/button/button.js'; import { IListRenderer, IListVirtualDelegate } from '../../../../../base/browser/ui/list/list.js'; +import { IAction } from '../../../../../base/common/actions.js'; import { coalesce } from '../../../../../base/common/arrays.js'; import { Codicon } from '../../../../../base/common/codicons.js'; import { Emitter, Event } from '../../../../../base/common/event.js'; @@ -15,13 +16,13 @@ import { basename } from '../../../../../base/common/path.js'; import { basenameOrAuthority, isEqualAuthority } from '../../../../../base/common/resources.js'; import { ThemeIcon } from '../../../../../base/common/themables.js'; import { URI } from '../../../../../base/common/uri.js'; -import { localize } from '../../../../../nls.js'; +import { localize, localize2 } from '../../../../../nls.js'; +import { createAndFillInContextMenuActions } from '../../../../../platform/actions/browser/menuEntryActionViewItem.js'; import { MenuWorkbenchToolBar } from '../../../../../platform/actions/browser/toolbar.js'; -import { MenuId } from '../../../../../platform/actions/common/actions.js'; -import { IClipboardService } from '../../../../../platform/clipboard/common/clipboardService.js'; +import { Action2, IMenuService, MenuId, registerAction2 } from '../../../../../platform/actions/common/actions.js'; import { IContextMenuService } from '../../../../../platform/contextview/browser/contextView.js'; import { FileKind } from '../../../../../platform/files/common/files.js'; -import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js'; +import { IInstantiationService, ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js'; import { ILabelService } from '../../../../../platform/label/common/label.js'; import { WorkbenchList } from '../../../../../platform/list/browser/listService.js'; import { IOpenerService } from '../../../../../platform/opener/common/opener.js'; @@ -30,12 +31,14 @@ import { IThemeService } from '../../../../../platform/theme/common/themeService import { fillEditorsDragData } from '../../../../browser/dnd.js'; import { IResourceLabel, ResourceLabels } from '../../../../browser/labels.js'; import { ColorScheme } from '../../../../browser/web.api.js'; +import { ResourceContextKey } from '../../../../common/contextkeys.js'; import { SETTINGS_AUTHORITY } from '../../../../services/preferences/common/preferences.js'; import { createFileIconThemableTreeContainerScope } from '../../../files/browser/views/explorerView.js'; +import { ExplorerFolderContext } from '../../../files/common/files.js'; import { ChatResponseReferencePartStatusKind, IChatContentReference, IChatWarningMessage } from '../../common/chatService.js'; import { IChatVariablesService } from '../../common/chatVariables.js'; import { IChatRendererContent, IChatResponseViewModel } from '../../common/chatViewModel.js'; -import { ChatTreeItem } from '../chat.js'; +import { ChatTreeItem, IChatWidgetService } from '../chat.js'; import { IDisposableReference, ResourcePool } from './chatCollections.js'; import { IChatContentPart } from './chatContentParts.js'; @@ -59,8 +62,9 @@ export class ChatCollapsibleListContentPart extends Disposable implements IChatC element: IChatResponseViewModel, contentReferencesListPool: CollapsibleListPool, @IOpenerService openerService: IOpenerService, + @IMenuService menuService: IMenuService, + @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextMenuService private readonly contextMenuService: IContextMenuService, - @IClipboardService private readonly clipboardService: IClipboardService, ) { super(); @@ -120,34 +124,32 @@ export class ChatCollapsibleListContentPart extends Disposable implements IChatC } } })); - this._register(list.onContextMenu((e) => { - e.browserEvent.preventDefault(); - e.browserEvent.stopPropagation(); - if (e.element && 'reference' in e.element && typeof e.element.reference === 'object') { - const uriOrLocation = 'variableName' in e.element.reference ? e.element.reference.value : e.element.reference; - const uri = URI.isUri(uriOrLocation) ? uriOrLocation : - uriOrLocation?.uri; - if (uri) { - this.contextMenuService.showContextMenu({ - getAnchor: () => e.anchor, - getActions: () => { - return [{ - id: 'workbench.action.chat.copyReference', - title: localize('copyReference', "Copy"), - label: localize('copyReference', "Copy"), - tooltip: localize('copyReference', "Copy"), - enabled: e.element?.kind === 'reference', - class: undefined, - run: () => { - void this.clipboardService.writeResources([uri]); - } - }]; - } - }); - } + this._register(list.onContextMenu(e => { + dom.EventHelper.stop(e.browserEvent, true); + + const uri = e.element && getResourceForElement(e.element); + if (!uri) { + return; } + this.contextMenuService.showContextMenu({ + getAnchor: () => e.anchor, + getActions: () => { + const menu = menuService.getMenuActions(MenuId.ChatAttachmentsContext, list.contextKeyService, { shouldForwardArgs: true, arg: uri }); + const primary: IAction[] = []; + createAndFillInContextMenuActions(menu, primary); + return primary; + } + }); + })); + + const resourceContextKey = this._register(this.instantiationService.createInstance(ResourceContextKey)); + this._register(list.onDidChangeFocus(e => { + resourceContextKey.reset(); + const element = e.elements.length ? e.elements[0] : undefined; + const uri = element && getResourceForElement(element); + resourceContextKey.set(uri ?? null); })); const maxItemsShown = 6; @@ -197,20 +199,6 @@ export class CollapsibleListPool extends Disposable { const container = $('.chat-used-context-list'); this._register(createFileIconThemableTreeContainerScope(container, this.themeService)); - const getDragURI = (element: IChatCollapsibleListItem): URI | null => { - if (element.kind === 'warning') { - return null; - } - const { reference } = element; - if (typeof reference === 'string' || 'variableName' in reference) { - return null; - } else if (URI.isUri(reference)) { - return reference; - } else { - return reference.uri; - } - }; - const list = this.instantiationService.createInstance( WorkbenchList, 'ChatListRenderer', @@ -239,9 +227,9 @@ export class CollapsibleListPool extends Disposable { getWidgetAriaLabel: () => localize('chatCollapsibleList', "Collapsible Chat List") }, dnd: { - getDragURI: (element: IChatCollapsibleListItem) => getDragURI(element)?.toString() ?? null, + getDragURI: (element: IChatCollapsibleListItem) => getResourceForElement(element)?.toString() ?? null, getDragLabel: (elements, originalEvent) => { - const uris: URI[] = coalesce(elements.map(getDragURI)); + const uris: URI[] = coalesce(elements.map(getResourceForElement)); if (!uris.length) { return undefined; } else if (uris.length === 1) { @@ -256,7 +244,7 @@ export class CollapsibleListPool extends Disposable { onDragStart: (data, originalEvent) => { try { const elements = data.getData() as IChatCollapsibleListItem[]; - const uris: URI[] = coalesce(elements.map(getDragURI)); + const uris: URI[] = coalesce(elements.map(getResourceForElement)); this.instantiationService.invokeFunction(accessor => fillEditorsDragData(accessor, uris, originalEvent)); } catch { // noop @@ -294,8 +282,8 @@ class CollapsibleListDelegate implements IListVirtualDelegate { @@ -414,3 +402,58 @@ class CollapsibleListRenderer implements IListRenderer { + const chatWidgetService = accessor.get(IChatWidgetService); + const variablesService = accessor.get(IChatVariablesService); + + if (!resource) { + return; + } + + const widget = chatWidgetService.lastFocusedWidget; + if (!widget) { + return; + } + + variablesService.attachContext('file', resource, widget.location); + } +}); + +//#endregion diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 81904a45cec17..ec2a3a69d0aaa 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -767,6 +767,36 @@ MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { }); +// Chat used attachment anchor context menu + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: 'navigation', + order: 10, + command: openToSideCommand, + when: ContextKeyExpr.and(ResourceContextKey.HasResource, ExplorerFolderContext.toNegated()) +}); + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: 'navigation', + order: 20, + command: revealInsideBarCommand, + when: ResourceContextKey.IsFileSystemResource +}); + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: '1_cutcopypaste', + order: 10, + command: copyPathCommand, + when: ResourceContextKey.IsFileSystemResource +}); + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: '1_cutcopypaste', + order: 20, + command: copyRelativePathCommand, + when: ResourceContextKey.IsFileSystemResource +}); + // Chat resource anchor context menu MenuRegistry.appendMenuItem(MenuId.ChatInlineResourceAnchorContext, { diff --git a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts index 1d75d5e5e44ca..5581931a9e7d1 100644 --- a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts @@ -97,6 +97,15 @@ appendToCommandPalette({ category: category }, REVEAL_IN_OS_WHEN_CONTEXT); +// Menu registration - chat attachments context + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: 'navigation', + order: 20, + command: revealInOsCommand, + when: REVEAL_IN_OS_WHEN_CONTEXT +}); + // Menu registration - chat inline anchor MenuRegistry.appendMenuItem(MenuId.ChatInlineResourceAnchorContext, { From bd9abc6ebe37ad975b7dc0c43c6ce2b384ec726d Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Fri, 27 Sep 2024 16:37:13 -0700 Subject: [PATCH 21/27] fix: #211878 for preferencesModels.ts (#230031) --- .../services/preferences/common/preferencesModels.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 8bc828292b109..e97874375fae9 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -422,7 +422,8 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, if (!model.isDisposed()) { visit(model.getValue(), visitor); } - return settings.length > 0 ? [{ + return settings.length > 0 ? [{ + id: model.isDisposed() ? '' : model.id, sections: [ { settings @@ -431,7 +432,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, title: '', titleRange: nullRange, range - }] : []; + } satisfies ISettingsGroup] : []; } export class WorkspaceConfigurationEditorModel extends SettingsEditorModel { @@ -844,7 +845,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements const metadata = this.collectMetadata(resultGroups); return resultGroups.length ? - { + { allGroups: this.settingsGroups, filteredGroups, matches, @@ -894,9 +895,10 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements filterMatches = filterMatches .map(filteredMatch => { // Fix match ranges to offset from setting start line - return { + return { setting: filteredMatch.setting, score: filteredMatch.score, + matchType: filteredMatch.matchType, matches: filteredMatch.matches && filteredMatch.matches.map(match => { return new Range( match.startLineNumber - filteredMatch.setting.range.startLineNumber, @@ -965,7 +967,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements } private getGroup(resultGroup: ISearchResultGroup): ISettingsGroup { - return { + return { id: resultGroup.id, range: nullRange, title: resultGroup.label, From 541f878e30173c000d9dc0feb45e36f3fd128c4c Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 27 Sep 2024 17:33:48 -0700 Subject: [PATCH 22/27] fix: reveal diffs for chat edits (#230032) --- src/vs/workbench/contrib/chat/browser/chatEditingService.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatEditingService.ts b/src/vs/workbench/contrib/chat/browser/chatEditingService.ts index 3321419dba3a0..14874cf40adf9 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditingService.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditingService.ts @@ -574,6 +574,7 @@ class ChatEditingSession extends Disposable implements IChatEditingSession { @ITextModelService private readonly _textModelService: ITextModelService, @IBulkEditService public readonly _bulkEditService: IBulkEditService, @IEditorGroupsService private readonly _editorGroupsService: IEditorGroupsService, + @IEditorService private readonly editorService: IEditorService, ) { super(); } @@ -708,7 +709,8 @@ class ChatEditingSession extends Disposable implements IChatEditingSession { private async _acceptTextEdits(resource: URI, textEdits: TextEdit[]): Promise { const entry = await this._getOrCreateModifiedFileEntry(resource); - entry.appyEdits(textEdits); + entry.applyEdits(textEdits); + await this.editorService.openEditor({ original: { resource: entry.originalURI }, modified: { resource: entry.modifiedURI }, options: { inactive: true } }); } private async _resolve(): Promise { @@ -796,7 +798,7 @@ class ModifiedFileEntry extends Disposable implements IModifiedFileEntry { this._register(resourceRef); } - appyEdits(textEdits: TextEdit[]): void { + applyEdits(textEdits: TextEdit[]): void { this.doc.applyEdits(textEdits); this._stateObs.set(ModifiedFileEntryState.Undecided, undefined); } From 6eba3f2d864711dcf75af46bbe784d352683dc59 Mon Sep 17 00:00:00 2001 From: BABA <38986298+BABA983@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:56:46 +0800 Subject: [PATCH 23/27] Fix debug console is cleared on style changed (#224694) --- src/vs/workbench/contrib/debug/browser/repl.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 7e33db78057e0..613fed3ce95ba 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -210,6 +210,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { this.refreshReplElements(true); if (this.styleChangedWhenInvisible) { this.styleChangedWhenInvisible = false; + this.tree?.updateChildren(undefined, true, false); this.onDidStyleChange(); } } From 4a8a56207333a8a06d36d7bd5a78f7ffc3e476f8 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:29:09 +0200 Subject: [PATCH 24/27] SCM Graph - only set the count and description is shown (#230039) * SCM Graph - only set the count and description is shown * . --- .../contrib/scm/browser/scmHistoryViewPane.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts index 5ad747852ecf8..79ae478779259 100644 --- a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts @@ -416,17 +416,21 @@ class HistoryItemRenderer implements ITreeRenderer 1 ? '' : 'none' } + style: { + display: historyItemRefs.length > 1 ? '' : 'none' + } }), h('div.icon@icon'), h('div.description@description', { - style: { display: showDescription ? '' : 'none' } + style: { + display: showDescription ? '' : 'none' + } }) ]); - elements.count.textContent = historyItemRefs.length.toString(); + elements.count.textContent = historyItemRefs.length > 1 ? historyItemRefs.length.toString() : ''; elements.icon.classList.add(...ThemeIcon.asClassNameArray(historyItemRefs[0].icon)); - elements.description.textContent = historyItemRefs[0].name; + elements.description.textContent = showDescription ? historyItemRefs[0].name : ''; append(templateData.labelContainer, elements.root); } From 3f5fa8a8bb2caca59b6e545ef8db7cc3718dfa50 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 28 Sep 2024 06:50:53 -0700 Subject: [PATCH 25/27] xterm@5.6.0-beta.65 Fixes #230010 --- package-lock.json | 76 ++++++++++++++++++------------------ package.json | 16 ++++---- remote/package-lock.json | 76 ++++++++++++++++++------------------ remote/package.json | 16 ++++---- remote/web/package-lock.json | 68 ++++++++++++++++---------------- remote/web/package.json | 14 +++---- 6 files changed, 133 insertions(+), 133 deletions(-) diff --git a/package-lock.json b/package-lock.json index d1ca8b05e78f0..06375d4a1a292 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,14 +26,14 @@ "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", "jschardet": "3.1.3", @@ -3505,65 +3505,65 @@ } }, "node_modules/@xterm/addon-clipboard": { - "version": "0.2.0-beta.47", - "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.47.tgz", - "integrity": "sha512-mJHV1770gwVckj4mgjdxegt4zLL5WGCoJblTqaLbgEF7xOwsJUzvGk38qsZ4ZpdTa2ti76H0pkb1CpZGrXL9qg==", + "version": "0.2.0-beta.48", + "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.48.tgz", + "integrity": "sha512-oTrGoGMOQaW7PINAShhNR3duV8l2No/DbJ9rtfSBjfoQ9clWe0K+4fUHdJIuzW65AZsiLo9oh5IbHLWxlFP3Jg==", "dependencies": { "js-base64": "^3.7.5" }, "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-image": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.64.tgz", - "integrity": "sha512-1Aqqytx/z/Khecf5xrO++f/p5EQX4uG87TbbAmE0OQys/JgKMnNggDzqon5bpHboimLfQiFPw716NbTqMphjfw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.65.tgz", + "integrity": "sha512-Ud5FI5cGtpbz8yYCHC4QINlbC1K04Mex1JD5oAWPFwjlOz/Si/DhqbY1QBDl6QrUmSUUTZc5DKT3v3nN5WbZxQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-search": { - "version": "0.16.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.64.tgz", - "integrity": "sha512-vUsvTkEOFJwv8nVtiiGr/vTMeQhu62VkUejY2h1+yZagnVEusGVPU1JYoqBTLu5HM4cFiTGsJYXFI/0apASXYA==", + "version": "0.16.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.65.tgz", + "integrity": "sha512-eHfbbgFCS3AcD8YSvGFIkW9NW4pfGHrtRDWIojM/zqmyi3JaCmHUgZmlxbaANwBlgLiNpJLDq7cmoz//86NgGw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-serialize": { - "version": "0.14.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.64.tgz", - "integrity": "sha512-0AqVveTV3Pr9Lp+beJYOP5WuRvIrPSDGAK24da7BRGcLIKVq8pok1FdlM9jPeUbkX0DKo6Ortm77qeb2Z+n8+A==", + "version": "0.14.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.65.tgz", + "integrity": "sha512-NlvXVtFAHpLKEDzd+6/68yPFQ4Oe02jvQH6+a8p+gcxbSEyYj1l0sqqeABQ3gC5QDCmQepk6BQVB8Rpz/e4HgQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-unicode11": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.64.tgz", - "integrity": "sha512-3+PKu+DXFq32xlsYfnI058/T8dTY2tQhRpJLP2CNR/jVWk5uBkVO0dBV0Srqj5QOAlAhzzZuS6TbsVRXORptqw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.65.tgz", + "integrity": "sha512-sH9mu2GEIVuc6cs6HxsmCXn6KKzCa5D+Zyl1Pt9d2S4FKqSB17Fc4mVukCOMW7wUR9UChKTbxmByGJK+4xwdCA==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-webgl": { - "version": "0.19.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.64.tgz", - "integrity": "sha512-cxTkMPAXPQAZnWqahNu7ff9mbJvM1sQqKnZWiFZAHTsZXym4oa3KCB4pjH4didSyYkhkPY/17E8I0UOUpvv0Yw==", + "version": "0.19.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.65.tgz", + "integrity": "sha512-gPwP8ozqrLFWOlo9eh2I+acxq0Z6obG7GpL8HpJ+B+q6+vjfxoXHQ6vV04W90aoAvbLpScHcT/JtXA58GcH2vw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/headless": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.64.tgz", - "integrity": "sha512-my08kgH2K3CBEtBg/o8lamtD6BYNBv03Akq747Lajv0QzOiwan7B4r2xdbA6i9sovB+MdjFs0XP1ksc3EpKakg==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.65.tgz", + "integrity": "sha512-gQICZsBkFHQEb/K+dc+KN4u5aBwrDPgai0S7W8/KT7fqTPWz8Cgjq119WQLshnzfLeMMFPYGttNHFGUbpp/wmw==" }, "node_modules/@xterm/xterm": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.64.tgz", - "integrity": "sha512-iSKS6tQTFpoN5y487eptlxkUT0jqK5hrvtFQMLugMcQdn7gCUCiFGa4Z1RdqKYSGvAypka+b9gMKPrKWZ7Q3yQ==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.65.tgz", + "integrity": "sha512-o6IIg4hqs994gtSQMbzQM6OUeLIXPG6RUxjoref0KJX4PIa/BqQjwQLPuSxnjOFeRQIvhZ2mSAPfGWJQ6jEGAg==" }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", diff --git a/package.json b/package.json index 7fbc5d9c91d75..8bd3499b8b52d 100644 --- a/package.json +++ b/package.json @@ -83,14 +83,14 @@ "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", "jschardet": "3.1.3", diff --git a/remote/package-lock.json b/remote/package-lock.json index 58725751af9ee..3a1e362f3dcca 100644 --- a/remote/package-lock.json +++ b/remote/package-lock.json @@ -20,14 +20,14 @@ "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "cookie": "^0.4.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", @@ -233,65 +233,65 @@ "hasInstallScript": true }, "node_modules/@xterm/addon-clipboard": { - "version": "0.2.0-beta.47", - "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.47.tgz", - "integrity": "sha512-mJHV1770gwVckj4mgjdxegt4zLL5WGCoJblTqaLbgEF7xOwsJUzvGk38qsZ4ZpdTa2ti76H0pkb1CpZGrXL9qg==", + "version": "0.2.0-beta.48", + "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.48.tgz", + "integrity": "sha512-oTrGoGMOQaW7PINAShhNR3duV8l2No/DbJ9rtfSBjfoQ9clWe0K+4fUHdJIuzW65AZsiLo9oh5IbHLWxlFP3Jg==", "dependencies": { "js-base64": "^3.7.5" }, "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-image": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.64.tgz", - "integrity": "sha512-1Aqqytx/z/Khecf5xrO++f/p5EQX4uG87TbbAmE0OQys/JgKMnNggDzqon5bpHboimLfQiFPw716NbTqMphjfw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.65.tgz", + "integrity": "sha512-Ud5FI5cGtpbz8yYCHC4QINlbC1K04Mex1JD5oAWPFwjlOz/Si/DhqbY1QBDl6QrUmSUUTZc5DKT3v3nN5WbZxQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-search": { - "version": "0.16.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.64.tgz", - "integrity": "sha512-vUsvTkEOFJwv8nVtiiGr/vTMeQhu62VkUejY2h1+yZagnVEusGVPU1JYoqBTLu5HM4cFiTGsJYXFI/0apASXYA==", + "version": "0.16.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.65.tgz", + "integrity": "sha512-eHfbbgFCS3AcD8YSvGFIkW9NW4pfGHrtRDWIojM/zqmyi3JaCmHUgZmlxbaANwBlgLiNpJLDq7cmoz//86NgGw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-serialize": { - "version": "0.14.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.64.tgz", - "integrity": "sha512-0AqVveTV3Pr9Lp+beJYOP5WuRvIrPSDGAK24da7BRGcLIKVq8pok1FdlM9jPeUbkX0DKo6Ortm77qeb2Z+n8+A==", + "version": "0.14.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.65.tgz", + "integrity": "sha512-NlvXVtFAHpLKEDzd+6/68yPFQ4Oe02jvQH6+a8p+gcxbSEyYj1l0sqqeABQ3gC5QDCmQepk6BQVB8Rpz/e4HgQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-unicode11": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.64.tgz", - "integrity": "sha512-3+PKu+DXFq32xlsYfnI058/T8dTY2tQhRpJLP2CNR/jVWk5uBkVO0dBV0Srqj5QOAlAhzzZuS6TbsVRXORptqw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.65.tgz", + "integrity": "sha512-sH9mu2GEIVuc6cs6HxsmCXn6KKzCa5D+Zyl1Pt9d2S4FKqSB17Fc4mVukCOMW7wUR9UChKTbxmByGJK+4xwdCA==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-webgl": { - "version": "0.19.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.64.tgz", - "integrity": "sha512-cxTkMPAXPQAZnWqahNu7ff9mbJvM1sQqKnZWiFZAHTsZXym4oa3KCB4pjH4didSyYkhkPY/17E8I0UOUpvv0Yw==", + "version": "0.19.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.65.tgz", + "integrity": "sha512-gPwP8ozqrLFWOlo9eh2I+acxq0Z6obG7GpL8HpJ+B+q6+vjfxoXHQ6vV04W90aoAvbLpScHcT/JtXA58GcH2vw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/headless": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.64.tgz", - "integrity": "sha512-my08kgH2K3CBEtBg/o8lamtD6BYNBv03Akq747Lajv0QzOiwan7B4r2xdbA6i9sovB+MdjFs0XP1ksc3EpKakg==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.65.tgz", + "integrity": "sha512-gQICZsBkFHQEb/K+dc+KN4u5aBwrDPgai0S7W8/KT7fqTPWz8Cgjq119WQLshnzfLeMMFPYGttNHFGUbpp/wmw==" }, "node_modules/@xterm/xterm": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.64.tgz", - "integrity": "sha512-iSKS6tQTFpoN5y487eptlxkUT0jqK5hrvtFQMLugMcQdn7gCUCiFGa4Z1RdqKYSGvAypka+b9gMKPrKWZ7Q3yQ==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.65.tgz", + "integrity": "sha512-o6IIg4hqs994gtSQMbzQM6OUeLIXPG6RUxjoref0KJX4PIa/BqQjwQLPuSxnjOFeRQIvhZ2mSAPfGWJQ6jEGAg==" }, "node_modules/agent-base": { "version": "7.1.1", diff --git a/remote/package.json b/remote/package.json index c107b048e45c0..236a6713ff4ca 100644 --- a/remote/package.json +++ b/remote/package.json @@ -15,14 +15,14 @@ "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "cookie": "^0.4.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", diff --git a/remote/web/package-lock.json b/remote/web/package-lock.json index b971ca265f03e..04199f4e652db 100644 --- a/remote/web/package-lock.json +++ b/remote/web/package-lock.json @@ -13,13 +13,13 @@ "@vscode/iconv-lite-umd": "0.7.0", "@vscode/tree-sitter-wasm": "^0.0.4", "@vscode/vscode-languagedetection": "1.0.21", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "jschardet": "3.1.3", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", @@ -87,60 +87,60 @@ } }, "node_modules/@xterm/addon-clipboard": { - "version": "0.2.0-beta.47", - "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.47.tgz", - "integrity": "sha512-mJHV1770gwVckj4mgjdxegt4zLL5WGCoJblTqaLbgEF7xOwsJUzvGk38qsZ4ZpdTa2ti76H0pkb1CpZGrXL9qg==", + "version": "0.2.0-beta.48", + "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.48.tgz", + "integrity": "sha512-oTrGoGMOQaW7PINAShhNR3duV8l2No/DbJ9rtfSBjfoQ9clWe0K+4fUHdJIuzW65AZsiLo9oh5IbHLWxlFP3Jg==", "dependencies": { "js-base64": "^3.7.5" }, "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-image": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.64.tgz", - "integrity": "sha512-1Aqqytx/z/Khecf5xrO++f/p5EQX4uG87TbbAmE0OQys/JgKMnNggDzqon5bpHboimLfQiFPw716NbTqMphjfw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.65.tgz", + "integrity": "sha512-Ud5FI5cGtpbz8yYCHC4QINlbC1K04Mex1JD5oAWPFwjlOz/Si/DhqbY1QBDl6QrUmSUUTZc5DKT3v3nN5WbZxQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-search": { - "version": "0.16.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.64.tgz", - "integrity": "sha512-vUsvTkEOFJwv8nVtiiGr/vTMeQhu62VkUejY2h1+yZagnVEusGVPU1JYoqBTLu5HM4cFiTGsJYXFI/0apASXYA==", + "version": "0.16.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.65.tgz", + "integrity": "sha512-eHfbbgFCS3AcD8YSvGFIkW9NW4pfGHrtRDWIojM/zqmyi3JaCmHUgZmlxbaANwBlgLiNpJLDq7cmoz//86NgGw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-serialize": { - "version": "0.14.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.64.tgz", - "integrity": "sha512-0AqVveTV3Pr9Lp+beJYOP5WuRvIrPSDGAK24da7BRGcLIKVq8pok1FdlM9jPeUbkX0DKo6Ortm77qeb2Z+n8+A==", + "version": "0.14.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.65.tgz", + "integrity": "sha512-NlvXVtFAHpLKEDzd+6/68yPFQ4Oe02jvQH6+a8p+gcxbSEyYj1l0sqqeABQ3gC5QDCmQepk6BQVB8Rpz/e4HgQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-unicode11": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.64.tgz", - "integrity": "sha512-3+PKu+DXFq32xlsYfnI058/T8dTY2tQhRpJLP2CNR/jVWk5uBkVO0dBV0Srqj5QOAlAhzzZuS6TbsVRXORptqw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.65.tgz", + "integrity": "sha512-sH9mu2GEIVuc6cs6HxsmCXn6KKzCa5D+Zyl1Pt9d2S4FKqSB17Fc4mVukCOMW7wUR9UChKTbxmByGJK+4xwdCA==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-webgl": { - "version": "0.19.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.64.tgz", - "integrity": "sha512-cxTkMPAXPQAZnWqahNu7ff9mbJvM1sQqKnZWiFZAHTsZXym4oa3KCB4pjH4didSyYkhkPY/17E8I0UOUpvv0Yw==", + "version": "0.19.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.65.tgz", + "integrity": "sha512-gPwP8ozqrLFWOlo9eh2I+acxq0Z6obG7GpL8HpJ+B+q6+vjfxoXHQ6vV04W90aoAvbLpScHcT/JtXA58GcH2vw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/xterm": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.64.tgz", - "integrity": "sha512-iSKS6tQTFpoN5y487eptlxkUT0jqK5hrvtFQMLugMcQdn7gCUCiFGa4Z1RdqKYSGvAypka+b9gMKPrKWZ7Q3yQ==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.65.tgz", + "integrity": "sha512-o6IIg4hqs994gtSQMbzQM6OUeLIXPG6RUxjoref0KJX4PIa/BqQjwQLPuSxnjOFeRQIvhZ2mSAPfGWJQ6jEGAg==" }, "node_modules/js-base64": { "version": "3.7.7", diff --git a/remote/web/package.json b/remote/web/package.json index 27be6a503bdc7..a4a18b9369cb0 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -8,13 +8,13 @@ "@vscode/iconv-lite-umd": "0.7.0", "@vscode/tree-sitter-wasm": "^0.0.4", "@vscode/vscode-languagedetection": "1.0.21", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "jschardet": "3.1.3", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", From 4d7a7a45e3ca33c2e10b2f95342f9746c6258969 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 28 Sep 2024 06:54:31 -0700 Subject: [PATCH 26/27] Add support for links 'foo(l:c)' and 'foo (l:c)' Fixes #229842 --- .../links/browser/terminalLinkParsing.ts | 11 ++++++++--- .../links/test/browser/terminalLinkParsing.test.ts | 4 ++++ .../test/browser/terminalLocalLinkDetector.test.ts | 4 ++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts index 7f148d7fecf15..4ff47d600d311 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts @@ -109,14 +109,19 @@ function generateLinkSuffixRegex(eolOnly: boolean) { // "foo", lines 339-341 [#171880] // "foo", lines 339-341, characters 12-789 [#178287] `['"]?(?:,? |: ?| on )lines? ${r()}(?:-${re()})?(?:,? (?:col(?:umn)?|characters?) ${c()}(?:-${ce()})?)?` + eolSuffix, + // () and [] are interchangeable // foo(339) // foo(339,12) // foo(339, 12) // foo (339) - // ... + // foo (339,12) + // foo (339, 12) // foo: (339) - // ... - `:? ?[\\[\\(]${r()}(?:, ?${c()})?[\\]\\)]` + eolSuffix, + // foo: (339,12) + // foo: (339, 12) + // foo(339:12) [#229842] + // foo (339:12) [#229842] + `:? ?[\\[\\(]${r()}(?:(?:, ?|:)${c()})?[\\]\\)]` + eolSuffix, ]; const suffixClause = lineAndColumnRegexClauses diff --git a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts index 3f61393ab7110..099e639ee820e 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts @@ -125,6 +125,8 @@ const testLinks: ITestLink[] = [ { link: 'foo: (339)', prefix: undefined, suffix: ': (339)', hasRow: true, hasCol: false }, { link: 'foo: (339,12)', prefix: undefined, suffix: ': (339,12)', hasRow: true, hasCol: true }, { link: 'foo: (339, 12)', prefix: undefined, suffix: ': (339, 12)', hasRow: true, hasCol: true }, + { link: 'foo(339:12)', prefix: undefined, suffix: '(339:12)', hasRow: true, hasCol: true }, + { link: 'foo (339:12)', prefix: undefined, suffix: ' (339:12)', hasRow: true, hasCol: true }, // Square brackets { link: 'foo[339]', prefix: undefined, suffix: '[339]', hasRow: true, hasCol: false }, @@ -136,6 +138,8 @@ const testLinks: ITestLink[] = [ { link: 'foo: [339]', prefix: undefined, suffix: ': [339]', hasRow: true, hasCol: false }, { link: 'foo: [339,12]', prefix: undefined, suffix: ': [339,12]', hasRow: true, hasCol: true }, { link: 'foo: [339, 12]', prefix: undefined, suffix: ': [339, 12]', hasRow: true, hasCol: true }, + { link: 'foo[339:12]', prefix: undefined, suffix: '[339:12]', hasRow: true, hasCol: true }, + { link: 'foo [339:12]', prefix: undefined, suffix: ' [339:12]', hasRow: true, hasCol: true }, // OCaml-style { link: '"foo", line 339, character 12', prefix: '"', suffix: '", line 339, character 12', hasRow: true, hasCol: true }, diff --git a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts index 70d503f1526ef..df3d642769a3e 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts @@ -110,6 +110,8 @@ const supportedLinkFormats: LinkFormatInfo[] = [ { urlFormat: '{0}({1}, {2})', line: '5', column: '3' }, { urlFormat: '{0} ({1}, {2})', line: '5', column: '3' }, { urlFormat: '{0}: ({1}, {2})', line: '5', column: '3' }, + { urlFormat: '{0}({1}:{2})', line: '5', column: '3' }, + { urlFormat: '{0} ({1}:{2})', line: '5', column: '3' }, { urlFormat: '{0}:{1}', line: '5' }, { urlFormat: '{0}:{1}:{2}', line: '5', column: '3' }, { urlFormat: '{0} {1}:{2}', line: '5', column: '3' }, @@ -121,6 +123,8 @@ const supportedLinkFormats: LinkFormatInfo[] = [ { urlFormat: '{0}[{1}, {2}]', line: '5', column: '3' }, { urlFormat: '{0} [{1}, {2}]', line: '5', column: '3' }, { urlFormat: '{0}: [{1}, {2}]', line: '5', column: '3' }, + { urlFormat: '{0}[{1}:{2}]', line: '5', column: '3' }, + { urlFormat: '{0} [{1}:{2}]', line: '5', column: '3' }, { urlFormat: '{0}",{1}', line: '5' }, { urlFormat: '{0}\',{1}', line: '5' }, { urlFormat: '{0}#{1}', line: '5' }, From 2b0935aea31f7e866fde758786aec27d3ab7a9c4 Mon Sep 17 00:00:00 2001 From: Tomer Chachamu Date: Sat, 28 Sep 2024 16:51:15 +0100 Subject: [PATCH 27/27] Fix scrolling of Test Results when a new test starts (fixes #229531) (#229532) --- .../testing/browser/testResultsView/testResultsOutput.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts b/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts index 3a07a2806feda..11350dd2893dc 100644 --- a/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts +++ b/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts @@ -353,9 +353,8 @@ export class TerminalMessagePeek extends Disposable implements IPeekOutputRender if (prev) { prev.xterm.clearBuffer(); prev.xterm.clearSearchDecorations(); - // clearBuffer tries to retain the prompt line, but this doesn't exist for tests. - // So clear the screen (J) and move to home (H) to ensure previous data is cleaned up. - prev.xterm.write(`\x1b[2J\x1b[0;0H`); + // clearBuffer tries to retain the prompt. Reset prompt, scrolling state, etc. + prev.xterm.write(`\x1bc`); return prev; }