From eb79f015555c391313d120013bf0b01feaec84d4 Mon Sep 17 00:00:00 2001 From: leopardracer <136604165+leopardracer@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:17:36 +0200 Subject: [PATCH 01/15] Update snippetSession.ts --- src/vs/editor/contrib/snippet/browser/snippetSession.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/snippet/browser/snippetSession.ts b/src/vs/editor/contrib/snippet/browser/snippetSession.ts index 34bf99e7d4a56..79cf57b3abf39 100644 --- a/src/vs/editor/contrib/snippet/browser/snippetSession.ts +++ b/src/vs/editor/contrib/snippet/browser/snippetSession.ts @@ -471,7 +471,7 @@ export class SnippetSession { const readClipboardText = () => clipboardText; // know what text the overwrite[Before|After] extensions - // of the primary curser have selected because only when + // of the primary cursor have selected because only when // secondary selections extend to the same text we can grow them const firstBeforeText = model.getValueInRange(SnippetSession.adjustSelection(model, editor.getSelection(), overwriteBefore, 0)); const firstAfterText = model.getValueInRange(SnippetSession.adjustSelection(model, editor.getSelection(), 0, overwriteAfter)); @@ -530,7 +530,7 @@ export class SnippetSession { ])); // store snippets with the index of their originating selection. - // that ensures the primiary cursor stays primary despite not being + // that ensures the primary cursor stays primary despite not being // the one with lowest start position edits[idx] = EditOperation.replace(snippetSelection, snippet.toString()); edits[idx].identifier = { major: idx, minor: 0 }; // mark the edit so only our undo edits will be used to generate end cursors From afd7c3ccb38f580dced00040f65b6eae719c7908 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 13 Dec 2024 19:45:19 +0100 Subject: [PATCH 02/15] fixing incorrect hover size after resize of other hover (#236078) * fixing incorrect sizing after resize * replacing line --- src/vs/editor/contrib/hover/browser/contentHoverWidget.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts b/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts index ffb8aaa9f115d..fdfc464bc048d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts +++ b/src/vs/editor/contrib/hover/browser/contentHoverWidget.ts @@ -138,6 +138,7 @@ export class ContentHoverWidget extends ResizableContentWidget { private _setHoverWidgetMaxDimensions(width: number | string, height: number | string): void { ContentHoverWidget._applyMaxDimensions(this._hover.contentsDomNode, width, height); + ContentHoverWidget._applyMaxDimensions(this._hover.scrollbar.getDomNode(), width, height); ContentHoverWidget._applyMaxDimensions(this._hover.containerDomNode, width, height); this._hover.containerDomNode.style.setProperty('--vscode-hover-maxWidth', typeof width === 'number' ? `${width}px` : width); this._layoutContentWidget(); @@ -145,9 +146,7 @@ export class ContentHoverWidget extends ResizableContentWidget { private _setAdjustedHoverWidgetDimensions(size: dom.Dimension): void { this._setHoverWidgetMaxDimensions('none', 'none'); - const width = size.width; - const height = size.height; - this._setHoverWidgetDimensions(width, height); + this._setHoverWidgetDimensions(size.width, size.height); } private _updateResizableNodeMaxDimensions(): void { @@ -297,6 +296,7 @@ export class ContentHoverWidget extends ResizableContentWidget { private _updateMaxDimensions() { const height = Math.max(this._editor.getLayoutInfo().height / 4, 250, ContentHoverWidget._lastDimensions.height); const width = Math.max(this._editor.getLayoutInfo().width * 0.66, 750, ContentHoverWidget._lastDimensions.width); + this._resizableNode.maxSize = new dom.Dimension(width, height); this._setHoverWidgetMaxDimensions(width, height); } @@ -304,7 +304,6 @@ export class ContentHoverWidget extends ResizableContentWidget { this._setRenderedHover(renderedHover); this._updateFont(); this._updateContent(renderedHover.domNode); - this._updateMaxDimensions(); this.onContentsChanged(); // Simply force a synchronous render on the editor // such that the widget does not really render with left = '0px' @@ -371,6 +370,7 @@ export class ContentHoverWidget extends ResizableContentWidget { const layoutInfo = this._editor.getLayoutInfo(); this._resizableNode.layout(layoutInfo.height, layoutInfo.width); this._setHoverWidgetDimensions('auto', 'auto'); + this._updateMaxDimensions(); } public setMinimumDimensions(dimensions: dom.Dimension): void { From afd3f0abf02675155a01770b7f45fcf3bb9202d6 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Fri, 13 Dec 2024 14:19:39 -0600 Subject: [PATCH 03/15] Check whether commands are executable before including them in terminal suggestions (#235997) --- .../src/terminalSuggestMain.ts | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/extensions/terminal-suggest/src/terminalSuggestMain.ts b/extensions/terminal-suggest/src/terminalSuggestMain.ts index 04af5ff5da937..c7cdf75406e20 100644 --- a/extensions/terminal-suggest/src/terminalSuggestMain.ts +++ b/extensions/terminal-suggest/src/terminalSuggestMain.ts @@ -168,6 +168,24 @@ function createCompletionItem(commandLine: string, cursorPosition: number, prefi }; } +async function isExecutable(filePath: string): Promise { + // Windows doesn't have the concept of an executable bit and running any + // file is possible. We considered using $PATHEXT here but since it's mostly + // there for legacy reasons and it would be easier and more intuitive to add + // a setting if needed instead. + if (osIsWindows()) { + return true; + } + try { + const stats = await fs.stat(filePath); + // On macOS/Linux, check if the executable bit is set + return (stats.mode & 0o100) !== 0; + } catch (error) { + // If the file does not exist or cannot be accessed, it's not executable + return false; + } +} + async function getCommandsInPath(): Promise | undefined> { if (cachedAvailableCommands) { return cachedAvailableCommands; @@ -176,7 +194,7 @@ async function getCommandsInPath(): Promise | undefined> { if (!paths) { return; } - + const pathSeparator = osIsWindows() ? '\\' : '/'; const executables = new Set(); for (const path of paths) { try { @@ -187,7 +205,7 @@ async function getCommandsInPath(): Promise | undefined> { const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(path)); for (const [file, fileType] of files) { - if (fileType !== vscode.FileType.Unknown && fileType !== vscode.FileType.Directory) { + if (fileType !== vscode.FileType.Unknown && fileType !== vscode.FileType.Directory && await isExecutable(path + pathSeparator + file)) { executables.add(file); } } From c1189b5a8e38e66a154eb07e28957c8beff587d0 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Fri, 13 Dec 2024 14:45:20 -0600 Subject: [PATCH 04/15] add aria label for disable/enable current file context button (#236077) fix #236076 --- .../chat/browser/attachments/implicitContextAttachment.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts b/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts index 73ab2960823fa..dfff8cee32bbc 100644 --- a/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts +++ b/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.ts @@ -79,6 +79,7 @@ export class ImplicitContextAttachmentWidget extends Disposable { this._register(this.hoverService.setupManagedHover(getDefaultHoverDelegate('element'), hintElement, title)); const buttonMsg = this.attachment.enabled ? localize('disable', "Disable current file context") : localize('enable', "Enable current file context"); + this.domNode.ariaLabel = buttonMsg; const toggleButton = this.renderDisposables.add(new Button(this.domNode, { supportIcons: true, title: buttonMsg })); toggleButton.icon = this.attachment.enabled ? Codicon.eye : Codicon.eyeClosed; this.renderDisposables.add(toggleButton.onDidClick((e) => { From 899afc031137585826b56aa200aca155a785a319 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Fri, 13 Dec 2024 22:01:05 +0100 Subject: [PATCH 05/15] Git - ignore changes reported to the submodule folder (#205125) (#236098) --- extensions/git/src/repository.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 73a54cef4afaa..2465bd80bc439 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -2385,7 +2385,16 @@ export class Repository implements Disposable { } switch (raw.y) { - case 'M': workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.MODIFIED, useIcons, renameUri)); break; + case 'M': { + // https://git-scm.com/docs/git-status#_porcelain_format_version_1 + // When using `-z` with the porcelain v1 format any submodule changes + // are reported as modified M instead of m or single ?. Due to that we + // will ignore any changes reported for the submodule folder. + if (this.submodules.every(s => !pathEquals(s.path, raw.path))) { + workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.MODIFIED, useIcons, renameUri)); + } + break; + } case 'D': workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.DELETED, useIcons, renameUri)); break; case 'A': workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.INTENT_TO_ADD, useIcons, renameUri)); break; case 'R': workingTreeGroup.push(new Resource(this.resourceCommandResolver, ResourceGroupType.WorkingTree, uri, Status.INTENT_TO_RENAME, useIcons, renameUri)); break; From f7cbfef520f09f4c36c9f510a4f9c67e3f2c0cc9 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 13 Dec 2024 13:26:02 -0800 Subject: [PATCH 06/15] extensions: warn folks not to change the debug worker name :P (#236104) Refs #232544 --- .../extensions/worker/webWorkerExtensionHostIframe.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html index 88407e89f1662..372f26d51e9f1 100644 --- a/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html +++ b/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html @@ -4,7 +4,7 @@ @@ -12,6 +12,8 @@ (function () { const searchParams = new URL(document.location.href).searchParams; const vscodeWebWorkerExtHostId = searchParams.get('vscodeWebWorkerExtHostId') || ''; + // DO NOT CHANGE the name of the worker without also updating js-debug, as that + // is used to filter targets to attach to (e.g. #232544) const name = searchParams.get('debugged') ? 'DebugExtensionHostWorker' : 'ExtensionHostWorker'; const parentOrigin = searchParams.get('parentOrigin') || window.origin; const salt = searchParams.get('salt'); From af9502d4b1425e076e05b02850363b227bf9316e Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 13 Dec 2024 13:38:11 -0800 Subject: [PATCH 07/15] fix: don't cut off focus border for chat editing Add Files button (#236102) --- src/vs/workbench/contrib/chat/browser/chatInputPart.ts | 2 +- src/vs/workbench/contrib/chat/browser/media/chat.css | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index 78b8a6628af09..2c3d2e0a19bac 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -1282,7 +1282,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge })); dom.append(addFilesElement, button.element); - // REALTED files (after Add Files...) + // RELATED files (after Add Files...) for (const [uri, metadata] of chatEditingSession.workingSet) { if (metadata.state !== WorkingSetEntryState.Suggested) { continue; diff --git a/src/vs/workbench/contrib/chat/browser/media/chat.css b/src/vs/workbench/contrib/chat/browser/media/chat.css index b93329f8ddf17..f906562163756 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chat.css +++ b/src/vs/workbench/contrib/chat/browser/media/chat.css @@ -661,6 +661,7 @@ have to be updated for changes to the rules above, or to support more deeply nes } .interactive-session .chat-editing-session .chat-editing-session-toolbar-actions .monaco-button.secondary:first-child { + margin: 3px 0px 3px 3px; flex-shrink: 0; } From c921e57456cb5721151fcef69e21f73a1cb221c5 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 13 Dec 2024 13:47:11 -0800 Subject: [PATCH 08/15] fix: add aria label for chat working set (#236106) fix: add aria label for working set region --- src/vs/workbench/contrib/chat/browser/chatInputPart.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts index 2c3d2e0a19bac..5ee4df949459b 100644 --- a/src/vs/workbench/contrib/chat/browser/chatInputPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatInputPart.ts @@ -1166,6 +1166,8 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge } else { suggestedFilesInWorkingSetCount = entries.filter(e => e.kind === 'reference' && e.state === WorkingSetEntryState.Suggested).length; } + overviewTitle.ariaLabel = overviewTitle.textContent; + overviewTitle.tabIndex = 0; if (excludedEntries.length > 0) { overviewFileCount.textContent = ' ' + localize('chatEditingSession.excludedFiles', '({0}/{1} files)', this.chatEditingService.editingSessionFileLimit + excludedEntries.length, this.chatEditingService.editingSessionFileLimit); From 0d676289ff74ffd00571a4dcce4ef80af2dfefda Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Fri, 13 Dec 2024 14:40:29 -0800 Subject: [PATCH 09/15] fix: reduce race timeout for getting chat related files (#236108) --- .../contrib/chat/browser/contrib/chatInputCompletions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.ts index 06a7bd3c9121c..bf5dfa67cef02 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.ts @@ -564,7 +564,7 @@ class BuiltinDynamicCompletions extends Disposable { // RELATED FILES if (widget.location === ChatAgentLocation.EditingSession && widget.viewModel && this._chatEditingService.currentEditingSessionObs.get()?.chatSessionId === widget.viewModel?.sessionId) { - const relatedFiles = (await raceTimeout(this._chatEditingService.getRelatedFiles(widget.viewModel.sessionId, widget.getInput(), token), 1000)) ?? []; + const relatedFiles = (await raceTimeout(this._chatEditingService.getRelatedFiles(widget.viewModel.sessionId, widget.getInput(), token), 200)) ?? []; for (const relatedFileGroup of relatedFiles) { for (const relatedFile of relatedFileGroup.files) { if (seen.has(relatedFile.uri)) { From eb70dfe409b18664d5fafe9d4bcf1ff8fbbade68 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 13 Dec 2024 15:20:34 -0800 Subject: [PATCH 10/15] testing: fix transparent background in test error badges artifacting (#236109) --- .../contrib/testing/browser/media/testing.css | 2 -- .../contrib/testing/browser/theme.ts | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/testing/browser/media/testing.css b/src/vs/workbench/contrib/testing/browser/media/testing.css index cafaaac4dd7a3..2ebd1fc35bca5 100644 --- a/src/vs/workbench/contrib/testing/browser/media/testing.css +++ b/src/vs/workbench/contrib/testing/browser/media/testing.css @@ -414,7 +414,6 @@ .monaco-workbench .test-error-content-widget .inner { margin-left: 20px; color: var(--vscode-testing-message-error-badgeForeground) !important; - background: var(--vscode-testing-message-error-badgeBackground); border-top-right-radius: 2px; border-bottom-right-radius: 2px; padding-right: 3px; @@ -452,7 +451,6 @@ top: -1px; width: 15px; left: -10px; - fill: var(--vscode-testing-message-error-badgeBackground); z-index: -1; stroke-width: 0.71px; /* 1 / sqrt(2) */ stroke: var(--vscode-testing-message-error-badgeBorder); diff --git a/src/vs/workbench/contrib/testing/browser/theme.ts b/src/vs/workbench/contrib/testing/browser/theme.ts index 439e1f765fa7c..b41f5828a9771 100644 --- a/src/vs/workbench/contrib/testing/browser/theme.ts +++ b/src/vs/workbench/contrib/testing/browser/theme.ts @@ -183,7 +183,6 @@ export const testStatesToRetiredIconColors: { [K in TestResultState]?: string } registerThemingParticipant((theme, collector) => { const editorBg = theme.getColor(editorBackground); - const missBadgeBackground = editorBg && theme.getColor(testingUncoveredBackground)?.transparent(2).makeOpaque(editorBg); collector.addRule(` .coverage-deco-inline.coverage-deco-hit.coverage-deco-hovered { @@ -194,9 +193,22 @@ registerThemingParticipant((theme, collector) => { background: ${theme.getColor(testingUncoveredBackground)?.transparent(1.3)}; outline-color: ${theme.getColor(testingUncoveredBorder)?.transparent(2)}; } - .coverage-deco-branch-miss-indicator::before { - border-color: ${missBadgeBackground?.transparent(1.3)}; - background-color: ${missBadgeBackground}; + `); + + if (editorBg) { + const missBadgeBackground = theme.getColor(testingUncoveredBackground)?.transparent(2).makeOpaque(editorBg); + const errorBadgeBackground = theme.getColor(messageBadgeBackground)?.makeOpaque(editorBg); + collector.addRule(` + .coverage-deco-branch-miss-indicator::before { + border-color: ${missBadgeBackground?.transparent(1.3)}; + background-color: ${missBadgeBackground}; + } + .monaco-workbench .test-error-content-widget .inner{ + background: ${errorBadgeBackground}; + } + .monaco-workbench .test-error-content-widget .inner .arrow svg { + fill: ${errorBadgeBackground}; + } + `); } - `); }); From cdec0c6a14aeeae336c3467a7fa156f2cde6945f Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 13 Dec 2024 15:53:23 -0800 Subject: [PATCH 11/15] testing: improve performance of filtering file tests (#236112) Fixes #235819. Probably. --- .../common/mainThreadTestCollection.ts | 7 ++- .../contrib/testing/common/testService.ts | 45 ++++++++++++++----- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/testing/common/mainThreadTestCollection.ts b/src/vs/workbench/contrib/testing/common/mainThreadTestCollection.ts index 1a691a3c80f17..bff443281f651 100644 --- a/src/vs/workbench/contrib/testing/common/mainThreadTestCollection.ts +++ b/src/vs/workbench/contrib/testing/common/mainThreadTestCollection.ts @@ -5,6 +5,7 @@ import { Emitter } from '../../../../base/common/event.js'; import { Iterable } from '../../../../base/common/iterator.js'; +import { LinkedList } from '../../../../base/common/linkedList.js'; import { ResourceMap } from '../../../../base/common/map.js'; import { URI } from '../../../../base/common/uri.js'; import { IMainThreadTestCollection } from './testService.js'; @@ -184,8 +185,10 @@ export class MainThreadTestCollection extends AbstractIncrementalTestCollection< } private *getIterator() { - const queue = [this.rootIds]; - while (queue.length) { + const queue = new LinkedList>(); + queue.push(this.rootIds); + + while (queue.size > 0) { for (const id of queue.pop()!) { const node = this.getNodeById(id)!; yield node; diff --git a/src/vs/workbench/contrib/testing/common/testService.ts b/src/vs/workbench/contrib/testing/common/testService.ts index fe1d04bc441ba..f75e3145ae803 100644 --- a/src/vs/workbench/contrib/testing/common/testService.ts +++ b/src/vs/workbench/contrib/testing/common/testService.ts @@ -8,6 +8,7 @@ import { CancellationToken } from '../../../../base/common/cancellation.js'; import { Event } from '../../../../base/common/event.js'; import { Iterable } from '../../../../base/common/iterator.js'; import { IDisposable } from '../../../../base/common/lifecycle.js'; +import { LinkedList } from '../../../../base/common/linkedList.js'; import { MarshalledId } from '../../../../base/common/marshallingIds.js'; import { IObservable } from '../../../../base/common/observable.js'; import { IPrefixTreeNode, WellDefinedPrefixTree } from '../../../../base/common/prefixTree.js'; @@ -172,24 +173,44 @@ const waitForTestToBeIdle = (testService: ITestService, test: IncrementalTestCol * in strictly descending order. */ export const testsInFile = async function* (testService: ITestService, ident: IUriIdentityService, uri: URI, waitForIdle = true): AsyncIterable { - for (const test of testService.collection.all) { - if (!test.item.uri) { - continue; - } + const queue = new LinkedList>(); - if (ident.extUri.isEqual(uri, test.item.uri)) { - yield test; - } + const existing = [...testService.collection.getNodeByUrl(uri)]; + queue.push(existing.length ? existing.map(e => e.item.extId) : testService.collection.rootIds); - if (ident.extUri.isEqualOrParent(uri, test.item.uri)) { - if (test.expand === TestItemExpandState.Expandable) { - await testService.collection.expand(test.item.extId, 1); + let n = 0; + while (queue.size > 0) { + for (const id of queue.pop()!) { + n++; + const test = testService.collection.getNodeById(id); + if (!test) { + continue; // possible because we expand async and things could delete + } + + if (!test.item.uri) { + queue.push(test.children); + continue; + } + + if (ident.extUri.isEqual(uri, test.item.uri)) { + yield test; } - if (waitForIdle) { - await waitForTestToBeIdle(testService, test); + + if (ident.extUri.isEqualOrParent(uri, test.item.uri)) { + if (test.expand === TestItemExpandState.Expandable) { + await testService.collection.expand(test.item.extId, 1); + } + if (waitForIdle) { + await waitForTestToBeIdle(testService, test); + } + + if (test.children.size) { + queue.push(test.children); + } } } } + console.log('iterated', n, 'times'); }; /** From 31092ac1a0f9e68026cd0796f184fd3dfe978069 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 13 Dec 2024 17:40:57 -0800 Subject: [PATCH 12/15] debug: fix remote attach fails without message (#236117) Fixes #235722 --- src/vs/workbench/contrib/debug/node/debugAdapter.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/workbench/contrib/debug/node/debugAdapter.ts b/src/vs/workbench/contrib/debug/node/debugAdapter.ts index 7c2b2e68307c2..4892338a1c1a6 100644 --- a/src/vs/workbench/contrib/debug/node/debugAdapter.ts +++ b/src/vs/workbench/contrib/debug/node/debugAdapter.ts @@ -114,6 +114,11 @@ export abstract class NetworkDebugAdapter extends StreamDebugAdapter { }); this.socket.on('error', error => { + // On ipv6 posix this can be an AggregateError which lacks a message. Use the first. + if (error instanceof AggregateError) { + error = error.errors[0]; + } + if (connected) { this._onError.fire(error); } else { From 1dc517c0a43a1df7730023b68533f9e3158b648d Mon Sep 17 00:00:00 2001 From: Jawad Najar <113301432+janajar@users.noreply.github.com> Date: Sat, 14 Dec 2024 09:39:46 -0500 Subject: [PATCH 13/15] Fix: When no results in search editor it throws an error (#235031) * Fix: issue #233200 Added a null check for matchRange in the iterateThroughMatches function to ensure setSelection is only called with valid arguments. * Revert package.json and package-lock.json to original states --------- Co-authored-by: Aly Ayyob <113083026+aayyob@users.noreply.github.com> --- src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts index 12423a7f38fc6..841b309d3648c 100644 --- a/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts +++ b/src/vs/workbench/contrib/searchEditor/browser/searchEditor.ts @@ -454,6 +454,7 @@ export class SearchEditor extends AbstractTextCodeEditor if (!matchRanges) { return; } const matchRange = (reverse ? findPrevRange : findNextRange)(matchRanges, currentPosition); + if (!matchRange) { return; } this.searchResultEditor.setSelection(matchRange); this.searchResultEditor.revealLineInCenterIfOutsideViewport(matchRange.startLineNumber); From 7606e11e89e5cce00cfb0959c4d2d97ffd477472 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sat, 14 Dec 2024 17:22:14 +0100 Subject: [PATCH 14/15] fix #235878 (#236129) --- .../common/extensionManagement.ts | 12 ++++++++++-- .../extensions/browser/extensionEditor.ts | 16 +++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index 2d6713d409d09..ba8a8e86feefd 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -12,7 +12,7 @@ import { Platform } from '../../../base/common/platform.js'; import { URI } from '../../../base/common/uri.js'; import { localize2 } from '../../../nls.js'; import { ExtensionType, IExtension, IExtensionManifest, TargetPlatform } from '../../extensions/common/extensions.js'; -import { IFileService } from '../../files/common/files.js'; +import { FileOperationError, FileOperationResult, IFileService, IFileStat } from '../../files/common/files.js'; import { createDecorator } from '../../instantiation/common/instantiation.js'; export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$'; @@ -640,7 +640,15 @@ export interface IAllowedExtensionsService { } export async function computeSize(location: URI, fileService: IFileService): Promise { - const stat = await fileService.resolve(location); + let stat: IFileStat; + try { + stat = await fileService.resolve(location); + } catch (e) { + if ((e).fileOperationResult === FileOperationResult.FILE_NOT_FOUND) { + return 0; + } + throw e; + } if (stat.children) { const sizes = await Promise.all(stat.children.map(c => computeSize(c.resource, fileService))); return sizes.reduce((r, s) => r + s, 0); diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index d5d8e0b3cd61c..a47806e80f404 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -1157,12 +1157,14 @@ class AdditionalDetailsWidget extends Disposable { $('div.more-info-entry-name', undefined, localize('id', "Identifier")), $('code', undefined, extension.identifier.id) )); - append(installInfo, - $('.more-info-entry', undefined, - $('div.more-info-entry-name', undefined, localize('Version', "Version")), - $('code', undefined, extension.manifest.version) - ) - ); + if (extension.type !== ExtensionType.System) { + append(installInfo, + $('.more-info-entry', undefined, + $('div.more-info-entry-name', undefined, localize('Version', "Version")), + $('code', undefined, extension.manifest.version) + ) + ); + } if (extension.installedTimestamp) { append(installInfo, $('.more-info-entry', undefined, @@ -1171,7 +1173,7 @@ class AdditionalDetailsWidget extends Disposable { ) ); } - if (extension.source !== 'gallery') { + if (!extension.isBuiltin && extension.source !== 'gallery') { const element = $('div', undefined, extension.source === 'vsix' ? localize('vsix', "VSIX") : localize('other', "Local")); append(installInfo, $('.more-info-entry', undefined, From 6fb1f6fbdd167ca4599f6ad28323257c3704a777 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Sat, 14 Dec 2024 17:22:39 +0100 Subject: [PATCH 15/15] fix #168779 (#236125) --- .../browser/userDataSyncWorkbenchService.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts index ddfd1f0553fde..6a1eb065c6c19 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts @@ -6,7 +6,7 @@ import { IUserDataSyncService, IAuthenticationProvider, isAuthenticationProvider, IUserDataAutoSyncService, IUserDataSyncStoreManagementService, SyncStatus, IUserDataSyncEnablementService, IUserDataSyncResource, IResourcePreview, USER_DATA_SYNC_SCHEME, USER_DATA_SYNC_LOG_ID, } from '../../../../platform/userDataSync/common/userDataSync.js'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; -import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNC_LOG_COMMAND_ID, CONTEXT_ENABLE_ACTIVITY_VIEWS, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_CONFLICTS_VIEW_ID, CONTEXT_ENABLE_SYNC_CONFLICTS_VIEW, CONTEXT_HAS_CONFLICTS, IUserDataSyncConflictsView } from '../common/userDataSync.js'; +import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNC_LOG_COMMAND_ID, CONTEXT_ENABLE_ACTIVITY_VIEWS, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_CONFLICTS_VIEW_ID, CONTEXT_ENABLE_SYNC_CONFLICTS_VIEW, CONTEXT_HAS_CONFLICTS, IUserDataSyncConflictsView, getSyncAreaLabel } from '../common/userDataSync.js'; import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js'; import { Emitter, Event } from '../../../../base/common/event.js'; import { getCurrentAuthenticationSessionInfo } from '../../authentication/browser/authenticationService.js'; @@ -403,9 +403,21 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat } private async handleConflictsWhileTurningOn(token: CancellationToken): Promise { + const conflicts = this.userDataSyncService.conflicts; + const andSeparator = localize('and', ' and '); + let conflictsText = ''; + for (let i = 0; i < conflicts.length; i++) { + if (i === conflicts.length - 1 && i !== 0) { + conflictsText += andSeparator; + } else if (i !== 0) { + conflictsText += ', '; + } + conflictsText += getSyncAreaLabel(conflicts[i].syncResource); + } + const singleConflictResource = conflicts.length === 1 ? getSyncAreaLabel(conflicts[0].syncResource) : undefined; await this.dialogService.prompt({ type: Severity.Warning, - message: localize('conflicts detected', "Conflicts Detected"), + message: localize('conflicts detected', "Conflicts Detected in {0}", conflictsText), detail: localize('resolve', "Please resolve conflicts to turn on..."), buttons: [ { @@ -417,11 +429,11 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat } }, { - label: localize({ key: 'replace local', comment: ['&& denotes a mnemonic'] }, "Replace &&Local"), + label: singleConflictResource ? localize({ key: 'replace local single', comment: ['&& denotes a mnemonic'] }, "Accept &&Remote {0}", singleConflictResource) : localize({ key: 'replace local', comment: ['&& denotes a mnemonic'] }, "Accept &&Remote"), run: async () => this.replace(true) }, { - label: localize({ key: 'replace remote', comment: ['&& denotes a mnemonic'] }, "Replace &&Remote"), + label: singleConflictResource ? localize({ key: 'replace remote single', comment: ['&& denotes a mnemonic'] }, "Accept &&Local {0}", singleConflictResource) : localize({ key: 'replace remote', comment: ['&& denotes a mnemonic'] }, "Accept &&Local"), run: () => this.replace(false) }, ],