From f1be6ea0a69cefb51af6e504ee8494e92511c493 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 27 Jul 2023 16:58:14 -0700 Subject: [PATCH 001/198] Set title and icon on chat view directly Fix microsoft/vscode-copilot-release#342 --- .../contrib/chat/browser/chatContributionServiceImpl.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts b/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts index 0176f7c10b6..e018afb26b0 100644 --- a/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts @@ -105,12 +105,15 @@ export class ChatContributionService implements IChatContributionService { } private registerChatProvider(extension: Readonly, providerDescriptor: IRawChatProviderContribution): IDisposable { + const icon = providerDescriptor.icon ? resources.joinPath(extension.extensionLocation, providerDescriptor.icon) : Codicon.commentDiscussion; + const title = localize('chat.viewContainer.label', "Chat"); + // Register View Container const viewContainerId = CHAT_SIDEBAR_PANEL_ID + '.' + providerDescriptor.id; const viewContainer: ViewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer({ id: viewContainerId, - title: localize('chat.viewContainer.label', "Chat"), - icon: providerDescriptor.icon ? resources.joinPath(extension.extensionLocation, providerDescriptor.icon) : Codicon.commentDiscussion, + title, + icon, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [viewContainerId, { mergeViewWithContainerWhenSingleView: true }]), storageId: viewContainerId, hideIfEmpty: true, @@ -121,6 +124,8 @@ export class ChatContributionService implements IChatContributionService { const viewId = this.getViewIdForProvider(providerDescriptor.id); const viewDescriptor: IViewDescriptor[] = [{ id: viewId, + containerIcon: icon, + containerTitle: title, name: providerDescriptor.label, canToggleVisibility: false, canMoveView: true, From 0b4911870f55568d2c5ff83a48630eb8d395c6fe Mon Sep 17 00:00:00 2001 From: Neelesh Bodas Date: Wed, 16 Aug 2023 12:16:39 -0700 Subject: [PATCH 002/198] Remove incorrect role from the title bar. --- src/vs/workbench/browser/workbench.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 28863e8e434..8fae627d8f6 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -342,7 +342,7 @@ export class Workbench extends Layout { // Create Parts for (const { id, role, classes, options } of [ - { id: Parts.TITLEBAR_PART, role: 'contentinfo', classes: ['titlebar'] }, + { id: Parts.TITLEBAR_PART, role: 'none', classes: ['titlebar'] }, { id: Parts.BANNER_PART, role: 'banner', classes: ['banner'] }, { id: Parts.ACTIVITYBAR_PART, role: 'none', classes: ['activitybar', this.getSideBarPosition() === Position.LEFT ? 'left' : 'right'] }, // Use role 'none' for some parts to make screen readers less chatty #114892 { id: Parts.SIDEBAR_PART, role: 'none', classes: ['sidebar', this.getSideBarPosition() === Position.LEFT ? 'left' : 'right'] }, From 91877b8abf8f5b35d771d6f6e07b0a84ed8a3fc7 Mon Sep 17 00:00:00 2001 From: kon72 Date: Tue, 15 Aug 2023 06:35:23 +0900 Subject: [PATCH 003/198] Add commands for collapsing/showing all unchanged regions --- .../diffEditorWidget2/diffEditorViewModel.ts | 7 ++- .../diffEditorWidget2.contribution.ts | 45 +++++++++++++++++++ .../diffEditorWidget2/diffEditorWidget2.ts | 16 +++++++ .../diffEditorWidget2/unchangedRanges.ts | 4 +- 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 4833d3de651..728bdc1976f 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -39,7 +39,7 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo // Reset state transaction(tx => { for (const r of this._unchangedRegions.get().regions) { - r.setState(0, 0, tx); + r.collapseAll(tx); } }); return []; @@ -401,6 +401,11 @@ export class UnchangedRegion { this._visibleLineCountBottom.set(this.lineCount - this._visibleLineCountTop.get(), tx); } + public collapseAll(tx: ITransaction | undefined): void { + this._visibleLineCountTop.set(0, tx); + this._visibleLineCountBottom.set(0, tx); + } + public setState(visibleLineCountTop: number, visibleLineCountBottom: number, tx: ITransaction | undefined): void { visibleLineCountTop = Math.max(Math.min(visibleLineCountTop, this.lineCount), 0); visibleLineCountBottom = Math.max(Math.min(visibleLineCountBottom, this.lineCount - visibleLineCountTop), 0); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts index d312eb5629a..ec2d305bda9 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts @@ -112,6 +112,7 @@ const diffEditorCategory: ILocalizedString = { value: localize('diffEditor', 'Diff Editor'), original: 'Diff Editor', }; + export class SwitchSide extends EditorAction2 { constructor() { super({ @@ -133,3 +134,47 @@ export class SwitchSide extends EditorAction2 { } registerAction2(SwitchSide); + +export class CollapseAllUnchangedRegions extends EditorAction2 { + constructor() { + super({ + id: 'diffEditor.collapseAllUnchangedRegions', + title: { value: localize('collapseAllUnchangedRegions', "Collapse All Unchanged Regions"), original: 'Collapse All Unchanged Regions' }, + icon: Codicon.fold, + precondition: ContextKeyExpr.and(ContextKeyEqualsExpr.create('diffEditorVersion', 2), ContextKeyExpr.has('isInDiffEditor')), + f1: true, + category: diffEditorCategory, + }); + } + + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void { + const diffEditor = findFocusedDiffEditor(accessor); + if (diffEditor instanceof DiffEditorWidget2) { + diffEditor.collapseAllUnchangedRegions(); + } + } +} + +registerAction2(CollapseAllUnchangedRegions); + +export class ShowAllUnchangedRegions extends EditorAction2 { + constructor() { + super({ + id: 'diffEditor.showAllUnchangedRegions', + title: { value: localize('showAllUnchangedRegions', "Show All Unchanged Regions"), original: 'Show All Unchanged Regions' }, + icon: Codicon.unfold, + precondition: ContextKeyExpr.and(ContextKeyEqualsExpr.create('diffEditorVersion', 2), ContextKeyExpr.has('isInDiffEditor')), + f1: true, + category: diffEditorCategory, + }); + } + + runEditorCommand(accessor: ServicesAccessor, editor: ICodeEditor, ...args: unknown[]): void { + const diffEditor = findFocusedDiffEditor(accessor); + if (diffEditor instanceof DiffEditorWidget2) { + diffEditor.showAllUnchangedRegions(); + } + } +} + +registerAction2(ShowAllUnchangedRegions); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 21b5f67aaae..13f039811af 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -512,6 +512,22 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { } destination.focus(); } + + collapseAllUnchangedRegions(): void { + const unchangedRegions = this._diffModel.get()?.unchangedRegions.get(); + if (!unchangedRegions) { return; } + for (const region of unchangedRegions) { + region.collapseAll(undefined); + } + } + + showAllUnchangedRegions(): void { + const unchangedRegions = this._diffModel.get()?.unchangedRegions.get(); + if (!unchangedRegions) { return; } + for (const region of unchangedRegions) { + region.showAll(undefined); + } + } } function translatePosition(posInOriginal: Position, mappings: LineRangeMapping[]): Range { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index 7272f56b11f..8e953782b21 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -156,7 +156,7 @@ export class UnchangedRangesFeature extends Disposable { if (!model) { return; } const region = model.unchangedRegions.get().find(r => r.modifiedRange.includes(lineNumber)); if (!region) { return; } - region.setState(0, 0, undefined); + region.collapseAll(undefined); event.event.stopPropagation(); event.event.preventDefault(); } @@ -169,7 +169,7 @@ export class UnchangedRangesFeature extends Disposable { if (!model) { return; } const region = model.unchangedRegions.get().find(r => r.originalRange.includes(lineNumber)); if (!region) { return; } - region.setState(0, 0, undefined); + region.collapseAll(undefined); event.event.stopPropagation(); event.event.preventDefault(); } From 121d7b169dc158c1512030d8a1827ed89c25783d Mon Sep 17 00:00:00 2001 From: kon72 Date: Tue, 15 Aug 2023 22:56:00 +0900 Subject: [PATCH 004/198] Address review comments --- .../diffEditorWidget2/diffEditorWidget2.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 13f039811af..49b56595b03 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -516,17 +516,21 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { collapseAllUnchangedRegions(): void { const unchangedRegions = this._diffModel.get()?.unchangedRegions.get(); if (!unchangedRegions) { return; } - for (const region of unchangedRegions) { - region.collapseAll(undefined); - } + transaction(tx => { + for (const region of unchangedRegions) { + region.collapseAll(tx); + } + }); } showAllUnchangedRegions(): void { const unchangedRegions = this._diffModel.get()?.unchangedRegions.get(); if (!unchangedRegions) { return; } - for (const region of unchangedRegions) { - region.showAll(undefined); - } + transaction(tx => { + for (const region of unchangedRegions) { + region.showAll(tx); + } + }); } } From bb90524c2c23b78242e9eaa1b1177d23b7a2e0e2 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 19:14:09 +0200 Subject: [PATCH 005/198] Fixes #187839 --- .../widget/diffEditorWidget2/diffEditorWidget2.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 280c2bb7b9a..b0da2fb6191 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -45,6 +45,7 @@ import { DiffEditorEditors } from './diffEditorEditors'; import { DiffEditorOptions } from './diffEditorOptions'; import { DiffEditorViewModel, DiffMapping, DiffState } from './diffEditorViewModel'; import { toDisposable } from 'vs/base/common/lifecycle'; +import { IEditorProgressService } from 'vs/platform/progress/common/progress'; export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { private readonly elements = h('div.monaco-diff-editor.side-by-side', { style: { position: 'relative', height: '100%' } }, [ @@ -89,6 +90,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { @IInstantiationService private readonly _parentInstantiationService: IInstantiationService, @ICodeEditorService codeEditorService: ICodeEditorService, @IAudioCueService private readonly _audioCueService: IAudioCueService, + @IEditorProgressService private readonly _editorProgressService: IEditorProgressService, ) { super(); codeEditorService.willCreateDiffEditor(); @@ -262,6 +264,14 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { } } })); + + const isDiffUpToDate = this._diffModel.map((m, reader) => m?.isDiffUpToDate.read(reader)); + this._register(autorunWithStore((reader, store) => { + if (isDiffUpToDate.read(reader) === false) { + const r = this._editorProgressService.show(true, 1000); + store.add(toDisposable(() => r.done())); + } + })); } public getContentHeight() { From d6d666effe991a730c67dcc758d3a1dcb541ca2e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 25 Aug 2023 06:52:48 -0700 Subject: [PATCH 006/198] Correct dim unfocused config scope Part of #190751 --- .../accessibility/browser/accessibilityConfiguration.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts index c8272bc512d..8dbcbd3abff 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts @@ -111,7 +111,7 @@ export function registerAccessibilityConfiguration() { type: 'boolean', default: false, tags: ['accessibility'], - scope: ConfigurationScope.MACHINE, + scope: ConfigurationScope.APPLICATION, }, [AccessibilityWorkbenchSettingId.ViewDimUnfocusedOpacity]: { description: localize('dimUnfocusedOpacity', 'The opacity fraction (0.2 to 1.0) to use for unfocused editors and terminals. This will only take effect when {0} is enabled.', `\`#${AccessibilityWorkbenchSettingId.ViewDimUnfocusedEnabled}#\``), @@ -120,7 +120,7 @@ export function registerAccessibilityConfiguration() { maximum: ViewDimUnfocusedOpacityProperties.Maximum, default: ViewDimUnfocusedOpacityProperties.Default, tags: ['accessibility'], - scope: ConfigurationScope.MACHINE, + scope: ConfigurationScope.APPLICATION, } } }); From a2be681a700076aeb73e25b33f083c5a6ceb46fb Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 28 Aug 2023 09:50:20 +0200 Subject: [PATCH 007/198] simplifying the code --- .../browser/stickyScrollWidget.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 00496bec0f0..e4d843f0551 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -45,6 +45,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { private _lineNumbers: number[] = []; private _lastLineRelativePosition: number = 0; private _minContentWidthInPx: number = 0; + private _isOnFoldingGlyphMargin: boolean = false; constructor( private readonly _editor: ICodeEditor @@ -187,28 +188,29 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { return; } this._foldingIconStore.add(dom.addDisposableListener(this._lineNumbersDomNode, dom.EventType.MOUSE_ENTER, (e) => { - const mouseEventTriggerredByClick = - 'fromElement' in e - && e.fromElement instanceof HTMLElement - && e.fromElement.classList.contains('codicon'); + + this._isOnFoldingGlyphMargin = true; for (const line of this._stickyLines) { const foldingIcon = line.foldingIcon; if (!foldingIcon) { continue; } - if (mouseEventTriggerredByClick) { - foldingIcon.setTransitionRequired(false); - foldingIcon.setVisible(true); - setTimeout(() => { foldingIcon.setTransitionRequired(true); }, 300); - } else { - foldingIcon.setVisible(true); - } + foldingIcon.setTransitionRequired(true); + foldingIcon.setVisible(true); + foldingIcon.setTransitionRequired(false); } })); this._foldingIconStore.add(dom.addDisposableListener(this._lineNumbersDomNode, dom.EventType.MOUSE_LEAVE, () => { + + this._isOnFoldingGlyphMargin = false; + for (const line of this._stickyLines) { const foldingIcon = line.foldingIcon; + if (!foldingIcon) { + continue; + } + foldingIcon.setTransitionRequired(true); foldingIcon?.setVisible(foldingIcon.isCollapsed); } })); From a357413f4916bb5a40aa97ddaf91ca3b8fb0e0a1 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 28 Aug 2023 04:00:52 -0700 Subject: [PATCH 008/198] Fix external link providers Fixes #191032 --- src/vs/workbench/contrib/terminal/browser/terminal.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index e02fbf99e5e..28b600107aa 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -170,7 +170,7 @@ export interface IDetachedTerminalInstance extends IDisposable { attachToElement(container: HTMLElement, options?: Partial): void; } -export const isDetachedTerminalInstance = (t: ITerminalInstance | IDetachedTerminalInstance): t is IDetachedTerminalInstance => typeof (t as ITerminalInstance).instanceId === 'number'; +export const isDetachedTerminalInstance = (t: ITerminalInstance | IDetachedTerminalInstance): t is IDetachedTerminalInstance => typeof (t as ITerminalInstance).instanceId !== 'number'; export interface ITerminalService extends ITerminalInstanceHost { readonly _serviceBrand: undefined; From 74a11f3d2b92d75e0737754993338cba1e85c1ee Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 28 Aug 2023 14:25:26 +0200 Subject: [PATCH 009/198] adding some working code, use classes instead --- .../lib/stylelint/vscode-known-variables.json | 3 ++- .../stickyScroll/browser/stickyScroll.css | 1 + .../browser/stickyScrollWidget.ts | 24 +++++++++++++++++-- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json index a7d22a17b85..fcace4c66d4 100644 --- a/build/lib/stylelint/vscode-known-variables.json +++ b/build/lib/stylelint/vscode-known-variables.json @@ -757,6 +757,7 @@ "--vscode-sash-hover-size", "--vscode-sash-size", "--vscode-editorStickyScroll-scrollableWidth", + "--vscode-editorStickyScroll-foldingTransition", "--window-border-color", "--workspace-trust-check-color", "--workspace-trust-selected-color", @@ -779,4 +780,4 @@ "--z-index-notebook-sticky-scroll", "--zoom-factor" ] -} \ No newline at end of file +} diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css index 212fbb7a050..2904d04f603 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css @@ -35,6 +35,7 @@ .monaco-editor .sticky-line-number .codicon { float: right; + transition: var(--vscode-editorStickyScroll-foldingTransition); } .monaco-editor .sticky-line-content { diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index e4d843f0551..493faf9fde5 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -191,6 +191,15 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { this._isOnFoldingGlyphMargin = true; + for (const line of this._stickyLines) { + const foldingIcon = line.foldingIcon; + if (!foldingIcon) { + continue; + } + foldingIcon.setVisible(true); + } + + /* for (const line of this._stickyLines) { const foldingIcon = line.foldingIcon; if (!foldingIcon) { @@ -200,6 +209,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { foldingIcon.setVisible(true); foldingIcon.setTransitionRequired(false); } + */ })); this._foldingIconStore.add(dom.addDisposableListener(this._lineNumbersDomNode, dom.EventType.MOUSE_LEAVE, () => { @@ -213,6 +223,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { foldingIcon.setTransitionRequired(true); foldingIcon?.setVisible(foldingIcon.isCollapsed); } + })); } @@ -320,8 +331,17 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { const isCollapsed = foldingRegions.isCollapsed(indexOfFoldingRegion); const foldingIcon = new StickyFoldingIcon(isCollapsed, this._lineHeight); container.append(foldingIcon.domNode); - foldingIcon.setVisible(isCollapsed || showFoldingControls === 'always'); - foldingIcon.setTransitionRequired(true); + + // If we are on the glyph margin + console.log('this._isOnFoldingGlyphMargin : ', this._isOnFoldingGlyphMargin); + + if (this._isOnFoldingGlyphMargin) { + foldingIcon.setTransitionRequired(false); + foldingIcon.setVisible(true); + } else { + foldingIcon.setTransitionRequired(true); + foldingIcon.setVisible(isCollapsed || showFoldingControls === 'always'); + } this._foldingIconStore.add(dom.addDisposableListener(foldingIcon.domNode, dom.EventType.CLICK, () => { toggleCollapseState(foldingModel, Number.MAX_VALUE, [line]); From 14c1d7c061c6e78e2dae575ff64f29d3374b0298 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Mon, 28 Aug 2023 15:04:43 +0200 Subject: [PATCH 010/198] adding code changes --- .../lib/stylelint/vscode-known-variables.json | 2 +- .../stickyScroll/browser/stickyScroll.css | 2 +- .../browser/stickyScrollWidget.ts | 71 ++++++------------- 3 files changed, 24 insertions(+), 51 deletions(-) diff --git a/build/lib/stylelint/vscode-known-variables.json b/build/lib/stylelint/vscode-known-variables.json index fcace4c66d4..1fb81747019 100644 --- a/build/lib/stylelint/vscode-known-variables.json +++ b/build/lib/stylelint/vscode-known-variables.json @@ -757,7 +757,7 @@ "--vscode-sash-hover-size", "--vscode-sash-size", "--vscode-editorStickyScroll-scrollableWidth", - "--vscode-editorStickyScroll-foldingTransition", + "--vscode-editorStickyScroll-foldingOpacityTransition", "--window-border-color", "--workspace-trust-check-color", "--workspace-trust-selected-color", diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css index 2904d04f603..b446742a2db 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScroll.css @@ -35,7 +35,7 @@ .monaco-editor .sticky-line-number .codicon { float: right; - transition: var(--vscode-editorStickyScroll-foldingTransition); + transition: var(--vscode-editorStickyScroll-foldingOpacityTransition); } .monaco-editor .sticky-line-content { diff --git a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts index 493faf9fde5..f98f67e3570 100644 --- a/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts +++ b/src/vs/editor/contrib/stickyScroll/browser/stickyScrollWidget.ts @@ -45,7 +45,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { private _lineNumbers: number[] = []; private _lastLineRelativePosition: number = 0; private _minContentWidthInPx: number = 0; - private _isOnFoldingGlyphMargin: boolean = false; + private _isOnGlyphMargin: boolean = false; constructor( private readonly _editor: ICodeEditor @@ -148,6 +148,20 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { this._rootDomNode.style.display = 'none'; } + private _useFoldingOpacityTransition(requireTransitions: boolean) { + this._lineNumbersDomNode.style.setProperty('--vscode-editorStickyScroll-foldingOpacityTransition', `opacity ${requireTransitions ? 0.5 : 0}s`); + } + + private _setFoldingIconsVisibility(allVisible: boolean) { + for (const line of this._stickyLines) { + const foldingIcon = line.foldingIcon; + if (!foldingIcon) { + continue; + } + foldingIcon.setVisible(allVisible ? true : foldingIcon.isCollapsed); + } + } + private async _renderRootNode(): Promise { const foldingModel = await FoldingController.get(this._editor)?.getFoldingModel(); @@ -160,6 +174,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { } if (foldingModel) { this._setFoldingHoverListeners(); + this._useFoldingOpacityTransition(!this._isOnGlyphMargin); } const widgetHeight: number = this._lineNumbers.length * this._lineHeight + this._lastLineRelativePosition; @@ -188,41 +203,13 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { return; } this._foldingIconStore.add(dom.addDisposableListener(this._lineNumbersDomNode, dom.EventType.MOUSE_ENTER, (e) => { - - this._isOnFoldingGlyphMargin = true; - - for (const line of this._stickyLines) { - const foldingIcon = line.foldingIcon; - if (!foldingIcon) { - continue; - } - foldingIcon.setVisible(true); - } - - /* - for (const line of this._stickyLines) { - const foldingIcon = line.foldingIcon; - if (!foldingIcon) { - continue; - } - foldingIcon.setTransitionRequired(true); - foldingIcon.setVisible(true); - foldingIcon.setTransitionRequired(false); - } - */ + this._isOnGlyphMargin = true; + this._setFoldingIconsVisibility(true); })); this._foldingIconStore.add(dom.addDisposableListener(this._lineNumbersDomNode, dom.EventType.MOUSE_LEAVE, () => { - - this._isOnFoldingGlyphMargin = false; - - for (const line of this._stickyLines) { - const foldingIcon = line.foldingIcon; - if (!foldingIcon) { - continue; - } - foldingIcon.setTransitionRequired(true); - foldingIcon?.setVisible(foldingIcon.isCollapsed); - } + this._isOnGlyphMargin = false; + this._useFoldingOpacityTransition(true); + this._setFoldingIconsVisibility(false); })); } @@ -331,17 +318,7 @@ export class StickyScrollWidget extends Disposable implements IOverlayWidget { const isCollapsed = foldingRegions.isCollapsed(indexOfFoldingRegion); const foldingIcon = new StickyFoldingIcon(isCollapsed, this._lineHeight); container.append(foldingIcon.domNode); - - // If we are on the glyph margin - console.log('this._isOnFoldingGlyphMargin : ', this._isOnFoldingGlyphMargin); - - if (this._isOnFoldingGlyphMargin) { - foldingIcon.setTransitionRequired(false); - foldingIcon.setVisible(true); - } else { - foldingIcon.setTransitionRequired(true); - foldingIcon.setVisible(isCollapsed || showFoldingControls === 'always'); - } + foldingIcon.setVisible(this._isOnGlyphMargin ? true : (isCollapsed || showFoldingControls === 'always')); this._foldingIconStore.add(dom.addDisposableListener(foldingIcon.domNode, dom.EventType.CLICK, () => { toggleCollapseState(foldingModel, Number.MAX_VALUE, [line]); @@ -462,8 +439,4 @@ class StickyFoldingIcon { this.domNode.style.cursor = visible ? 'pointer' : 'default'; this.domNode.style.opacity = visible ? '1' : '0'; } - - public setTransitionRequired(transitionRequired: boolean) { - this.domNode.style.transition = `opacity ${transitionRequired ? 0.5 : 0}s`; - } } From 76ef8f7cf9e64425ec92d3acfbef457695011731 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Mon, 28 Aug 2023 15:48:37 +0200 Subject: [PATCH 011/198] voice - some :lipstick: (#191459) * voice - some :lipstick: * voice - cannot `export` from worklet --- .../voiceTranscriptionWorklet.ts | 12 ++++++++---- .../workbenchVoiceRecognitionService.ts | 18 +++++++++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.ts b/src/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.ts index 47c7baf3433..fc3acd9eb6a 100644 --- a/src/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.ts +++ b/src/vs/workbench/services/voiceRecognition/electron-sandbox/voiceTranscriptionWorklet.ts @@ -10,9 +10,13 @@ declare class AudioWorkletProcessor { process(inputs: [Float32Array[]], outputs: [Float32Array[]]): boolean; } -class VoiceTranscriptionWorklet extends AudioWorkletProcessor { +interface IVoiceTranscriptionWorkletOptions extends AudioWorkletNodeOptions { + processorOptions: { + readonly bufferTimespan: number; + }; +} - private static readonly BUFFER_TIMESPAN = 1000; +class VoiceTranscriptionWorklet extends AudioWorkletProcessor { private startTime: number | undefined = undefined; private stopped: boolean = false; @@ -21,7 +25,7 @@ class VoiceTranscriptionWorklet extends AudioWorkletProcessor { private sharedProcessConnection: MessagePort | undefined = undefined; - constructor() { + constructor(private readonly options: IVoiceTranscriptionWorkletOptions) { super(); this.registerListeners(); @@ -71,7 +75,7 @@ class VoiceTranscriptionWorklet extends AudioWorkletProcessor { this.buffer.push(inputChannelData.slice(0)); - if (Date.now() - this.startTime > VoiceTranscriptionWorklet.BUFFER_TIMESPAN && this.sharedProcessConnection) { + if (Date.now() - this.startTime > this.options.processorOptions.bufferTimespan && this.sharedProcessConnection) { const buffer = this.buffer; this.buffer = []; diff --git a/src/vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService.ts b/src/vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService.ts index d35dd681f77..11aa0dae3e1 100644 --- a/src/vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService.ts +++ b/src/vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService.ts @@ -38,11 +38,17 @@ export interface IWorkbenchVoiceRecognitionService { transcribe(cancellation: CancellationToken, options?: IWorkbenchVoiceRecognitionOptions): Promise>; } +interface IVoiceTranscriptionWorkletOptions extends AudioWorkletNodeOptions { + processorOptions: { + readonly bufferTimespan: number; + }; +} + class VoiceTranscriptionWorkletNode extends AudioWorkletNode { constructor( context: BaseAudioContext, - options: AudioWorkletNodeOptions, + options: IVoiceTranscriptionWorkletOptions, private readonly onDidTranscribe: Emitter, private readonly sharedProcessService: ISharedProcessService ) { @@ -86,6 +92,8 @@ export class WorkbenchVoiceRecognitionService implements IWorkbenchVoiceRecognit private static readonly AUDIO_BIT_DEPTH = 16; private static readonly AUDIO_CHANNELS = 1; + private static readonly BUFFER_TIMESPAN = 1000; + constructor( @IProgressService private readonly progressService: IProgressService, @ISharedProcessService private readonly sharedProcessService: ISharedProcessService, @@ -125,7 +133,8 @@ export class WorkbenchVoiceRecognitionService implements IWorkbenchVoiceRecognit sampleSize: WorkbenchVoiceRecognitionService.AUDIO_BIT_DEPTH, channelCount: WorkbenchVoiceRecognitionService.AUDIO_CHANNELS, autoGainControl: true, - noiseSuppression: true + noiseSuppression: true, + echoCancellation: false } }); @@ -161,7 +170,10 @@ export class WorkbenchVoiceRecognitionService implements IWorkbenchVoiceRecognit const voiceTranscriptionTarget = new VoiceTranscriptionWorkletNode(audioContext, { channelCount: WorkbenchVoiceRecognitionService.AUDIO_CHANNELS, - channelCountMode: 'explicit' + channelCountMode: 'explicit', + processorOptions: { + bufferTimespan: WorkbenchVoiceRecognitionService.BUFFER_TIMESPAN + } }, onDidTranscribe, this.sharedProcessService); await voiceTranscriptionTarget.start(cts.token); From 4b37efe37504412948604efcd0b9d23988fa5159 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Mon, 28 Aug 2023 13:26:18 +0200 Subject: [PATCH 012/198] August 2023 endgame OSS Tool changes --- ThirdPartyNotices.txt | 1291 ++++++++++++++++++++----------------- cli/ThirdPartyNotices.txt | 121 ++-- package.json | 2 +- 3 files changed, 757 insertions(+), 657 deletions(-) diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index cf52ca35c94..6863bf7828f 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -440,580 +440,6 @@ Title to copyright in this work will at all times remain with copyright holders. --------------------------------------------------------- -dompurify 2.3.1 - Apache 2.0 -https://github.com/cure53/DOMPurify - -DOMPurify -Copyright 2023 Dr.-Ing. Mario Heiderich, Cure53 - -DOMPurify is free software; you can redistribute it and/or modify it under the -terms of either: - -a) the Apache License Version 2.0, or -b) the Mozilla Public License Version 2.0 - ------------------------------------------------------------------------------ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ------------------------------------------------------------------------------ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. "Contributor" - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. "Contributor Version" - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor’s Contribution. - -1.3. "Contribution" - - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of version - 1.1 or earlier of the License, but not also under the terms of a - Secondary License. - -1.6. "Executable Form" - - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - - means a work that combines Covered Software with other material, in a separate - file or files, that is not Covered Software. - -1.8. "License" - - means this document. - -1.9. "Licensable" - - means having the right to grant, to the maximum extent possible, whether at the - time of the initial grant or subsequently, any and all of the rights conveyed by - this License. - -1.10. "Modifications" - - means any of the following: - - a. any file in Source Code Form that results from an addition to, deletion - from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. "Patent Claims" of a Contributor - - means any patent claim(s), including without limitation, method, process, - and apparatus claims, in any patent Licensable by such Contributor that - would be infringed, but for the grant of the License, by the making, - using, selling, offering for sale, having made, import, or transfer of - either its Contributions or its Contributor Version. - -1.12. "Secondary License" - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. "Source Code Form" - - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, "control" means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or as - part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its Contributions - or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution become - effective for each Contribution on the date the Contributor first distributes - such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under this - License. No additional rights or licenses will be implied from the distribution - or licensing of Covered Software under this License. Notwithstanding Section - 2.1(b) above, no patent license is granted by a Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party’s - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of its - Contributions. - - This License does not grant any rights in the trademarks, service marks, or - logos of any Contributor (except as may be necessary to comply with the - notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this License - (see Section 10.2) or under the terms of a Secondary License (if permitted - under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its Contributions - are its original creation(s) or it has sufficient rights to grant the - rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under applicable - copyright doctrines of fair use, fair dealing, or other equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under the - terms of this License. You must inform recipients that the Source Code Form - of the Covered Software is governed by the terms of this License, and how - they can obtain a copy of this License. You may not attempt to alter or - restrict the recipients’ rights in the Source Code Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this License, - or sublicense it under different terms, provided that the license for - the Executable Form does not attempt to limit or alter the recipients’ - rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for the - Covered Software. If the Larger Work is a combination of Covered Software - with a work governed by one or more Secondary Licenses, and the Covered - Software is not Incompatible With Secondary Licenses, this License permits - You to additionally distribute such Covered Software under the terms of - such Secondary License(s), so that the recipient of the Larger Work may, at - their option, further distribute the Covered Software under the terms of - either this License or such Secondary License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices (including - copyright notices, patent notices, disclaimers of warranty, or limitations - of liability) contained within the Source Code Form of the Covered - Software, except that You may alter any license notices to the extent - required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on behalf - of any Contributor. You must make it absolutely clear that any such - warranty, support, indemnity, or liability obligation is offered by You - alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, judicial - order, or regulation then You must: (a) comply with the terms of this License - to the maximum extent possible; and (b) describe the limitations and the code - they affect. Such description must be placed in a text file included with all - distributions of the Covered Software under this License. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing basis, - if such Contributor fails to notify You of the non-compliance by some - reasonable means prior to 60 days after You have come back into compliance. - Moreover, Your grants from a particular Contributor are reinstated on an - ongoing basis if such Contributor notifies You of the non-compliance by - some reasonable means, this is the first time You have received notice of - non-compliance with this License from such Contributor, and You become - compliant prior to 30 days after Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, counter-claims, - and cross-claims) alleging that a Contributor Version directly or - indirectly infringes any patent, then the rights granted to You by any and - all Contributors for the Covered Software under Section 2.1 of this License - shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an "as is" basis, without - warranty of any kind, either expressed, implied, or statutory, including, - without limitation, warranties that the Covered Software is free of defects, - merchantable, fit for a particular purpose or non-infringing. The entire - risk as to the quality and performance of the Covered Software is with You. - Should any Covered Software prove defective in any respect, You (not any - Contributor) assume the cost of any necessary servicing, repair, or - correction. This disclaimer of warranty constitutes an essential part of this - License. No use of any Covered Software is authorized under this License - except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from such - party’s negligence to the extent applicable law prohibits such limitation. - Some jurisdictions do not allow the exclusion or limitation of incidental or - consequential damages, so this exclusion and limitation may not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts of - a jurisdiction where the defendant maintains its principal place of business - and such litigation shall be governed by laws of that jurisdiction, without - reference to its conflict-of-law provisions. Nothing in this Section shall - prevent a party’s ability to bring cross-claims or counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject matter - hereof. If any provision of this License is held to be unenforceable, such - provision shall be reformed only to the extent necessary to make it - enforceable. Any law or regulation which provides that the language of a - contract shall be construed against the drafter shall not be used to construe - this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version of - the License under which You originally received the Covered Software, or - under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a modified - version of this License if you rename the license and remove any - references to the name of the license steward (except to note that such - modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses - If You choose to distribute Source Code Form that is Incompatible With - Secondary Licenses under the terms of this version of the License, the - notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, then -You may include the notice in a location (such as a LICENSE file in a relevant -directory) where a recipient would be likely to look for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice - - This Source Code Form is "Incompatible - With Secondary Licenses", as defined by - the Mozilla Public License, v. 2.0. ---------------------------------------------------------- - ---------------------------------------------------------- - dotnet/csharp-tmLanguage 0.1.0 - MIT https://github.com/dotnet/csharp-tmLanguage @@ -1345,27 +771,682 @@ SOFTWARE. jeff-hykin/better-cpp-syntax 1.17.4 - MIT https://github.com/jeff-hykin/better-cpp-syntax -MIT License +The MIT License (MIT) -Copyright (c) 2019 Jeff Hykin +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + Preamble -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. --------------------------------------------------------- --------------------------------------------------------- @@ -1454,6 +1535,34 @@ SOFTWARE. --------------------------------------------------------- +jeff-hykin/better-snippet-syntax 1.0.2 - MIT +https://github.com/jeff-hykin/better-snippet-syntax + +MIT License + +Copyright (c) 2019 Jeff Hykin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +--------------------------------------------------------- + +--------------------------------------------------------- + jlelong/vscode-latex-basics 1.5.3 - MIT https://github.com/jlelong/vscode-latex-basics diff --git a/cli/ThirdPartyNotices.txt b/cli/ThirdPartyNotices.txt index ba85a27096c..09856f72402 100644 --- a/cli/ThirdPartyNotices.txt +++ b/cli/ThirdPartyNotices.txt @@ -525,35 +525,6 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -atty 0.2.14 - MIT -https://github.com/softprops/atty - -The MIT License (MIT) - -Copyright (c) 2015-2019 Doug Tangren - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ---------------------------------------------------------- - ---------------------------------------------------------- - autocfg 1.1.0 - Apache-2.0 OR MIT https://github.com/cuviper/autocfg @@ -1875,7 +1846,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -crossbeam-utils 0.8.12 - MIT OR Apache-2.0 +crossbeam-utils 0.8.16 - MIT OR Apache-2.0 https://github.com/crossbeam-rs/crossbeam The MIT License (MIT) @@ -1965,7 +1936,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted --------------------------------------------------------- -cxx 1.0.78 - MIT OR Apache-2.0 +cxx 1.0.97 - MIT OR Apache-2.0 https://github.com/dtolnay/cxx Permission is hereby granted, free of charge, to any @@ -1995,7 +1966,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -cxx-build 1.0.78 - MIT OR Apache-2.0 +cxx-build 1.0.97 - MIT OR Apache-2.0 https://github.com/dtolnay/cxx Permission is hereby granted, free of charge, to any @@ -2025,7 +1996,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -cxxbridge-flags 1.0.78 - MIT OR Apache-2.0 +cxxbridge-flags 1.0.97 - MIT OR Apache-2.0 https://github.com/dtolnay/cxx Permission is hereby granted, free of charge, to any @@ -2055,7 +2026,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -cxxbridge-macro 1.0.78 - MIT OR Apache-2.0 +cxxbridge-macro 1.0.97 - MIT OR Apache-2.0 https://github.com/dtolnay/cxx Permission is hereby granted, free of charge, to any @@ -3553,7 +3524,7 @@ Unless you explicitly state otherwise, any contribution intentionally submitted --------------------------------------------------------- -http 0.2.8 - MIT OR Apache-2.0 +http 0.2.9 - MIT OR Apache-2.0 https://github.com/hyperium/http Copyright (c) 2017 http-rs authors @@ -3725,7 +3696,7 @@ THE SOFTWARE. --------------------------------------------------------- -iana-time-zone 0.1.51 - MIT OR Apache-2.0 +iana-time-zone 0.1.57 - MIT OR Apache-2.0 https://github.com/strawlab/iana-time-zone Copyright (c) 2020 Andrew D. Straw @@ -3757,7 +3728,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -iana-time-zone-haiku 0.1.0 - MIT OR Apache-2.0 +iana-time-zone-haiku 0.1.1 - MIT OR Apache-2.0 https://github.com/strawlab/iana-time-zone Copyright (c) 2020 Andrew D. Straw @@ -4259,7 +4230,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -link-cplusplus 1.0.7 - MIT OR Apache-2.0 +link-cplusplus 1.0.9 - MIT OR Apache-2.0 https://github.com/dtolnay/link-cplusplus Permission is hereby granted, free of charge, to any @@ -7734,7 +7705,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -scratch 1.0.2 - MIT OR Apache-2.0 +scratch 1.0.7 - MIT OR Apache-2.0 https://github.com/dtolnay/scratch Permission is hereby granted, free of charge, to any @@ -8753,7 +8724,7 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -termcolor 1.1.3 - Unlicense OR MIT +termcolor 1.2.0 - Unlicense OR MIT https://github.com/BurntSushi/termcolor The MIT License (MIT) @@ -8841,7 +8812,6 @@ DEALINGS IN THE SOFTWARE. --------------------------------------------------------- -time 0.1.44 - MIT/Apache-2.0 time 0.3.21 - MIT OR Apache-2.0 https://github.com/time-rs/time @@ -9136,31 +9106,25 @@ DEALINGS IN THE SOFTWARE. toml 0.5.9 - MIT/Apache-2.0 https://github.com/toml-rs/toml -Copyright (c) 2014 Alex Crichton +Copyright (c) Individual contributors -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. --------------------------------------------------------- --------------------------------------------------------- @@ -9357,7 +9321,7 @@ THE SOFTWARE. --------------------------------------------------------- -tunnels 2621784a9ad72aa39500372391332a14bad581a3 +tunnels 3141ad7be00e18c4231f7c4fb6c11f9219ac49af https://github.com/microsoft/dev-tunnels MIT License @@ -9852,7 +9816,6 @@ THE SOFTWARE. --------------------------------------------------------- -wasi 0.10.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT wasi 0.11.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT wasi 0.9.0+wasi-snapshot-preview1 - Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT https://github.com/bytecodealliance/wasi @@ -10272,6 +10235,34 @@ SOFTWARE. --------------------------------------------------------- +windows 0.48.0 - MIT OR Apache-2.0 +https://github.com/microsoft/windows-rs + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE +--------------------------------------------------------- + +--------------------------------------------------------- + windows-sys 0.36.1 - MIT OR Apache-2.0 windows-sys 0.45.0 - MIT OR Apache-2.0 windows-sys 0.48.0 - MIT OR Apache-2.0 diff --git a/package.json b/package.json index 080af3cecd2..4dbaa275413 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.82.0", - "distro": "56bfb9ce4a8d2298f475a1b8d9c7a7b5a72204f2", + "distro": "49cc0fbc0a8e222bcce2a7c3bf62e0d23f20d258", "author": { "name": "Microsoft Corporation" }, From 8514185e28b3395660bb1f9f360fa49ba4ada375 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 28 Aug 2023 16:26:34 +0200 Subject: [PATCH 013/198] Fixes CI --- src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts | 3 ++- src/vs/editor/standalone/browser/standaloneCodeEditor.ts | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts index dc5dd6c299c..d9785bfc8c1 100644 --- a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts +++ b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts @@ -134,8 +134,9 @@ export class EmbeddedDiffEditorWidget2 extends DiffEditorWidget2 { @IInstantiationService instantiationService: IInstantiationService, @ICodeEditorService codeEditorService: ICodeEditorService, @IAudioCueService audioCueService: IAudioCueService, + @IEditorProgressService editorProgressService: IEditorProgressService, ) { - super(domElement, parentEditor.getRawOptions(), codeEditorWidgetOptions, contextKeyService, instantiationService, codeEditorService, audioCueService); + super(domElement, parentEditor.getRawOptions(), codeEditorWidgetOptions, contextKeyService, instantiationService, codeEditorService, audioCueService, editorProgressService); this._parentEditor = parentEditor; this._overwriteOptions = options; diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index d9a8d83cf09..b6cff679cf2 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -575,6 +575,7 @@ export class StandaloneDiffEditor2 extends DiffEditorWidget2 implements IStandal @IEditorProgressService editorProgressService: IEditorProgressService, @IClipboardService clipboardService: IClipboardService, @IAudioCueService audioCueService: IAudioCueService, + @IEditorProgressService editorProgressService: IEditorProgressService, ) { const options = { ..._options }; updateConfigurationService(configurationService, options, true); @@ -594,6 +595,7 @@ export class StandaloneDiffEditor2 extends DiffEditorWidget2 implements IStandal instantiationService, codeEditorService, audioCueService, + editorProgressService, ); this._configurationService = configurationService; From c7d46b2430ad5b57187df77f79a2b923fc665987 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:34:46 +0200 Subject: [PATCH 014/198] Git - improve getRepositoryExact() error handling (#191462) * Git - improve getRepositoryExact() error handling * Run async operations in parallel --- extensions/git/src/git.ts | 9 ++++++-- extensions/git/src/model.ts | 38 ++++++++++++++++++++++++-------- extensions/git/src/repository.ts | 4 ++++ 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 62bdf24ebcb..65d34af1e31 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -397,8 +397,8 @@ export class Git { return Versions.compare(Versions.fromString(this.version), Versions.fromString(version)); } - open(repository: string, dotGit: { path: string; commonPath?: string }, logger: LogOutputChannel): Repository { - return new Repository(this, repository, dotGit, logger); + open(repositoryRoot: string, repositoryRootRealPath: string | undefined, dotGit: { path: string; commonPath?: string }, logger: LogOutputChannel): Repository { + return new Repository(this, repositoryRoot, repositoryRootRealPath, dotGit, logger); } async init(repository: string, options: InitOptions = {}): Promise { @@ -956,6 +956,7 @@ export class Repository { constructor( private _git: Git, private repositoryRoot: string, + private repositoryRootRealPath: string | undefined, readonly dotGit: { path: string; commonPath?: string }, private logger: LogOutputChannel ) { } @@ -968,6 +969,10 @@ export class Repository { return this.repositoryRoot; } + get rootRealPath(): string | undefined { + return this.repositoryRootRealPath; + } + async exec(args: string[], options: SpawnOptions = {}): Promise> { return await this.git.exec(this.repositoryRoot, args, options); } diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index eacfca8f035..02ff0ec8f5b 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -577,8 +577,8 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu } // Open repository - const dotGit = await this.git.getRepositoryDotGit(repositoryRoot); - const repository = new Repository(this.git.open(repositoryRoot, dotGit, this.logger), this, this, this, this, this.globalState, this.logger, this.telemetryReporter); + const [dotGit, repositoryRootRealPath] = await Promise.all([this.git.getRepositoryDotGit(repositoryRoot), this.getRepositoryRootRealPath(repositoryRoot)]); + const repository = new Repository(this.git.open(repositoryRoot, repositoryRootRealPath, dotGit, this.logger), this, this, this, this, this.globalState, this.logger, this.telemetryReporter); this.open(repository); this._closedRepositoriesManager.deleteRepository(repository.root); @@ -615,6 +615,16 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu } } + private async getRepositoryRootRealPath(repositoryRoot: string): Promise { + try { + const repositoryRootRealPath = await fs.promises.realpath(repositoryRoot); + return !pathEquals(repositoryRoot, repositoryRootRealPath) ? repositoryRootRealPath : undefined; + } catch (err) { + this.logger.warn(`Failed to get repository realpath for: "${repositoryRoot}". ${err}`); + return undefined; + } + } + private shouldRepositoryBeIgnored(repositoryRoot: string): boolean { const config = workspace.getConfiguration('git'); const ignoredRepos = config.get('ignoredRepositories') || []; @@ -766,15 +776,25 @@ export class Model implements IBranchProtectionProviderRegistry, IRemoteSourcePu } private async getRepositoryExact(repoPath: string): Promise { - const repoPathCanonical = await fs.promises.realpath(repoPath, { encoding: 'utf8' }); + // Use the repository path + const openRepository = this.openRepositories + .find(r => pathEquals(r.repository.root, repoPath)); - for (const openRepository of this.openRepositories) { - const rootPathCanonical = await fs.promises.realpath(openRepository.repository.root, { encoding: 'utf8' }); - if (pathEquals(rootPathCanonical, repoPathCanonical)) { - return openRepository.repository; - } + if (openRepository) { + return openRepository.repository; + } + + try { + // Use the repository real path + const repoPathRealPath = await fs.promises.realpath(repoPath, { encoding: 'utf8' }); + const openRepositoryRealPath = this.openRepositories + .find(r => pathEquals(r.repository.rootRealPath ?? '', repoPathRealPath)); + + return openRepositoryRealPath?.repository; + } catch (err) { + this.logger.warn(`Failed to get repository realpath for: "${repoPath}". ${err}`); + return undefined; } - return undefined; } private getOpenRepository(repository: Repository): OpenRepository | undefined; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 77739e11ce9..c3092d37b63 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -765,6 +765,10 @@ export class Repository implements Disposable { return this.repository.root; } + get rootRealPath(): string | undefined { + return this.repository.rootRealPath; + } + get dotGit(): { path: string; commonPath?: string } { return this.repository.dotGit; } From bbf51539736704c63689754ceb3096781a320417 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 24 Aug 2023 15:56:26 +0200 Subject: [PATCH 015/198] Writes module manager to global require function to allow for external module hot reloading --- src/vs/loader.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/loader.js b/src/vs/loader.js index c2d38dfca0e..a618210a168 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -1248,6 +1248,7 @@ var AMDLoader; this._buildInfoPath = []; this._buildInfoDefineStack = []; this._buildInfoDependencies = []; + this._requireFunc.moduleManager = this; } reset() { return new ModuleManager(this._env, this._scriptLoader, this._defineFunc, this._requireFunc, this._loaderAvailableTimestamp); From f650932f1661b84fdcf85cc21d39fa805ad1dc6e Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 28 Aug 2023 16:48:59 +0200 Subject: [PATCH 016/198] Fixes CI --- src/vs/editor/standalone/browser/standaloneCodeEditor.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts index b6cff679cf2..c2eb25b69e9 100644 --- a/src/vs/editor/standalone/browser/standaloneCodeEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneCodeEditor.ts @@ -575,7 +575,6 @@ export class StandaloneDiffEditor2 extends DiffEditorWidget2 implements IStandal @IEditorProgressService editorProgressService: IEditorProgressService, @IClipboardService clipboardService: IClipboardService, @IAudioCueService audioCueService: IAudioCueService, - @IEditorProgressService editorProgressService: IEditorProgressService, ) { const options = { ..._options }; updateConfigurationService(configurationService, options, true); From bfe4c57647c354fd303a1336493b95d0206ff078 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Sat, 26 Aug 2023 16:08:26 +0200 Subject: [PATCH 017/198] Adds detectedMoves to diffEditor.computeDiff telemetry event --- .../editor/browser/widget/workerBasedDocumentDiffProvider.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts index 648ba44763c..02d3c157aa6 100644 --- a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts +++ b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts @@ -84,16 +84,19 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I this.telemetryService.publicLog2<{ timeMs: number; timedOut: boolean; + detectedMoves: number; }, { owner: 'hediet'; timeMs: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To understand if the new diff algorithm is slower/faster than the old one' }; timedOut: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To understand how often the new diff algorithm times out' }; + detectedMoves: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'To understand how often the new diff algorithm detects moves' }; comment: 'This event gives insight about the performance of the new diff algorithm.'; }>('diffEditor.computeDiff', { timeMs, timedOut: result?.quitEarly ?? true, + detectedMoves: options.computeMoves ? (result?.moves.length ?? 0) : -1, }); if (cancellationToken.isCancellationRequested) { From 8f65d452dbe19790d952e87ccda6a0e981f68df5 Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Mon, 28 Aug 2023 08:32:40 -0700 Subject: [PATCH 018/198] Add aiGenerated tag for generated workspaces. (#191467) Update tags to include aiGenerated tag --- .../tags/electron-sandbox/workspaceTagsService.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts index c53bc26175e..ad3172b3878 100644 --- a/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts +++ b/src/vs/workbench/contrib/tags/electron-sandbox/workspaceTagsService.ts @@ -638,6 +638,21 @@ export class WorkspaceTagsService implements IWorkspaceTagsService { return Promise.resolve(tags); } + const aiGeneratedWorkspaces = URI.joinPath(this.environmentService.workspaceStorageHome, 'aiGeneratedWorkspaces.json'); + await this.fileService.exists(aiGeneratedWorkspaces).then(async result => { + if (result) { + try { + const content = await this.fileService.readFile(aiGeneratedWorkspaces); + const workspaces = JSON.parse(content.value.toString()) as string[]; + if (workspaces.indexOf(workspace.folders[0].uri.toString()) > -1) { + tags['aiGenerated'] = true; + } + } catch (e) { + // Ignore errors when resolving file contents + } + } + }); + return this.fileService.resolveAll(folders.map(resource => ({ resource }))).then((files: IFileStatResult[]) => { const names = ([]).concat(...files.map(result => result.success ? (result.stat!.children || []) : [])).map(c => c.name); const nameSet = names.reduce((s, n) => s.add(n.toLowerCase()), new Set()); From 0555ea55be59a8b5f23cf5ad74f2f940801dc0d5 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 09:22:15 -0700 Subject: [PATCH 019/198] fix #189981 --- .../accessibility/browser/accessibleView.ts | 27 +++++++++++----- .../browser/accessibility/accessibility.css | 31 +++++++++++++++++++ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 0cc34ecd49c..8b9a071a1dc 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -105,9 +105,11 @@ class AccessibleView extends Disposable { private _accessibleViewCurrentProviderId: IContextKey; get editorWidget() { return this._editorWidget; } - private _editorContainer: HTMLElement; - private _currentProvider: IAccessibleContentProvider | undefined; + private _container: HTMLElement; + private _title: HTMLElement; private readonly _toolbar: WorkbenchToolBar; + + private _currentProvider: IAccessibleContentProvider | undefined; private _currentContent: string | undefined; constructor( @@ -131,12 +133,21 @@ class AccessibleView extends Disposable { this._accessibleViewGoToSymbolSupported = accessibleViewGoToSymbolSupported.bindTo(this._contextKeyService); this._accessibleViewCurrentProviderId = accessibleViewCurrentProviderId.bindTo(this._contextKeyService); - this._editorContainer = document.createElement('div'); - this._editorContainer.classList.add('accessible-view'); + this._container = document.createElement('div'); + this._container.classList.add('accessible-view'); const codeEditorWidgetOptions: ICodeEditorWidgetOptions = { contributions: EditorExtensionsRegistry.getEditorContributions().filter(c => c.id !== CodeActionController.ID) }; - this._toolbar = this._register(_instantiationService.createInstance(WorkbenchToolBar, this._editorContainer, { orientation: ActionsOrientation.HORIZONTAL })); + const titleBar = document.createElement('div'); + titleBar.classList.add('accessible-view-title-bar'); + this._title = document.createElement('div'); + this._title.classList.add('accessible-view-title'); + titleBar.appendChild(this._title); + const actionBar = document.createElement('div'); + actionBar.classList.add('accessible-view-action-bar'); + titleBar.appendChild(actionBar); + this._container.appendChild(titleBar); + this._toolbar = this._register(_instantiationService.createInstance(WorkbenchToolBar, actionBar, { orientation: ActionsOrientation.HORIZONTAL })); this._toolbar.context = { viewId: 'accessibleView' }; const toolbarElt = this._toolbar.getElement(); toolbarElt.tabIndex = 0; @@ -155,7 +166,7 @@ class AccessibleView extends Disposable { readOnly: true, fontFamily: 'var(--monaco-monospace-font)' }; - this._editorWidget = this._register(this._instantiationService.createInstance(CodeEditorWidget, this._editorContainer, editorOptions, codeEditorWidgetOptions)); + this._editorWidget = this._register(this._instantiationService.createInstance(CodeEditorWidget, this._container, editorOptions, codeEditorWidgetOptions)); this._register(this._accessibilityService.onDidChangeScreenReaderOptimized(() => { if (this._currentProvider && this._accessiblityHelpIsShown.get()) { this.show(this._currentProvider); @@ -334,7 +345,6 @@ class AccessibleView extends Disposable { message += '\n'; } } - this._currentContent = message + provider.provideContent() + readMoreLink + disableHelpHint + localize('exit-tip', '\nExit this dialog via the Escape key.'); this._updateContextKeys(provider, true); @@ -348,7 +358,7 @@ class AccessibleView extends Disposable { return; } model.setLanguage(provider.options.language ?? 'markdown'); - container.appendChild(this._editorContainer); + container.appendChild(this._container); let actionsHint = ''; const verbose = this._configurationService.getValue(provider.verbositySettingKey); const hasActions = this._accessibleViewSupportsNavigation.get() || this._accessibleViewVerbosityEnabled.get() || this._accessibleViewGoToSymbolSupported.get() || this._currentProvider?.actions; @@ -356,6 +366,7 @@ class AccessibleView extends Disposable { actionsHint = localize('ariaAccessibleViewActions', "Use Shift+Tab to explore actions such as disabling this hint."); } let ariaLabel = provider.options.type === AccessibleViewType.Help ? localize('accessibility-help', "Accessibility Help") : localize('accessible-view', "Accessible View"); + this._title.textContent = ariaLabel; if (actionsHint && provider.options.type === AccessibleViewType.View) { ariaLabel = localize('accessible-view-hint', "Accessible View, {0}", actionsHint); } else if (actionsHint) { diff --git a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css index 25fcb4b03d8..f8044ced3b2 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css +++ b/src/vs/workbench/contrib/codeEditor/browser/accessibility/accessibility.css @@ -21,3 +21,34 @@ width: 100%; justify-content: flex-end; } + +.accessible-view-title-bar { + display: flex; + align-items: center; + border-top-left-radius: 5px; + border-top-right-radius: 5px; +} + +.accessible-view-title { + padding: 3px 0px; + text-align: center; + text-overflow: ellipsis; + overflow: hidden; + width: 100%; +} + +.accessible-view-action-bar { + justify-content: flex-end; + margin-right: 4px; + flex: 1; +} + +.accessible-view-action-bar > .actions-container { + justify-content: flex-end; +} + +.accessible-view-title-bar .monaco-action-bar .action-label.codicon { + background-position: center; + background-repeat: no-repeat; + padding: 2px; +} From 97f81a9dac483a1d69489264c852610b88541a92 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 09:27:59 -0700 Subject: [PATCH 020/198] fix #189984 --- .../contrib/accessibility/browser/accessibleViewActions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts index 6c3034b4b05..21547678e51 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts @@ -42,7 +42,7 @@ class AccessibleViewNextAction extends Action2 { ...accessibleViewMenu, when: ContextKeyExpr.and(accessibleViewIsShown, accessibleViewSupportsNavigation), }], - icon: Codicon.chevronRight, + icon: Codicon.arrowDown, title: localize('editor.action.accessibleViewNext', "Show Next in Accessible View") }); } @@ -62,7 +62,7 @@ class AccessibleViewPreviousAction extends Action2 { primary: KeyMod.Alt | KeyCode.BracketLeft, weight: KeybindingWeight.WorkbenchContrib }, - icon: Codicon.chevronLeft, + icon: Codicon.arrowUp, menu: [ commandPalette, { From ff87edf5031e64b859796951dbf46fd9d3465e54 Mon Sep 17 00:00:00 2001 From: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> Date: Mon, 28 Aug 2023 09:29:02 -0700 Subject: [PATCH 021/198] Recommend release on Stable, pre-release otherwise (#191477) --- .../workbench/contrib/preferences/browser/settingsEditor2.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index d0666ca8be5..d751cf35bdd 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -1273,8 +1273,9 @@ export class SettingsEditor2 extends EditorPane { if (toggleData && groups.filter(g => g.extensionInfo).length) { for (const key in toggleData.settingsEditorRecommendedExtensions) { const extensionId = key; - // Always recommend prerelease for now. - const [extension] = await this.extensionGalleryService.getExtensions([{ id: extensionId, preRelease: true }], CancellationToken.None); + // Recommend prerelease if not on Stable. + const isStable = this.productService.quality === 'stable'; + const [extension] = await this.extensionGalleryService.getExtensions([{ id: extensionId, preRelease: !isStable }], CancellationToken.None); if (!extension) { continue; } From 264cd8b0803ad673ebe8a97fa523c865a4c28d78 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 09:44:38 -0700 Subject: [PATCH 022/198] fix bug --- .../workbench/contrib/accessibility/browser/accessibleView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 8b9a071a1dc..2c7b4780c06 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -506,9 +506,9 @@ class AccessibleView extends Disposable { let hint = ''; const disableKeybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.DisableVerbosityHint, this._contextKeyService)?.getAriaLabel(); if (disableKeybinding) { - hint = localize('acessibleViewDisableHint', "Disable the aria label hint to open this ({0})", disableKeybinding); + hint = localize('acessibleViewDisableHint', "Disable the aria label hint to open this ({0}).\n", disableKeybinding); } else { - hint = localize('accessibleViewDisableHintNoKb', "Add a keybinding for the command Disable Accessible View Hint to disable this hint"); + hint = localize('accessibleViewDisableHintNoKb', "Add a keybinding for the command Disable Accessible View Hint to disable this hint.\n"); } return hint; } From e311d61ab836041a644c3e3c4000ca27f3dadeff Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 09:45:48 -0700 Subject: [PATCH 023/198] add periods --- src/vs/editor/common/standaloneStrings.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/common/standaloneStrings.ts b/src/vs/editor/common/standaloneStrings.ts index 87a6d066017..1f9525d2024 100644 --- a/src/vs/editor/common/standaloneStrings.ts +++ b/src/vs/editor/common/standaloneStrings.ts @@ -10,17 +10,17 @@ export namespace AccessibilityHelpNLS { export const openingDocs = nls.localize("openingDocs", "Now opening the Accessibility documentation page."); export const readonlyDiffEditor = nls.localize("readonlyDiffEditor", "You are in a read-only pane of a diff editor."); export const editableDiffEditor = nls.localize("editableDiffEditor", "You are in a pane of a diff editor."); - export const readonlyEditor = nls.localize("readonlyEditor", "You are in a read-only code editor"); - export const editableEditor = nls.localize("editableEditor", "You are in a code editor"); + export const readonlyEditor = nls.localize("readonlyEditor", "You are in a read-only code editor."); + export const editableEditor = nls.localize("editableEditor", "You are in a code editor."); export const changeConfigToOnMac = nls.localize("changeConfigToOnMac", "To configure the application to be optimized for usage with a Screen Reader press Command+E now."); export const changeConfigToOnWinLinux = nls.localize("changeConfigToOnWinLinux", "To configure the application to be optimized for usage with a Screen Reader press Control+E now."); export const auto_on = nls.localize("auto_on", "The application is configured to be optimized for usage with a Screen Reader."); - export const auto_off = nls.localize("auto_off", "The application is configured to never be optimized for usage with a Screen Reader"); + export const auto_off = nls.localize("auto_off", "The application is configured to never be optimized for usage with a Screen Reader."); export const screenReaderModeEnabled = nls.localize("screenReaderModeEnabled", "Screen Reader Optimized Mode enabled."); export const screenReaderModeDisabled = nls.localize("screenReaderModeDisabled", "Screen Reader Optimized Mode disabled."); export const tabFocusModeOnMsg = nls.localize("tabFocusModeOnMsg", "Pressing Tab in the current editor will move focus to the next focusable element. Toggle this behavior by pressing {0}."); export const tabFocusModeOnMsgNoKb = nls.localize("tabFocusModeOnMsgNoKb", "Pressing Tab in the current editor will move focus to the next focusable element. The command {0} is currently not triggerable by a keybinding."); - export const stickScrollKb = nls.localize("stickScrollKb", "Run the command: Focus Sticky Scroll ({0}) to focus the currently nested scopes"); + export const stickScrollKb = nls.localize("stickScrollKb", "Run the command: Focus Sticky Scroll ({0}) to focus the currently nested scopes."); export const stickScrollNoKb = nls.localize("stickScrollNoKb", "Run the command: Focus Sticky Scroll to focus the currently nested scopes. It is currently not triggerable by a keybinding."); export const tabFocusModeOffMsg = nls.localize("tabFocusModeOffMsg", "Pressing Tab in the current editor will insert the tab character. Toggle this behavior by pressing {0}."); export const tabFocusModeOffMsgNoKb = nls.localize("tabFocusModeOffMsgNoKb", "Pressing Tab in the current editor will insert the tab character. The command {0} is currently not triggerable by a keybinding."); From 77187a9bb864ca2e522d5727f53cebfea5a5179d Mon Sep 17 00:00:00 2001 From: Logan Ramos Date: Mon, 28 Aug 2023 09:56:39 -0700 Subject: [PATCH 024/198] Add cleaning and logging for extension error data (#191331) Add cleaning and logging for error data --- .../workbench/api/common/extHostTelemetry.ts | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/api/common/extHostTelemetry.ts b/src/vs/workbench/api/common/extHostTelemetry.ts index 0fb5ed2ce40..ea9d652f143 100644 --- a/src/vs/workbench/api/common/extHostTelemetry.ts +++ b/src/vs/workbench/api/common/extHostTelemetry.ts @@ -275,8 +275,24 @@ export class ExtHostTelemetryLogger { if (typeof eventNameOrException === 'string') { this.logEvent(eventNameOrException, data); } else { - // TODO @lramos15, implement cleaning for and logging for this case - this._sender.sendErrorData(eventNameOrException, data); + const errorData = { + name: eventNameOrException.name, + message: eventNameOrException.message, + stack: eventNameOrException.stack, + cause: eventNameOrException.cause + }; + const cleanedErrorData = cleanData(errorData, []); + // Reconstruct the error object with the cleaned data + const cleanedError = new Error(cleanedErrorData.message, { + cause: cleanedErrorData.cause + }); + cleanedError.stack = cleanedErrorData.stack; + cleanedError.name = cleanedErrorData.name; + data = this.mixInCommonPropsAndCleanData(data || {}); + if (!this._inLoggingOnlyMode) { + this._sender.sendErrorData(cleanedError, data); + } + this._logger.trace('exception', data); } } From 738234ab526f5a24cc3703b6dc3d2a94af3c7a11 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Mon, 28 Aug 2023 17:24:11 +0000 Subject: [PATCH 025/198] Update `EnvironmentVariableScope` --- src/vscode-dts/vscode.d.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index d440e2d2fc1..ec7dfa27120 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -11475,12 +11475,15 @@ declare module 'vscode' { getScoped(scope: EnvironmentVariableScope): EnvironmentVariableCollection; } - export type EnvironmentVariableScope = { + /** + * The scope object to which the environment variable collection applies to. + */ + export interface EnvironmentVariableScope { /** * Any specific workspace folder to get collection for. */ workspaceFolder?: WorkspaceFolder; - }; + } /** * A location in the editor at which progress information can be shown. It depends on the From 7360269b7a4ff1011e8d1186c5a49f8bc1c59f98 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Mon, 28 Aug 2023 10:37:08 -0700 Subject: [PATCH 026/198] Update src/vscode-dts/vscode.d.ts Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com> --- src/vscode-dts/vscode.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index ec7dfa27120..5a146bee7bb 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -11476,7 +11476,7 @@ declare module 'vscode' { } /** - * The scope object to which the environment variable collection applies to. + * The scope object to which the environment variable collection applies. */ export interface EnvironmentVariableScope { /** From a7a40fe0315138dc2fdd0367fd041f4454990dbd Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 28 Aug 2023 10:49:56 -0700 Subject: [PATCH 027/198] Misc UX polishes of Quick Chat (#191483) * rounded bottom * max height of sash --- src/vs/workbench/contrib/chat/browser/chatQuick.ts | 10 +++++++--- src/vs/workbench/contrib/chat/browser/media/chat.css | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index 32b6ca797fd..76bea4666b7 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -26,7 +26,7 @@ export class QuickChatService extends Disposable implements IQuickChatService { readonly onDidClose = this._onDidClose.event; private _input: IQuickWidget | undefined; - // TODO: support multiple chat providers eventually + // TODO@TylerLeonhardt: support multiple chat providers eventually private _currentChat: QuickChat | undefined; private _container: HTMLElement | undefined; @@ -119,6 +119,10 @@ export class QuickChatService extends Disposable implements IQuickChatService { } class QuickChat extends Disposable { + // TODO@TylerLeonhardt: be responsive to window size + static DEFAULT_MIN_HEIGHT = 200; + static DEFAULT_MAX_HEIGHT = 900; + private widget!: ChatWidget; private sash!: Sash; private model: ChatModel | undefined; @@ -178,7 +182,7 @@ class QuickChat extends Disposable { })); this.widget.render(parent); this.widget.setVisible(true); - this.widget.setDynamicChatTreeItemLayout(2, 900); + this.widget.setDynamicChatTreeItemLayout(2, QuickChat.DEFAULT_MAX_HEIGHT); this.updateModel(); this.sash = this._register(new Sash(parent, { getHorizontalSashTop: () => parent.offsetHeight }, { orientation: Orientation.HORIZONTAL })); this.registerListeners(parent); @@ -192,7 +196,7 @@ class QuickChat extends Disposable { this._register(this.widget.onDidChangeHeight((e) => this.sash.layout())); const width = parent.offsetWidth; this._register(this.sash.onDidChange((e) => { - if (e.currentY < 200) { + if (e.currentY < QuickChat.DEFAULT_MIN_HEIGHT || e.currentY > QuickChat.DEFAULT_MAX_HEIGHT) { return; } this.widget.layout(e.currentY, width); diff --git a/src/vs/workbench/contrib/chat/browser/media/chat.css b/src/vs/workbench/contrib/chat/browser/media/chat.css index 60b78970f75..5c36c297345 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chat.css +++ b/src/vs/workbench/contrib/chat/browser/media/chat.css @@ -429,6 +429,11 @@ border-radius: 2px; } +.quick-input-widget .interactive-list { + border-bottom-right-radius: 6px; + border-bottom-left-radius: 6px; +} + /* #endregion */ .interactive-response-progress-tree .monaco-tl-row:hover { From 3500c500450d4326a77dd66458d7ee92dc88814b Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Mon, 28 Aug 2023 10:55:13 -0700 Subject: [PATCH 028/198] fix #191490 --- src/vs/workbench/contrib/terminal/common/terminal.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 77e37c5b574..2c67eda18cb 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -568,6 +568,7 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [ TerminalCommandId.AcceptSelectedSuggestion, TerminalCommandId.HideSuggestWidget, TerminalCommandId.FocusHover, + TerminalCommandId.FocusAccessibleBuffer, AccessibilityCommandId.OpenAccessibilityHelp, 'editor.action.toggleTabFocusMode', 'notifications.hideList', From ed1a0e3b20d4f5c4a22ae4cb773ca6070ba2c6af Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 28 Aug 2023 19:45:16 +0200 Subject: [PATCH 029/198] Adds diffEditor.hideUnchangedRegions settings. Fixes #190886, fixes #190887 --- .../editor/browser/widget/diffEditorWidget.ts | 18 ++++++++- .../diffEditorWidget2/diffEditorEditors.ts | 2 +- .../diffEditorWidget2/diffEditorOptions.ts | 40 ++++++------------- .../diffEditorWidget2/diffEditorViewModel.ts | 33 ++++++++++----- .../diffEditorWidget2.contribution.ts | 6 +-- .../diffEditorWidget2/diffEditorWidget2.ts | 4 +- .../diffEditorWidget2/unchangedRanges.ts | 9 +++-- src/vs/editor/common/config/diffEditor.ts | 37 +++++++++++++++++ .../config/editorConfigurationSchema.ts | 27 +++++++++++-- src/vs/editor/common/config/editorOptions.ts | 11 +++-- .../browser/widget/diffEditorWidget2.test.ts | 8 ++++ src/vs/monaco.d.ts | 10 +++-- .../codeEditor/browser/diffEditorHelper.ts | 13 ++++++ 13 files changed, 156 insertions(+), 62 deletions(-) create mode 100644 src/vs/editor/common/config/diffEditor.ts diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 5588ae6f5ec..62d42cee6aa 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -297,7 +297,14 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE diffAlgorithm: 'advanced', accessibilityVerbose: false, experimental: { - collapseUnchangedRegions: false, + showEmptyDecorations: false, + showMoves: false, + }, + hideUnchangedRegions: { + enabled: false, + contextLineCount: 0, + minimumLineCount: 0, + revealLineCount: 0, }, isInEmbeddedEditor: false, onlyShowAccessibleDiffViewer: false, @@ -2743,8 +2750,15 @@ function validateDiffEditorOptions(options: Readonly, defaul diffWordWrap: validateDiffWordWrap(options.diffWordWrap, defaults.diffWordWrap), diffAlgorithm: validateStringSetOption(options.diffAlgorithm, defaults.diffAlgorithm, ['legacy', 'advanced'], { 'smart': 'legacy', 'experimental': 'advanced' }), accessibilityVerbose: validateBooleanOption(options.accessibilityVerbose, defaults.accessibilityVerbose), + hideUnchangedRegions: { + enabled: false, + contextLineCount: 0, + minimumLineCount: 0, + revealLineCount: 0, + }, experimental: { - collapseUnchangedRegions: false, + showEmptyDecorations: false, + showMoves: false, }, isInEmbeddedEditor: validateBooleanOption(options.isInEmbeddedEditor, defaults.isInEmbeddedEditor), onlyShowAccessibleDiffViewer: false, diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts index 642359aeae4..254ce84d2be 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors.ts @@ -147,7 +147,7 @@ export class DiffEditorEditors extends Disposable { clonedOptions.minimap = { ...(clonedOptions.minimap || {}) }; clonedOptions.minimap.enabled = false; - if (this._options.collapseUnchangedRegions.get()) { + if (this._options.hideUnchangedRegions.get()) { clonedOptions.stickyScroll = { enabled: false }; } else { clonedOptions.stickyScroll = this._options.editorOptions.get().stickyScroll; diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts index 97a4e2adaaf..ffb76330146 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorOptions.ts @@ -6,6 +6,7 @@ import { IObservable, ISettableObservable, derived, observableValue } from 'vs/base/common/observable'; import { Constants } from 'vs/base/common/uint'; import { IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser'; +import { diffEditorDefaultOptions } from 'vs/editor/common/config/diffEditor'; import { IDiffEditorBaseOptions, IDiffEditorOptions, IEditorOptions, ValidDiffEditorBaseOptions, clampedFloat, clampedInt, boolean as validateBooleanOption, stringSet as validateStringSetOption } from 'vs/editor/common/config/editorOptions'; export class DiffEditorOptions { @@ -37,7 +38,6 @@ export class DiffEditorOptions { }); public readonly renderIndicators = derived(reader => /** @description renderIndicators */ this._options.read(reader).renderIndicators); public readonly enableSplitViewResizing = derived(reader => /** @description enableSplitViewResizing */ this._options.read(reader).enableSplitViewResizing); - public readonly collapseUnchangedRegions = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).experimental.collapseUnchangedRegions!); public readonly splitViewDefaultRatio = derived(reader => /** @description splitViewDefaultRatio */ this._options.read(reader).splitViewDefaultRatio); public readonly ignoreTrimWhitespace = derived(reader => /** @description ignoreTrimWhitespace */ this._options.read(reader).ignoreTrimWhitespace); public readonly maxComputationTimeMs = derived(reader => /** @description maxComputationTime */ this._options.read(reader).maxComputationTime); @@ -51,6 +51,11 @@ export class DiffEditorOptions { public readonly showEmptyDecorations = derived(reader => /** @description showEmptyDecorations */ this._options.read(reader).experimental.showEmptyDecorations!); public readonly onlyShowAccessibleDiffViewer = derived(reader => /** @description onlyShowAccessibleDiffViewer */ this._options.read(reader).onlyShowAccessibleDiffViewer); + public readonly hideUnchangedRegions = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.enabled!); + public readonly hideUnchangedRegionsRevealLineCount = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.revealLineCount!); + public readonly hideUnchangedRegionsContextLineCount = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.contextLineCount!); + public readonly hideUnchangedRegionsminimumLineCount = derived(reader => /** @description hideUnchangedRegions */ this._options.read(reader).hideUnchangedRegions.minimumLineCount!); + public updateOptions(changedOptions: IDiffEditorOptions): void { const newDiffEditorOptions = validateDiffEditorOptions(changedOptions, this._options.get()); const newOptions = { ...this._options.get(), ...changedOptions, ...newDiffEditorOptions }; @@ -58,32 +63,6 @@ export class DiffEditorOptions { } } -const diffEditorDefaultOptions: ValidDiffEditorBaseOptions = { - enableSplitViewResizing: true, - splitViewDefaultRatio: 0.5, - renderSideBySide: true, - renderMarginRevertIcon: true, - maxComputationTime: 5000, - maxFileSize: 50, - ignoreTrimWhitespace: true, - renderIndicators: true, - originalEditable: false, - diffCodeLens: false, - renderOverviewRuler: true, - diffWordWrap: 'inherit', - diffAlgorithm: 'advanced', - accessibilityVerbose: false, - experimental: { - collapseUnchangedRegions: false, - showMoves: false, - showEmptyDecorations: true, - }, - isInEmbeddedEditor: false, - onlyShowAccessibleDiffViewer: false, - renderSideBySideInlineBreakpoint: 900, - useInlineViewWhenSpaceIsLimited: true, -}; - function validateDiffEditorOptions(options: Readonly, defaults: ValidDiffEditorBaseOptions): ValidDiffEditorBaseOptions { return { enableSplitViewResizing: validateBooleanOption(options.enableSplitViewResizing, defaults.enableSplitViewResizing), @@ -101,10 +80,15 @@ function validateDiffEditorOptions(options: Readonly, defaul diffAlgorithm: validateStringSetOption(options.diffAlgorithm, defaults.diffAlgorithm, ['legacy', 'advanced'], { 'smart': 'legacy', 'experimental': 'advanced' }), accessibilityVerbose: validateBooleanOption(options.accessibilityVerbose, defaults.accessibilityVerbose), experimental: { - collapseUnchangedRegions: validateBooleanOption(options.experimental?.collapseUnchangedRegions, defaults.experimental.collapseUnchangedRegions!), showMoves: validateBooleanOption(options.experimental?.showMoves, defaults.experimental.showMoves!), showEmptyDecorations: validateBooleanOption(options.experimental?.showEmptyDecorations, defaults.experimental.showEmptyDecorations!), }, + hideUnchangedRegions: { + enabled: validateBooleanOption(options.hideUnchangedRegions?.enabled ?? (options.experimental as any)?.collapseUnchangedRegions, defaults.hideUnchangedRegions.enabled!), + contextLineCount: clampedInt(options.hideUnchangedRegions?.contextLineCount, defaults.hideUnchangedRegions.contextLineCount!, 0, Constants.MAX_SAFE_SMALL_INTEGER), + minimumLineCount: clampedInt(options.hideUnchangedRegions?.minimumLineCount, defaults.hideUnchangedRegions.minimumLineCount!, 0, Constants.MAX_SAFE_SMALL_INTEGER), + revealLineCount: clampedInt(options.hideUnchangedRegions?.revealLineCount, defaults.hideUnchangedRegions.revealLineCount!, 0, Constants.MAX_SAFE_SMALL_INTEGER), + }, isInEmbeddedEditor: validateBooleanOption(options.isInEmbeddedEditor, defaults.isInEmbeddedEditor), onlyShowAccessibleDiffViewer: validateBooleanOption(options.onlyShowAccessibleDiffViewer, defaults.onlyShowAccessibleDiffViewer), renderSideBySideInlineBreakpoint: clampedInt(options.renderSideBySideInlineBreakpoint, defaults.renderSideBySideInlineBreakpoint, 0, Constants.MAX_SAFE_SMALL_INTEGER), diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 58a4694c317..aff79983e40 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -35,7 +35,7 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ); public readonly unchangedRegions: IObservable = derived(r => { /** @description unchangedRegions */ - if (this._options.collapseUnchangedRegions.read(r)) { + if (this._options.hideUnchangedRegions.read(r)) { return this._unchangedRegions.read(r).regions; } else { // Reset state @@ -79,8 +79,14 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo const contentChangedSignal = observableSignal('contentChangedSignal'); const debouncer = this._register(new RunOnceScheduler(() => contentChangedSignal.trigger(undefined), 200)); - const updateUnchangedRegions = (result: IDocumentDiff, tx: ITransaction) => { - const newUnchangedRegions = UnchangedRegion.fromDiffs(result.changes, model.original.getLineCount(), model.modified.getLineCount()); + const updateUnchangedRegions = (result: IDocumentDiff, tx: ITransaction, reader?: IReader) => { + const newUnchangedRegions = UnchangedRegion.fromDiffs( + result.changes, + model.original.getLineCount(), + model.modified.getLineCount(), + this._options.hideUnchangedRegionsminimumLineCount.read(reader), + this._options.hideUnchangedRegionsContextLineCount.read(reader), + ); // Transfer state from cur state const lastUnchangedRegions = this._unchangedRegions.get(); @@ -122,7 +128,6 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo ); }; - this._register(model.modified.onDidChangeContent((e) => { const diff = this._diff.get(); if (diff) { @@ -164,6 +169,11 @@ export class DiffEditorViewModel extends Disposable implements IDiffEditorViewMo this._register(autorunWithStore(async (reader, store) => { /** @description compute diff */ + + // So that they get recomputed when these settings change + this._options.hideUnchangedRegionsminimumLineCount.read(reader); + this._options.hideUnchangedRegionsContextLineCount.read(reader); + debouncer.cancel(); contentChangedSignal.read(reader); documentDiffProviderOptionChanged.read(reader); @@ -310,13 +320,16 @@ export class DiffMapping { } export class UnchangedRegion { - public static fromDiffs(changes: readonly LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): UnchangedRegion[] { + public static fromDiffs( + changes: readonly LineRangeMapping[], + originalLineCount: number, + modifiedLineCount: number, + minHiddenLineCount: number, + minContext: number, + ): UnchangedRegion[] { const inversedMappings = LineRangeMapping.inverse(changes, originalLineCount, modifiedLineCount); const result: UnchangedRegion[] = []; - const minHiddenLineCount = 3; - const minContext = 3; - for (const mapping of inversedMappings) { let origStart = mapping.originalRange.startLineNumber; let modStart = mapping.modifiedRange.startLineNumber; @@ -325,7 +338,7 @@ export class UnchangedRegion { const atStart = origStart === 1 && modStart === 1; const atEnd = origStart + length === originalLineCount + 1 && modStart + length === modifiedLineCount + 1; - if ((atStart || atEnd) && length > minContext + minHiddenLineCount) { + if ((atStart || atEnd) && length >= minContext + minHiddenLineCount) { if (atStart && !atEnd) { length -= minContext; } @@ -335,7 +348,7 @@ export class UnchangedRegion { length -= minContext; } result.push(new UnchangedRegion(origStart, modStart, length, 0, 0)); - } else if (length > minContext * 2 + minHiddenLineCount) { + } else if (length >= minContext * 2 + minHiddenLineCount) { origStart += minContext; modStart += minContext; length -= minContext * 2; diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts index abb62f83158..79ef25a3e44 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.contribution.ts @@ -23,7 +23,7 @@ export class ToggleCollapseUnchangedRegions extends Action2 { title: { value: localize('toggleCollapseUnchangedRegions', "Toggle Collapse Unchanged Regions"), original: 'Toggle Collapse Unchanged Regions' }, icon: Codicon.map, precondition: ContextKeyEqualsExpr.create('diffEditorVersion', 2), - toggled: ContextKeyExpr.has('config.diffEditor.experimental.collapseUnchangedRegions'), + toggled: ContextKeyExpr.has('config.diffEditor.hideUnchangedRegions.enabled'), menu: { id: MenuId.EditorTitle, order: 22, @@ -35,8 +35,8 @@ export class ToggleCollapseUnchangedRegions extends Action2 { run(accessor: ServicesAccessor, ...args: unknown[]): void { const configurationService = accessor.get(IConfigurationService); - const newValue = !configurationService.getValue('diffEditor.experimental.collapseUnchangedRegions'); - configurationService.updateValue('diffEditor.experimental.collapseUnchangedRegions', newValue); + const newValue = !configurationService.getValue('diffEditor.hideUnchangedRegions.enabled'); + configurationService.updateValue('diffEditor.hideUnchangedRegions.enabled', newValue); } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 090655ac00d..9d5047da806 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -82,7 +82,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { private readonly movedBlocksLinesPart = observableValue('MovedBlocksLinesPart', undefined); - public get collapseUnchangedRegions() { return this._options.collapseUnchangedRegions.get(); } + public get collapseUnchangedRegions() { return this._options.hideUnchangedRegions.get(); } constructor( private readonly _domElement: HTMLElement, @@ -232,7 +232,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(applyStyle(this.elements.overlay, { width: this._layoutInfo.map((i, r) => i.originalEditor.width + (this._options.renderSideBySide.read(r) ? 0 : i.modifiedEditor.width)), - visibility: derived(reader => /** @description visibility */(this._options.collapseUnchangedRegions.read(reader) && this._diffModel.read(reader)?.diff.read(reader)?.mappings.length === 0) + visibility: derived(reader => /** @description visibility */(this._options.hideUnchangedRegions.read(reader) && this._diffModel.read(reader)?.diff.read(reader)?.mappings.length === 0) ? 'visible' : 'hidden' ), })); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index f9a38f16b69..5b5c4ecc2a9 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -94,13 +94,13 @@ export class UnchangedRangesFeature extends Disposable { const d = derived(reader => /** @description hiddenOriginalRangeStart */ r.getHiddenOriginalRange(reader).startLineNumber - 1); const origVz = new PlaceholderViewZone(d, 24); origViewZones.push(origVz); - store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, r.originalRange, !sideBySide, modifiedOutlineSource, l => this._diffModel.get()!.ensureOriginalLineIsVisible(l, undefined))); + store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, r.originalRange, !sideBySide, modifiedOutlineSource, l => this._diffModel.get()!.ensureOriginalLineIsVisible(l, undefined), this._options)); } { const d = derived(reader => /** @description hiddenModifiedRangeStart */ r.getHiddenModifiedRange(reader).startLineNumber - 1); const modViewZone = new PlaceholderViewZone(d, 24); modViewZones.push(modViewZone); - store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, r.modifiedRange, false, modifiedOutlineSource, l => this._diffModel.get()!.ensureModifiedLineIsVisible(l, undefined))); + store.add(new CollapsedCodeOverlayWidget(this._editors.modified, modViewZone, r, r.modifiedRange, false, modifiedOutlineSource, l => this._diffModel.get()!.ensureModifiedLineIsVisible(l, undefined), this._options)); } } @@ -266,6 +266,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { private readonly hide: boolean, private readonly _modifiedOutlineSource: OutlineSource, private readonly _revealHiddenLine: (lineNumber: number) => void, + private readonly _options: DiffEditorOptions, ) { const root = h('div.diff-hidden-lines-widget'); super(_editor, _viewZone, root.root); @@ -307,7 +308,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { const mouseUpListener = addDisposableListener(window, 'mouseup', e => { if (!didMove) { - this._unchangedRegion.showMoreAbove(20, undefined); + this._unchangedRegion.showMoreAbove(this._options.hideUnchangedRegionsRevealLineCount.get(), undefined); } this._nodes.top.classList.toggle('dragging', false); this._nodes.root.classList.toggle('dragging', false); @@ -347,7 +348,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { if (!didMove) { const top = editor.getTopForLineNumber(this._unchangedRegionRange.endLineNumberExclusive); - this._unchangedRegion.showMoreBelow(20, undefined); + this._unchangedRegion.showMoreBelow(this._options.hideUnchangedRegionsRevealLineCount.get(), undefined); const top2 = editor.getTopForLineNumber(this._unchangedRegionRange.endLineNumberExclusive); editor.setScrollTop(editor.getScrollTop() + (top2 - top)); } diff --git a/src/vs/editor/common/config/diffEditor.ts b/src/vs/editor/common/config/diffEditor.ts new file mode 100644 index 00000000000..2f2bc06f2d2 --- /dev/null +++ b/src/vs/editor/common/config/diffEditor.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ValidDiffEditorBaseOptions } from 'vs/editor/common/config/editorOptions'; + +export const diffEditorDefaultOptions: ValidDiffEditorBaseOptions = { + enableSplitViewResizing: true, + splitViewDefaultRatio: 0.5, + renderSideBySide: true, + renderMarginRevertIcon: true, + maxComputationTime: 5000, + maxFileSize: 50, + ignoreTrimWhitespace: true, + renderIndicators: true, + originalEditable: false, + diffCodeLens: false, + renderOverviewRuler: true, + diffWordWrap: 'inherit', + diffAlgorithm: 'advanced', + accessibilityVerbose: false, + experimental: { + showMoves: false, + showEmptyDecorations: true, + }, + hideUnchangedRegions: { + enabled: false, + contextLineCount: 3, + minimumLineCount: 3, + revealLineCount: 20, + }, + isInEmbeddedEditor: false, + onlyShowAccessibleDiffViewer: false, + renderSideBySideInlineBreakpoint: 900, + useInlineViewWhenSpaceIsLimited: true, +}; diff --git a/src/vs/editor/common/config/editorConfigurationSchema.ts b/src/vs/editor/common/config/editorConfigurationSchema.ts index b605d1dadf3..0123d64e587 100644 --- a/src/vs/editor/common/config/editorConfigurationSchema.ts +++ b/src/vs/editor/common/config/editorConfigurationSchema.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { diffEditorDefaultOptions } from 'vs/editor/common/config/diffEditor'; import { editorOptionsRegistry } from 'vs/editor/common/config/editorOptions'; import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/core/textModelDefaults'; import * as nls from 'vs/nls'; @@ -206,17 +207,35 @@ const editorConfiguration: IConfigurationNode = { 'diffEditor.diffAlgorithm': { type: 'string', enum: ['legacy', 'advanced'], - default: 'advanced', + default: diffEditorDefaultOptions.diffAlgorithm, markdownEnumDescriptions: [ nls.localize('diffAlgorithm.legacy', "Uses the legacy diffing algorithm."), nls.localize('diffAlgorithm.advanced', "Uses the advanced diffing algorithm."), ], tags: ['experimental'], }, - 'diffEditor.experimental.collapseUnchangedRegions': { + 'diffEditor.hideUnchangedRegions.enabled': { type: 'boolean', - default: false, - markdownDescription: nls.localize('collapseUnchangedRegions', "Controls whether the diff editor shows unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'), + default: diffEditorDefaultOptions.hideUnchangedRegions.enabled, + markdownDescription: nls.localize('hideUnchangedRegions.enabled', "Controls whether the diff editor shows unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'), + }, + 'diffEditor.hideUnchangedRegions.revealLineCount': { + type: 'integer', + default: diffEditorDefaultOptions.hideUnchangedRegions.revealLineCount, + markdownDescription: nls.localize('hideUnchangedRegions.revealLineCount', "Controls how many lines are used for unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'), + minimum: 1, + }, + 'diffEditor.hideUnchangedRegions.minimumLineCount': { + type: 'integer', + default: diffEditorDefaultOptions.hideUnchangedRegions.minimumLineCount, + markdownDescription: nls.localize('hideUnchangedRegions.minimumLineCount', "Controls how many lines are used as a minimum for unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'), + minimum: 1, + }, + 'diffEditor.hideUnchangedRegions.contextLineCount': { + type: 'integer', + default: diffEditorDefaultOptions.hideUnchangedRegions.contextLineCount, + markdownDescription: nls.localize('hideUnchangedRegions.contextLineCount', "Controls how many lines are used as context when comparing unchanged regions. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`'), + minimum: 1, }, 'diffEditor.experimental.showMoves': { type: 'boolean', diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index eee7baf03c6..f338f7b0817 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -825,10 +825,6 @@ export interface IDiffEditorBaseOptions { accessibilityVerbose?: boolean; experimental?: { - /** - * Defaults to false. - */ - collapseUnchangedRegions?: boolean; /** * Defaults to false. */ @@ -847,6 +843,13 @@ export interface IDiffEditorBaseOptions { * If the diff editor should only show the difference review mode. */ onlyShowAccessibleDiffViewer?: boolean; + + hideUnchangedRegions?: { + enabled?: boolean; + revealLineCount?: number; + minimumLineCount?: number; + contextLineCount?: number; + }; } /** diff --git a/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts b/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts index 85c9043e060..c9980e34a08 100644 --- a/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts +++ b/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts @@ -19,6 +19,8 @@ suite('DiffEditorWidget2', () => { [new LineRangeMapping(new LineRange(1, 10), new LineRange(1, 10), [])], 10, 10, + 3, + 3, )), []); }); @@ -27,6 +29,8 @@ suite('DiffEditorWidget2', () => { [], 10, 10, + 3, + 3, )), [ "[1,11) - [1,11)" ]); @@ -37,6 +41,8 @@ suite('DiffEditorWidget2', () => { [new LineRangeMapping(new LineRange(50, 60), new LineRange(50, 60), [])], 100, 100, + 3, + 3, )), ([ '[1,47) - [1,47)', '[63,101) - [63,101)' @@ -48,6 +54,8 @@ suite('DiffEditorWidget2', () => { [new LineRangeMapping(new LineRange(99, 100), new LineRange(100, 100), [])], 100, 100, + 3, + 3, )), (["[1,96) - [1,96)"])); }); }); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 442b460ca18..3a49dbf4aa5 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3976,10 +3976,6 @@ declare namespace monaco.editor { */ accessibilityVerbose?: boolean; experimental?: { - /** - * Defaults to false. - */ - collapseUnchangedRegions?: boolean; /** * Defaults to false. */ @@ -3995,6 +3991,12 @@ declare namespace monaco.editor { * If the diff editor should only show the difference review mode. */ onlyShowAccessibleDiffViewer?: boolean; + hideUnchangedRegions?: { + enabled?: boolean; + revealLineCount?: number; + minimumLineCount?: number; + contextLineCount?: number; + }; } /** diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts index 22148696b72..f9f2bd13d28 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorHelper.ts @@ -23,6 +23,8 @@ import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibil import { AccessibleViewType, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { Registry } from 'vs/platform/registry/common/platform'; +import { Extensions, IConfigurationMigrationRegistry } from 'vs/workbench/common/configuration'; class DiffEditorHelperContribution extends Disposable implements IDiffEditorContribution { public static readonly ID = 'editor.contrib.diffEditorHelper'; @@ -120,3 +122,14 @@ function createScreenReaderHelp(): IDisposable { } registerDiffEditorContribution(DiffEditorHelperContribution.ID, DiffEditorHelperContribution); + +Registry.as(Extensions.ConfigurationMigration) + .registerConfigurationMigrations([{ + key: 'diffEditor.experimental.collapseUnchangedRegions', + migrateFn: (value, accessor) => { + return [ + ['diffEditor.hideUnchangedRegions.enabled', { value }], + ['diffEditor.experimental.collapseUnchangedRegions', { value: undefined }] + ]; + } + }]); From 5397203187a4c8b8b893f91a948b5984b1b3944a Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Mon, 28 Aug 2023 11:26:59 -0700 Subject: [PATCH 030/198] Sort slash commands by `yieldTo` (#191112) --- .../browser/contrib/chatInputEditorContrib.ts | 79 ++++++++++++++++++- .../contrib/chat/common/chatService.ts | 5 ++ .../vscode.proposed.interactive.d.ts | 1 + 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts index 9ef0f6b1601..8be40c833c1 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts @@ -24,7 +24,7 @@ import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart'; import { SlashCommandContentWidget } from 'vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget'; import { ChatWidget } from 'vs/workbench/contrib/chat/browser/chatWidget'; import { chatSlashCommandBackground, chatSlashCommandForeground } from 'vs/workbench/contrib/chat/common/chatColors'; -import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; +import { IChatService, ISlashCommand } from 'vs/workbench/contrib/chat/common/chatService'; import { IChatVariablesService } from 'vs/workbench/contrib/chat/common/chatVariables'; import { isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; @@ -253,14 +253,14 @@ class SlashCommandCompletions extends Disposable { } return { - suggestions: slashCommands.map(c => { + suggestions: sortSlashCommandsByYieldTo(slashCommands).map((c, i) => { const withSlash = `/${c.command}`; return { label: withSlash, insertText: c.executeImmediately ? '' : `${withSlash} `, detail: c.detail, range: new Range(1, 1, 1, 1), - sortText: c.sortText ?? c.command, + sortText: c.sortText ?? 'a'.repeat(i + 1), kind: CompletionItemKind.Text, // The icons are disabled here anyway, command: c.executeImmediately ? { id: SubmitAction.ID, title: withSlash, arguments: [{ widget, inputValue: `${withSlash} ` }] } : undefined, }; @@ -271,6 +271,79 @@ class SlashCommandCompletions extends Disposable { } } +interface SlashCommandYieldTo { + command: string; +} + +// Adapted from https://github.com/microsoft/vscode/blob/ca2c1636f87ea4705f32345c2e348e815996e129/src/vs/editor/contrib/dropOrPasteInto/browser/edit.ts#L31-L99 +function sortSlashCommandsByYieldTo; +}>(slashCommands: readonly T[]): T[] { + function yieldsTo(yTo: SlashCommandYieldTo, other: T): boolean { + return 'command' in yTo && other.command === yTo.command; + } + + // Build list of nodes each node yields to + const yieldsToMap = new Map(); + for (const slashCommand of slashCommands) { + for (const yTo of slashCommand.yieldsTo ?? []) { + for (const other of slashCommands) { + if (other.command === slashCommand.command) { + continue; + } + + if (yieldsTo(yTo, other)) { + let arr = yieldsToMap.get(slashCommand); + if (!arr) { + arr = []; + yieldsToMap.set(slashCommand, arr); + } + arr.push(other); + } + } + } + } + + if (!yieldsToMap.size) { + return Array.from(slashCommands); + } + + // Topological sort + const visited = new Set(); + const tempStack: T[] = []; + + function visit(nodes: T[]): T[] { + if (!nodes.length) { + return []; + } + + const node = nodes[0]; + if (tempStack.includes(node)) { + console.warn(`Yield to cycle detected for ${node.command}`); + return nodes; + } + + if (visited.has(node)) { + return visit(nodes.slice(1)); + } + + let pre: T[] = []; + const yTo = yieldsToMap.get(node); + if (yTo) { + tempStack.push(node); + pre = visit(yTo); + tempStack.pop(); + } + + visited.add(node); + + return [...pre, node, ...visit(nodes.slice(1))]; + } + + return visit(Array.from(slashCommands)); +} + Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(SlashCommandCompletions, LifecyclePhase.Eventually); class VariableCompletions extends Disposable { diff --git a/src/vs/workbench/contrib/chat/common/chatService.ts b/src/vs/workbench/contrib/chat/common/chatService.ts index 9039dfb5150..39fb93a4739 100644 --- a/src/vs/workbench/contrib/chat/common/chatService.ts +++ b/src/vs/workbench/contrib/chat/common/chatService.ts @@ -90,6 +90,11 @@ export interface ISlashCommand { * Has no effect if `shouldRepopulate` is `false`. */ followupPlaceholder?: string; + /** + * The slash command(s) that this command wants to be + * deprioritized in favor of. + */ + yieldsTo?: ReadonlyArray<{ readonly command: string }>; } export interface IChatReplyFollowup { diff --git a/src/vscode-dts/vscode.proposed.interactive.d.ts b/src/vscode-dts/vscode.proposed.interactive.d.ts index 8ec16060be1..39e1e22e191 100644 --- a/src/vscode-dts/vscode.proposed.interactive.d.ts +++ b/src/vscode-dts/vscode.proposed.interactive.d.ts @@ -159,6 +159,7 @@ declare module 'vscode' { shouldRepopulate?: boolean; followupPlaceholder?: string; executeImmediately?: boolean; + yieldTo?: ReadonlyArray<{ readonly command: string }>; } export interface InteractiveSessionReplyFollowup { From 3b4fdca0cda60b5d79a3c95abb56184b0232341f Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 11:39:57 -0700 Subject: [PATCH 031/198] fix #189776 --- src/vs/platform/terminal/common/terminal.ts | 1 + .../terminal/browser/terminalActions.ts | 18 ++++++++++++++++-- .../terminal/common/terminalConfiguration.ts | 11 +++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 235d8efdbe8..e7e9dbe82e2 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -114,6 +114,7 @@ export const enum TerminalSettingId { EnableImages = 'terminal.integrated.enableImages', SmoothScrolling = 'terminal.integrated.smoothScrolling', IgnoreBracketedPasteMode = 'terminal.integrated.ignoreBracketedPasteMode', + FocusAfterRun = 'terminal.integrated.focusAfterRun', // Debug settings that are hidden from user diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 8e58f90c8fc..62b3605a7d7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -15,7 +15,7 @@ import { URI } from 'vs/base/common/uri'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EndOfLinePreference } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; -import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; +import { CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { Action2, registerAction2, IAction2Options } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -131,6 +131,7 @@ export class TerminalLaunchHelpAction extends Action { } } + /** * A wrapper function around registerAction2 to help make registering terminal actions more concise. * The following default options are used if undefined: @@ -206,6 +207,7 @@ export function registerActiveXtermAction( }); } + export interface ITerminalServicesCollection { service: ITerminalService; groupService: ITerminalGroupService; @@ -547,6 +549,8 @@ export function registerTerminalActions() { title: { value: localize('workbench.action.terminal.runSelectedText', "Run Selected Text In Active Terminal"), original: 'Run Selected Text In Active Terminal' }, run: async (c, accessor) => { const codeEditorService = accessor.get(ICodeEditorService); + const configurationService = accessor.get(IConfigurationService); + const accessibilityService = accessor.get(IAccessibilityService); const editor = codeEditorService.getActiveCodeEditor(); if (!editor || !editor.hasModel()) { return; @@ -560,8 +564,18 @@ export function registerTerminalActions() { const endOfLinePreference = isWindows ? EndOfLinePreference.LF : EndOfLinePreference.CRLF; text = editor.getModel().getValueInRange(selection, endOfLinePreference); } - instance.sendText(text, true, true); + await instance.sendText(text, true, true); await c.service.revealActiveTerminal(); + const focusAfterRun = configurationService.getValue(TerminalSettingId.FocusAfterRun); + const focusTerminal = focusAfterRun === 'terminal' || (focusAfterRun === 'auto' && accessibilityService.isScreenReaderOptimized()); + if (focusTerminal) { + instance.focus(true); + } else if (focusAfterRun === 'accessible-buffer') { + const contribution = instance.getContribution('terminal.accessible-buffer'); + if (contribution) { + (contribution as any).show(); + } + } } }); diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index d92eac5fe3f..07dcce63ce9 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -609,6 +609,17 @@ const terminalConfiguration: IConfigurationNode = { type: 'boolean', default: true }, + [TerminalSettingId.FocusAfterRun]: { + markdownDescription: localize('terminal.integrated.focusAfterRun', "Controls whether the terminal, accessible buffer, or neither will be focused after `Terminal: Run Selected Text In Active Terminal` has been run."), + enum: ['auto', 'terminal', 'accessible-buffer', 'none'], + default: 'auto', + markdownEnumDescriptions: [ + localize('terminal.integrated.focusAfterRun.auto', "Set to `terminal` when in screen reader optimized mode and `none` otherwise."), + localize('terminal.integrated.focusAfterRun.terminal', "Always focus the terminal."), + localize('terminal.integrated.focusAfterRun.accessible-buffer', "Always focus the accessible buffer."), + localize('terminal.integrated.focusAfterRun.none', "Keep the focus in the editor."), + ] + } } }; From bf1d725ef44f65ac38d7bee5c8167814a43e8197 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 11:40:47 -0700 Subject: [PATCH 032/198] add accessibility tag --- .../workbench/contrib/terminal/common/terminalConfiguration.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 07dcce63ce9..b997c5e3c72 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -613,6 +613,7 @@ const terminalConfiguration: IConfigurationNode = { markdownDescription: localize('terminal.integrated.focusAfterRun', "Controls whether the terminal, accessible buffer, or neither will be focused after `Terminal: Run Selected Text In Active Terminal` has been run."), enum: ['auto', 'terminal', 'accessible-buffer', 'none'], default: 'auto', + tags: ['accessibility'], markdownEnumDescriptions: [ localize('terminal.integrated.focusAfterRun.auto', "Set to `terminal` when in screen reader optimized mode and `none` otherwise."), localize('terminal.integrated.focusAfterRun.terminal', "Always focus the terminal."), From d6c486841b7bb9f39467d9d47b5dc8dc0057d99c Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Mon, 28 Aug 2023 11:41:39 -0700 Subject: [PATCH 033/198] Apply suggestions from code review --- src/vs/workbench/contrib/terminal/browser/terminalActions.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 62b3605a7d7..dfcfe77d906 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -131,7 +131,6 @@ export class TerminalLaunchHelpAction extends Action { } } - /** * A wrapper function around registerAction2 to help make registering terminal actions more concise. * The following default options are used if undefined: @@ -207,7 +206,6 @@ export function registerActiveXtermAction( }); } - export interface ITerminalServicesCollection { service: ITerminalService; groupService: ITerminalGroupService; From 727cd820735d8fe6e239747b1992582178d8626c Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Mon, 28 Aug 2023 20:46:04 +0200 Subject: [PATCH 034/198] Light version is always used for `iconPath` (#191127) * Light version is always used for `iconPath` Fixes #188830 * Use ThemeService instead --- src/vs/platform/quickinput/browser/quickInput.ts | 2 -- .../quickinput/browser/quickInputController.ts | 6 ++++-- src/vs/platform/quickinput/browser/quickInputList.ts | 10 ++++++---- .../platform/quickinput/browser/quickInputService.ts | 6 +++--- .../quickinput/test/browser/quickinput.test.ts | 8 ++++---- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index c56674f2f78..173bbc88096 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -31,7 +31,6 @@ import { IInputBox, IKeyMods, IQuickInput, IQuickInputButton, IQuickInputHideEve import { QuickInputBox } from './quickInputBox'; import { QuickInputList, QuickInputListFocus } from './quickInputList'; import { getIconClass, renderQuickInputDescription } from './quickInputUtils'; -import { ColorScheme } from 'vs/platform/theme/common/theme'; export interface IQuickInputOptions { idPrefix: string; @@ -62,7 +61,6 @@ export interface IQuickInputStyles { readonly keybindingLabel: IKeybindingLabelStyles; readonly list: IListStyles; readonly pickerGroup: { pickerGroupBorder: string | undefined; pickerGroupForeground: string | undefined }; - readonly colorScheme: ColorScheme; } export interface IQuickInputWidgetStyles { diff --git a/src/vs/platform/quickinput/browser/quickInputController.ts b/src/vs/platform/quickinput/browser/quickInputController.ts index f42e1ff78d1..85780828ce1 100644 --- a/src/vs/platform/quickinput/browser/quickInputController.ts +++ b/src/vs/platform/quickinput/browser/quickInputController.ts @@ -21,6 +21,7 @@ import { QuickInputBox } from 'vs/platform/quickinput/browser/quickInputBox'; import { QuickInputList, QuickInputListFocus } from 'vs/platform/quickinput/browser/quickInputList'; import { QuickInputUI, Writeable, IQuickInputStyles, IQuickInputOptions, QuickPick, backButton, InputBox, Visibilities, QuickWidget } from 'vs/platform/quickinput/browser/quickInput'; import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; const $ = dom.$; @@ -50,7 +51,8 @@ export class QuickInputController extends Disposable { private previousFocusElement?: HTMLElement; - constructor(private options: IQuickInputOptions) { + constructor(private options: IQuickInputOptions, + private readonly themeService: IThemeService) { super(); this.idPrefix = options.idPrefix; this.parentElement = options.container; @@ -145,7 +147,7 @@ export class QuickInputController extends Disposable { const description1 = dom.append(container, $('.quick-input-description')); const listId = this.idPrefix + 'list'; - const list = this._register(new QuickInputList(container, listId, this.options)); + const list = this._register(new QuickInputList(container, listId, this.options, this.themeService)); inputBox.setAttribute('aria-controls', listId); this._register(list.onDidChangeFocus(() => { inputBox.setAttribute('aria-activedescendant', list.getActiveDescendant() ?? ''); diff --git a/src/vs/platform/quickinput/browser/quickInputList.ts b/src/vs/platform/quickinput/browser/quickInputList.ts index 650219bb460..e5914bfef84 100644 --- a/src/vs/platform/quickinput/browser/quickInputList.ts +++ b/src/vs/platform/quickinput/browser/quickInputList.ts @@ -34,7 +34,8 @@ import { getIconClass } from 'vs/platform/quickinput/browser/quickInputUtils'; import { IQuickPickItem, IQuickPickItemButtonEvent, IQuickPickSeparator, IQuickPickSeparatorButtonEvent, QuickPickItem } from 'vs/platform/quickinput/common/quickInput'; import { Lazy } from 'vs/base/common/lazy'; import { URI } from 'vs/base/common/uri'; -import { ColorScheme, isDark } from 'vs/platform/theme/common/theme'; +import { isDark } from 'vs/platform/theme/common/theme'; +import { IThemeService } from 'vs/platform/theme/common/themeService'; const $ = dom.$; @@ -234,7 +235,7 @@ class ListElementRenderer implements IListRenderer { // always prefer item over separator because if item is defined, it must be the main item type diff --git a/src/vs/platform/quickinput/browser/quickInputService.ts b/src/vs/platform/quickinput/browser/quickInputService.ts index f797cd31f05..c4d20832264 100644 --- a/src/vs/platform/quickinput/browser/quickInputService.ts +++ b/src/vs/platform/quickinput/browser/quickInputService.ts @@ -98,7 +98,8 @@ export class QuickInputService extends Themable implements IQuickInputService { const controller = this._register(new QuickInputController({ ...defaultOptions, ...options - })); + }, + this.themeService)); controller.layout(host.dimension, host.offset.quickPickTop); @@ -225,8 +226,7 @@ export class QuickInputService extends Themable implements IQuickInputService { pickerGroup: { pickerGroupBorder: asCssVariable(pickerGroupBorder), pickerGroupForeground: asCssVariable(pickerGroupForeground), - }, - colorScheme: this.themeService.getColorTheme().type + } }; } } diff --git a/src/vs/platform/quickinput/test/browser/quickinput.test.ts b/src/vs/platform/quickinput/test/browser/quickinput.test.ts index b50d6523c68..2ca1fb2b16e 100644 --- a/src/vs/platform/quickinput/test/browser/quickinput.test.ts +++ b/src/vs/platform/quickinput/test/browser/quickinput.test.ts @@ -15,7 +15,7 @@ import { unthemedKeybindingLabelOptions } from 'vs/base/browser/ui/keybindingLab import { unthemedProgressBarOptions } from 'vs/base/browser/ui/progressbar/progressbar'; import { QuickInputController } from 'vs/platform/quickinput/browser/quickInputController'; import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { ColorScheme } from 'vs/platform/theme/common/theme'; +import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; // Sets up an `onShow` listener to allow us to wait until the quick pick is shown (useful when triggering an `accept()` right after launching a quick pick) // kick this off before you launch the picker and then await the promise returned after you launch the picker. @@ -82,10 +82,10 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 pickerGroup: { pickerGroupBorder: undefined, pickerGroupForeground: undefined, - }, - colorScheme: ColorScheme.DARK + } } - }); + }, + new TestThemeService()); // initial layout controller.layout({ height: 20, width: 40 }, 0); From 91c9158a5c1682b4f0e985eb901e307857c13666 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Mon, 28 Aug 2023 21:17:23 +0200 Subject: [PATCH 035/198] Uses version2 of diff editor by default. --- src/vs/editor/common/config/editorConfigurationSchema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/editorConfigurationSchema.ts b/src/vs/editor/common/config/editorConfigurationSchema.ts index 0123d64e587..845adcd40ac 100644 --- a/src/vs/editor/common/config/editorConfigurationSchema.ts +++ b/src/vs/editor/common/config/editorConfigurationSchema.ts @@ -244,7 +244,7 @@ const editorConfiguration: IConfigurationNode = { }, 'diffEditor.experimental.useVersion2': { type: 'boolean', - default: false, + default: true, description: nls.localize('useVersion2', "Controls whether the diff editor uses the new or the old implementation."), tags: ['experimental'], }, From 2dc082211bb9768a1e0b4b6ff1d72ae53bd78cc5 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Mon, 28 Aug 2023 12:35:08 -0700 Subject: [PATCH 036/198] Context menu for Quick Search appearing in search view (#191509) Fixes #191485 --- .../contrib/search/browser/searchActionsTextQuickAccess.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts b/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts index 3971c1f112c..b517ae9e2b3 100644 --- a/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/searchActionsTextQuickAccess.ts @@ -6,7 +6,7 @@ import * as nls from 'vs/nls'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import * as Constants from 'vs/workbench/contrib/search/common/constants'; import { RenderableMatch } from 'vs/workbench/contrib/search/browser/searchModel'; -import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; +import { Action2, registerAction2 } from 'vs/platform/actions/common/actions'; import { category } from 'vs/workbench/contrib/search/browser/searchActionsBase'; import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { TEXT_SEARCH_QUICK_ACCESS_PREFIX } from 'vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess'; @@ -22,11 +22,6 @@ registerAction2(class TextSearchQuickAccessAction extends Action2 { original: 'Quick Text Search (Experimental)' }, category, - menu: [{ - id: MenuId.SearchContext, - group: 'search_2', - order: 1 - }], f1: true }); From 92be1f75d967ad081c15809687163124e110a486 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Mon, 28 Aug 2023 12:43:00 -0700 Subject: [PATCH 037/198] Disable image support by default This was the cause of the black rectangle when using the DOM renderer and it appears it can also have that issue with the other renderers. Fixes #191426 --- .../workbench/contrib/terminal/common/terminalConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index d92eac5fe3f..8a8803cd23f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -607,7 +607,7 @@ const terminalConfiguration: IConfigurationNode = { restricted: true, markdownDescription: localize('terminal.integrated.enableImages', "Enables image support in the terminal, this will only work when {0} is enabled. Both sixel and iTerm's inline image protocol are supported on Linux and macOS, Windows support will light up automatically when ConPTY passes through the sequences. Images will currently not be restored between window reloads/reconnects.", `\`#${TerminalSettingId.GpuAcceleration}#\``), type: 'boolean', - default: true + default: false }, } }; From db135a575a4af753e11b38f9b10540a2363ec16b Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 28 Aug 2023 12:51:04 -0700 Subject: [PATCH 038/198] cli: fix decompression loop stalling (#191512) Fixes #191501 It turns out this was a difference in inflate/deflate implementations between the extension/SDK and the CLI. The SDK uses Node's zlib bindings, while by default Rust's flate2 library uses a rust port of [miniz][1]. The 'logic' in the CLI was good, but miniz does not appear to flush decompressed data as nicely on SYNC'd boundaries as zlib does, which caused data to 'stall'. Telling the flate2 crate to use the native bindings fixed this. This could also be the cause of the flakiness occasionally seen on idle tunnel connections! [1]: https://github.com/richgel999/miniz --- cli/Cargo.lock | 12 ++++++++++++ cli/Cargo.toml | 4 ++-- cli/src/tunnels/socket_signal.rs | 24 +++++++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 34627da135b..1e75e0541fa 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -735,6 +735,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", + "libz-sys", "miniz_oxide", ] @@ -1217,6 +1218,17 @@ version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +[[package]] +name = "libz-sys" +version = "1.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "link-cplusplus" version = "1.0.9" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 50fad68a8a4..03a6f573952 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -18,8 +18,8 @@ open = "4.1.0" reqwest = { version = "0.11.18", default-features = false, features = ["json", "stream", "native-tls"] } tokio = { version = "1.28.2", features = ["full"] } tokio-util = { version = "0.7.8", features = ["compat", "codec"] } -flate2 = "1.0.26" -zip = { version = "0.6.6", default-features = false, features = ["time", "deflate"] } +flate2 = { version = "1.0.26", default-features = false, features = ["zlib"] } +zip = { version = "0.6.6", default-features = false, features = ["time", "deflate-zlib"] } regex = "1.8.3" lazy_static = "1.4.0" sysinfo = { version = "0.29.0", default-features = false } diff --git a/cli/src/tunnels/socket_signal.rs b/cli/src/tunnels/socket_signal.rs index 2a2df6607ea..69feddade61 100644 --- a/cli/src/tunnels/socket_signal.rs +++ b/cli/src/tunnels/socket_signal.rs @@ -264,8 +264,8 @@ where #[cfg(test)] mod tests { - // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; + use base64::{engine::general_purpose, Engine as _}; #[test] fn test_round_trips_compression() { @@ -287,4 +287,26 @@ mod tests { assert_eq!(decompressed, vals); } } + + const TEST_191501_BUFS: [&'static str; 3] = [ + "TMzLSsQwFIDhfSDv0NXsYs2kubQQXIgX0IUwHVyfpCdjaSYZmkjRpxdEBnf/5vufHsZmK0PbxuwhfuRS2zmVecKVBd1rEYTUqL3gCoxBY7g2RoWOg+nE7Z4H1N3dij6nhL7OOY15wWTBeN87IVkACayTijMXcGJagevkxJ3i/e4/swFiwV1Z5ss7ukP2C9bHFc5YbF0/sXkex7eW33BK7q9maI6X0woTUvIXQ7OhK7+YkgN6dn2xF/wamhTgVM8xHl8Tr2kvvv2SymYtJZT8AAAA//8=", + "YmJAgIhqpZLKglQlK6XE0pIMJR0IZaVUlJqbX5JaXAwSSkksSQQK+WUkung5BWam6TumVaWEFhQHJBuUGrg4WUY4eQV4GOTnhwVkWJiX5lRmOdoq1QIAAAD//w==", + "jHdTdCZQk23UsW3btpOObeuLbdu2bdvs2E46tm17+p+71ty5b/ect13aVbte6n8XmfmfIv9rev8BaP8BNjYWzv8s/78S/ItxsjCzNTEW/T+s2DhZaNSE5Bi41B0kFBjZ2VjYtAzlzTWUHJWtJC2dPFUclDmZPW2EFQEAGkN3Rb7/tGPiZOFoYizy/1LhZvnXu6OZEzG3F/F/duNf6v/Zk39B9naO/yAuRi5GHx8FeWUVQob/JZTEPx9uQiZmDnrGf5/pv93+KeX0b7OEzExs/9kALo7WDBz0nEz0/wxCAICJ/T+QmoH6v0V2/udCJ2Nia+Zs/i8L47/3f+H/cOMmNLS3t7YAGP6HLIM7nZubG52pnaMN3b+kJrYAO2MT4//IGvKquY+4Oly7Z01ajWRItkE1jacYu9tcSU339/OnBkYgUbBD9rHonA9pvJV7heYuoFUpRcnKi8RwoJrSkW7ePD6N3ANHPr1UW7wPu5907dLnd4hlXwziROJkDgejfKv5ztZzPgXoUaEPEsM6y752iLyMJdkKwrSo+LAiaFp4HSRvSAnMT2Ck9JHIyQNuaFslDhaLQMIP+B7AGRyZFXeqpFF8HvfFVkQHqGejNjdizFvRHkndAl8AtfEqRHfxPFAit0twsNMyaONmusi/YHvmbQhpTRnyOV0gg+tXzisWmDsLBFAutCcGRHR0Cigere6p3A7NDGmBxHAZSmK/LGHKCeyUqN9fyBIUmyCtV99ptMaQWt4KAny5Fg+nTU1gBvBq4RvHlGCF9WL+2ZxKDfB2gr2GQaUY76Tv7x79VKbxwC5GITg2q02XPy6ZNFnLryVCGskiYPFPQLAsU+LrTvbyQTk7KNUFHwzBUTP1MiKg9LCdWAs8BZx3FHYaJyvIPw4nJpUAP3rP8GPdJeb3iIJ7i8xf15F71iT47rNv+qCXaQD9NBo8PcRVqnEy3vyrPG5SO8HwSDk9PhQJe2xo4Q52soIDB3v1jYYmR8ZkuoNq3Moy6BDjR1WBCTFJEHjdSSADxzRJ2hnozSOLmzTLuKgwWnFU1aGpQ5S8Ry7ME7gVb+CwnFvVtrpofL+DXvE3CY9Fhqe0y4Sq1yLyn/vcgA7ShFG+QnTB5zaKS3Ndj6LSCxwiNivY9R9TsAXobw4Exqog7xCAjYxNIbDuo/fC1QKpFUzvxw+7Rjc8J2lJg80YveK++I5fqJVAFu0Gb4SuJAd8ernBkpyy9lbou0enEfQMOjjucNiy+rgpU4pl+ERgt/Be+8G9l0RbeUwthLZp4ARnBHAB2mcB2o1cJIbhXnMiYStLmjwI+i+NOhBvRV8nmAVslkGdsEVU6Q3hYy/cT/QRTbEF0W58bkYPCyx93ESp7/sWkTG5i9GInCwW+zw1NIRfi2zkuz7KIzOlg33b5/R60L2tjlPtcLjZYL9qGWXwgPApKkndbDq0HhRCQYTyEZ1nC4MFi9NuasFm4t4UV4/W4L0A8YwsXH2m8Rh7hl1No5oIIlAGi5Er/amKw5mAA/Hvwbzfd4TGx66MHWA9t6NAA2WPx538griN7LCqE2315o09fNbOumI6fM1CN0AJT2FheQgaG4tdPFPn6uAeDXUDT8OkTdRFNi6Av4rwo6NnyfLnLYxBNdAhHs75bAedI5egbRrWLC48JT7aKsV+VsOmLsk0TGh6ISxI3WzskVbVFr6HGLy8jee1ZiMF0wzd/B4LvlyGIMa6HD+JBsGOH6vukgqV7ywTl6P+Wo8mTZHo12d7u09Z59eyXJcZKnqY4YzEzGUrlGzvO0Rgfgsse3RMPWJSpsETWqo5zMTtzYk9HANeoA5ubNoO/jjtLyModk/iH6XLiFD1591q+nXNb3Ve2v/aHlJQQYaytpOULvnsEYGIQH9+y3eK1Rgqgs7fxD3uzpv06A/afiToieIJpbjLhy3JZBEAmtN5UgJm6SuCbqgKJ+fDsuwMp/m0fCNVqrYORcBpKTvIWFzWF/leWJntKUis0dPrWy5x7Yu2GhqJh3GN2bT8w1uIh1haSlBmhMOzV3yNUmNcjqFV+GziNt6twoPDJ+4m7TE7hP2E9mEhiYihUDjT0X2Q4k0GIqdIl6fpoFPK0zdfRfbEkP2Ulr7fzfVqCYp9iuxtZFqBafBWLNHVjYtIn9/Z6Z3mP8DBfOYrXbMXldLjKW6rHr3w/LACe+LINkxcxQ9rxxBffepkhhj8NQ7vpyXpudfYmfPMsnai+b5VI5QMcyZly26kxMo6KGGilNYyX/hLaowV4GjIEY7kHRCNmJIBNevb1ag4w98wLWMtfyPMLn18o9cFKiJk2kjZmRBFh0S0Bd7AjxiNO8YdDQ83lBGS5JrxmLG+hW2oGYQllWS2UjK3+loONmC6NpPNgUiNhDQ05s24iRJZ/bzrgBskPLGukoMu8NK8CQNKZE8zzmsCrnkU53iPeZd/UT8ox6WMMZOtDv8YyQpTmhbzXCQW9ogbfgqH447dJFZuPkT4MGfKw+0c5L6aLWqAadBU9yLftFVsi8GZOSB9Ctv9/fJZ5SmlNgt25uGvspB9y1PQGEmLQyjFiGK7kveEw4Knn9lv/9GV2YlCdeRTAUyOS56k6G4ajfxNtMHPaDqIWTM1yBem3dShwkhD0nMXit14/wHRHosy59T+nkuvxG1MbTx8GJM45rvrOmUW0nwxNNdsdqFCNPWn+GcYzIdwCNFtHmdSKNOecfZZVJnKzuGbs41wRQIkv1E1p6ITiPxv+zKWflEU76wHOPrDx4rmyw3Z6MqaP316eOcW43JwBvp9hJuMUHr0TFkvjd5KzvmUSrZfYvpPZ2humVwOsjChiFzc7aoBMt8MdXyf2LIhuhBAg8Ue3wLqlg3cEYBS2z+uzrS5bJzmzH3NGmI+M/WbHOkbqcNtSoZjwp4NI5bSpCKWs7BqrK8sfsUC+UpA08Lfc4CpcBmsTyuHncO2gLc9jPMT+SBAgiZxTDncaiM+YG19ntqYSttys+jpASZDwEWjYRN8QURClAIs0G0KKoY0jjWcc0rypYXiCsHD9+kjtnYJHuzeZw2GQ5U5j7acLM8nyuy8bSJaKZXFq8TJkQ/p4lSkKHpVQPi+dWF4jYaQFEGiPAuiLOGzOE/f8B2rePs9zps7QivUyIiM8fsbPx5mwaC7FbjdihjbM198akLx99SpXAF4fh6d/xwLppw2kFrKa0UsTa/emTuV+6l2/8WmVWLd8JJAhcE+qbMrJBrohgGdDNZIRxJOrsFCzSmu2ykTCZnZlPITlbK/hUA/+DwdtJbmzKczEWAS9ENNbxHNSbn4Nqsz0yvhUE2a/FT6tvnBbXm/X2yLQQhxuVyNCsK2TeUNifqlsCEAJAALqqNI/NX+owJEAk+KehT/fpCsXGTsT3kFsUiPNWAkOEuHviK3Nzpu53edKRZgInWOWhGnd8aD6k7kio0tLT8i/PkxVrdZftlNrqPZfiEXkqX3hM526HzLGVzlr+CvTBKxsU8ROxHvBGWzJk4Tt0uDhZessy5BDFVx2xiYxMTXfQyv8NF0Op3CKCFvH1KbE2Z2TGCvpOEH7LKVK5TyTVSP+yah8TkpL1cHorIRxz2a5cMNMZGgdooqszII7PJuT3Ii0GpCCXe3v5mzysGhVKBulynWOeMrlJ4jKA4xzAXIg7ReLCGOntAOvU7qD+5UBufLWxx/3cqhuMcZDnR2dUjJuFG5LuFiwnvboFRMjVTvVJkcNdUc7b+0auIQWC1E3hTQx422OCMuGvayP3WMCGe8IClwSw4f1uA5LkoDYZbVQo1SUzETYNPQUK5BTJy7YRq4ln9vLvDHDImNd3TiWnsL7Zp9qWVSSTfSVSyZTT4fJqKIZ/Kcy7IkXFyv0Frw64R7y0vM+tAu+0kebn9y+DlN2xmi7nmf81iI1xffS5+ehMzQJTIa8SjVc8kCf14eOLiR7TgCnHcJieDFQI9r9K9co2G0hpitdihrbb56XvossnHl8Fu4JRLBPgKXsAQyX3v3BUHuw42rmeQXz74oZzmEIG13oteilg9HOUyoR5NHE94cYtIqP80qheAh9uQA9e3+TSmiLy6dsU625mYOYcPixVm9ZYuiOtLWQ3tT8j2T111qqjqNu6yUSxlIAh0+ANUEhEh9Uoj9v89/WqlGXNWPDmKfRtn+yFVoyggl8PjW0GB7qfreaEuoqouCGoV+lWma6sNZyKYQGIn51nzIyO1uUlRQZq5j8aTQgcXlNYi5rXALJ2Kj8nEbJT8OqXEt0fbWPKaLQZch23yR9RLyaXMpTIzzRBkoFY5g0MfTWFLbcMynydkZITcfLTSDeD/fxSqUzWmgjk9j1aQ07KUBInTRErSbfEhgCVikEENWXpOubo3XV4YBv9CJYSuXnSv0d3jLQdHefqwT7+Gyqy0ZJYicFYw3ma+acapIZw2r4qg4BNKbSbkMKOuWidsr1dxjS9bjSYoNH/VDBdbgXpXTpPJosDIjwMHsV48OfhwZjvnAC0r2yJ3+NPhBP4g/GU14mpdefzvR08OElSHLpZidGsL5GGtpzcohM5sQ48TMsOs6Cy3vvgKR1oanGjGa8dRN+UaaAWm1dieSOjvXzIIVPp3zoKEgVu9zlP2W5NtNSVDfceVy/cA2IFjOlKa5EiLEEA57fuxvGmOvxCB+ZROvg6KOi6EbxLMylQEbvzctlbmEJ0S32x1usYisIWFfCLX/SEETVFuAxZJej9AcvkolOkSLNlohZdKzOYeRMfQM/RMT4JwSfFqHgIq4XeYPtTzMO2ZkTdOjdrrWL0ZMFosuXiKD/9qKKbo1FjqjwiT5a4uIaPdU95J52kiPoS7adOxUFiypbB9SrLFTABESJrPr0qMSVCi9cMME+Vt2Qq9gYFIvXoDRAR0SP04c/2A1r/tvxBu6JRGDB9cwYWOE1g8W+W/vju6WwPvifEO4AQ+KD3bGEhffrUWM1SnsAZBbJOgep/M1iU/HX4uNGb6Dmz+0PQdJAo7TkA2D+Wigyb9CQUfK16vwLvIIvMnylTcOOIAUtbiy2/lcdbmnQcFMt7ZZLQxBemf8S5L8jkyl1WLZyVNGDm5qf/72TQLs6KK4ljCJqMt0F6p8tidu/52WK95lYzKiZy6nlOSKadsCEWX5+eMzpJu8ZjYF5Qf1K54q5wO/T4Y+QYoWlUlXB6MoL0adwXmSs5T7Mht+6k8BO7T5I+3iI54WdYwixTnvlI/TNQSjwGJdxqJOmInihyKgkCx1lUyn/fx6jKZ+1MHPZwvfOg5V9TuCf+aXvjVhcgJHJBilS8ytrZh8FQh23yNbEIMoE6lYyWuYdSKv6831VdffGAP6gvaD3d9aUBJRkHquA1iqVB/ZG+bcJLpeMFJagd95AvGXUIuYwFKFmBtlKkjOuiEbKNKxv+SJ/NQCIGRBxVkm6oqcabuFnskNEhB4FnYnplnCIUZEfsuLirqsm6sSQZ2ZITdUAkmQ308cj5051V8FwogjNmZJyYuNNsOxYzumG33B7Z5k6QHkr2HC4aky5ZHP2bW8quZNaSXEcL5YGfZeTPTOVCv3TA+e4NLZeVocXTUYNWe7pyYjaf6EUeHdXOAMpZk9084KP8PBCwnlNfiZG2fXD+36bvn8sOVcsLvwAT01LEmVgo2E0geZqDPd8OIHJxDVB7VXNeFYIKjKgOjT63Bq49GLdBmwOlTKDljg00eYqLTQO66FPzSTWMc2EMGCae7sVr/OluTg/T4NKFt39gySNurVvPtlXZfqCo3GfCiyTV6iZWeuVMh69PrrozqgCX0mHJ+OyzMtQrTbqUB4BvHZe9Bfo/uyBDmRDWV0vTCz1mz0t+DTOjRkjEiAOFOKSQ5w/L3RgIwmuEgW3kqaQqtwAFIfWb9PxNuLvTLGMttZ3yO5P3aYl9G6jCSrrcr+3m0ICKOTBu8lH/lonRkZOq/08lpP5VtCEak6I+aSIT9tP9LJIZACn/IUe7qE88kjETKmnZT6F1D/1p58pEA0NI4g5CtdHlSXmg0s+zhAKS7tYpvNx96EPw5cCc5+VneGb0RDNvLaa+cEF4M/JuU0PcA9u9gu+PC+byS52tGqNA8yuH7El6JwFI8dXUvX07iAkC2VOvtt4kg0aeiHDyPHJpvvN4TaAH9Bz+WT5FDWNTAz4LC79GO6pQb9j5iojBlt+UUHvr8nfZN6AKa57RMsFTt9m0t0eBVUqR5fgpE/k6+57U9FtAQPZ5ufj66n0Ys1Chyr93K5jhX3GM64JjdryhghfffO150Q+hYrX3a5/fo2ULWBM27UoViPGVCFtmd0Yw1V5F+l8j58Mck1yUYxpU6tg+o1tara6THtW91V2dqC0+ha42qUVZhScMys1ygeqrpwVTvfhsaVH3/e0xXB7cO4UYkBg1ivB9O+90jwFfg1noBWOg7JpyGvPzYuLPz1CzNtVCqtRpqhMbCu4e2xQ++w8gJGD87TjODSjvgsXoDOs/Fs2qzhSatxvKrnW6pmKqwo9j4B12XZ4Sc+4oE2DIquGY8iyYrp9oBkSCQ8kOIkYVD74yj5C+Y/+JkFNVPwwBvarswkuyZUp8gjHCBLFkf0l+yBDWvJ/jZBXyUFSCGDIrpl1USocwndJFH5zst9/ZyaiKGKEO2nEBAuOCo1XTAyPLIjonN2pH7c01ySgFXymnEV0K0UGq78eDfUtxpmcGLtK+75NVraVGD2wNVNrpWJl1al+s+CM4OvabLcM6VnweXcGciDFRmghhWVoE4EqnhFUuFxCB3umtoyn8lKuEy1fmrRsweDOMtUNd0qA6IctHwIM0AOX2Sx0KxqjEhpp+YkfStkyLrzC33yJbUqRbgkDGq1fKfJDAdenpfQOVj6VMCsB208bbzJUcGOWzZtvfnETOnRLxb4LddrcPuP91CawvOVuAphNrIEUsiRon1SrCuL8GVF75tbSHcskqjIVLfycIZlvVjlywu9gBptiORxw/e1CZ7bDeKlTTIK67KQqosSEs1fnc/X0aAxlkqaOEZQdefKhrABuZFa/KTPRhQsFSncg6wI+niscy0rjfkkvg5fe4c17WCpa0eXot7t+4ot9O5+v0H/buYYniE4MzfrsDnJhqu1tLt1z0dNQ60Qz/8RxR7461d9KxJaNTelFLXDQwDHcTCBSk+0BrJVKT9Ls0bHgxr0zDoaDnbnlXjuu9+I+TH6sZYee1kDBqfPV/RKaXBx6yCFxEBosyCqvwmiuHUzItjvCMSpgREhM861FtvcyaGbN1+nFgM0NlPJQdpqz7bpEJcVw8HFp0yAAT61uYy8m51btG5zFKE74t+qEpjkQPOxPzxh52MDHVgMT0vIQcdA2GGXmjLInOlKHy44blBXKhSsvnWk6goe3xaY/vatI9iOJP0zdmqYuV/Z82spbMuwMwDVEEqrn/KPXqWl0G9AIAPPSA/DO5U9NZAn8nW5CcnB359CkSxVmBXbPBph/GvVrjZEiohjaAfRzdYgSBArwPcIhmfsE3ankfWrXOiw0qJgH4UvOuQphVkNCTIDl405MQMo+6Usm6YMkKx93V+wFSt0l6zoNYeELrp5hNwWNc35EVD0YJegiTIgVDqJykV3YM5po2UCDF4a1Ijhgu+mWL/+B3K8OcvmsGG8X/tKBCNPK/0jJT6PKfks/NEJDkcRcfm1ZDp9AFzldq53UZoT4o4zhRSpLA+f6VTIJx4/t78vpyZKMEJmc8RbIp/swFrbSGInwW4NCrovIK+oS5Z3zXeNbGSpuf2oWYAtpQvttaM2LNl4svcEwxvYor7JMy46l1f2SB0Q0PXLIehirHvMLhbfdWLQw0QB7Gq2O0khxvT1LjZ+H+euX7uZmkY9IvXdW0pnDhaNmZKT6nKj9K1bcLT3520W7lrdOzlEMHxtoSMMd9u2LtEkdtO0KIyfVvkXReY+ilkTyBUmcRCEWl27pABXdcl9jZn6A/16Ze1Lv9SFRncN42vpbOS3xkIBPtFwaDftP6IZLtchcxmj3xkeJFH8fFKg5f06HvCjPbxR3US46FTJqo49yM0H1L8wOjSC8wYHb4Mo6Zhh4i48snY9IOVfrIGqFfTsTQ5kxIctBPqGnMO7dl+iu4TUqeHkDk2IkmZSNjB7hp0mmLHKcTAB49JQDsZdlPlcOeADP/r7q/I5vXE8ZHzXqFmxW9v90+JMckU0V0AIrcJK9IQWl4LQR+dRuKRxJwDpy4wa4ymhqnBdjDMqQ/cetUExuVkzntiCPyOz6dMpAx9ZeidxQ02hYjPVqgFg8sCl1lTHTulvk7Nj698usBJMG+IKJorZp7+a97Tr226dW1h++Ic3ERIIDuFrJVY0UvO/vrTZrxZbzT2Ki+UvjN5Ins+P6gU7XLKlAlh4h3u54VXMJO6MqqpSFKXQlRY2fOOn/m5YDfOCvjmhsmrp63Wz9s+kowNsciO+DZa5Mce5qH9/ysvEHv7Sgb3AIZ4+zl1R9px1bU2HI/tcieQUvHkNG0N43uBelEbsrZTfVDAsk7KashZp+QG9k91BWuxlN00Hmaqd3foNx2EwoBe14MbFyJKr0PLJvFrMBQamhlWX31hknK3y9m7F3cIopvO2kIngxuVgZ/c3XOMnJysZcmgeVvouinM2GCcJF5k54InnSO0JJ0g4taICxSdD1NbXw4aVfuPXY2loCOKwXAsHW+vRvIu5yBYsAXeOX1J7LwWwVHOTLjQDRyIwgAsot1J4dr3tRO1u3s72SospfgKrMJdMYtrSJ6zvRQTEDXZcyk3fqtElG55syIjePTyPVPDGCGHVvaqOCWvYDXnsFAy9L3gVg8HaLMerTRuSzj6HjRmyZNheBBZkDOTRmc6yaJVhK/+NCpXgPsW3xyAX6ZGQ44NOAyn9U49Jz5VIUpEfXTK/hDaJeMgl/HmLcfxbBara5U+J5xi9IvwTcMMzxxN/sm/BjLc+34gP33ChIncbfHleQbbQvS6JMkySTA2PCbI/vwYonIZnymVtA3c4fC5zso+ZgTyvnxZkeJdDRPjTUtP6DFIAxMbIotg2e93CXfUp4ciADmTWa4IbuP3n602bqsqzTldZAt7UzolvY0gnTcmZWJC8dCoZhebkdcf9hd+jW/HdVo/YM6s39d1Mqm7PnG2dsXFSCn+yg1redbnDTPpUVi1+T1xd6dGeM7GddroA/qyNLl9dvdvCUGQvRL7BIFQFUZYXRdx27OAStt+iqORvuibZWfLufrRJVM6AoyJNpRo4rALSdtAcfW8d4HJGPEaP1cxl6ErnQz+yDbv+zRMTFCJiuPTJRDXD+ir8hz+eChUN323YpgVJ0Qjl9oqEj9H3SKORfnFaq0337C3oyz0eQ5PedG/d78nJzRP+BfQIOFMDzPSJ40yg+MAgX0P6ZPOiBIW7c/i2j6TQhVyeEUzsjRMYMMiGQl/lgTz9D6Kc/WP4tzbzhRb0Icoy5+sZRiap1rQFjaOVzGUEOXgMoME9voaumyWcTskYTxGdil9CvKBKsHCFx8iZ63V1xcmT2JnOVuYEAqOwD6bSc6KhJznv+nSyG7HNY+ycCXP1NBoG5Z8QgXEcJxUMl0SDUaMAqM4K/NL+ZiQHDbDL38U9eBa9zYaG7xronBtZ7ieC2yMOcMfz4tSvATwPeH+qlTOJQjBtFEzHkFV84bUdVYLaMj8/oM+rVU/4hZCpXR42AXjhfEZBT2M4YZv9ciCjNAo63zbfTv2zt7A6ZYVUkRFW3mRQw0EP7bmK8w4BcVzhy2U0zaJqlBAbc1i/4A+0lmSnyKBISJRF4lrGz1dIsCpZ5AeuDopJNc59Rb7viBjmnA5rBqdrxPhNnReYbJd2k3g7YPAV21Hx4wf7oUsVn8Mu6dgmChDCc1IEc9jxSnHYCWqlCA7YBeUtXTXIJf2qe7knGliksYKnYfX9RnXdeDoIbmKWGsV2mnK+oJPzOlF46TC391bf9GBe8T2rvcXJINCfZBmS60iO+5Yo2NNJQi+Qc9SebaaygxTZOj6rIbNwzdhDEUYCG8zfS9KmEhZKfcz5+9oCIG6mM8oh7q79yxzDIzdpaotBKCgJ9M8jtC/Ee5ZI8adPdXMkB1EEzaGWZBuBvzecpPmTyhzpKBy8FB0kKhEOjY0/utP7JAJKpId0xWuDDsFlSsbCqPgb4wbUqID7Qxu6FUJ1QGCxGYA+u/NXFQesgGrYlWKdm0zY62gtlUv89zV1PwQwB4TNtP16MrfZAuYhqgR2xJ7ON7tWJ49lVyjB5NbzlCGelLKJIkoicwMz1CSQ8b9SO2qk+WMWUPnXqCsHBSU7ews5rZ8ccw539tfEBj9UNPUqW30tjb9BIc5q0ypPa15S8ucZOGEpSGyRLaf8SdSxw1JDsq0vYF04PoWvvYyAIAVNl6ACzWEnCPSzVAb2orLKO2McQpRAY4I762BRDhBt0R6a1Qm9Hx9g0gUfQE6iXBniPe81OUTKzGHNKxHzV2sP3HgVlBmB2M3N2tJTzb65XnRGKLGOgMe2/eVvLj54lK4MRe5vTJG1QvZUKbxnK0YdMNE/N/eTPwJ3tB7tMyVVVDEUQpzKNtWqrbKvtQcxG1Dy42DjnsCW+DNlXdgmIKcG8ZpJT9vTihoR2UAK1ZG1WPhVF2oNNvQGU3z3hIQ8VNmdu0EMJlEu6v4iTlLYi3E68RpLs8Eq1d6csi6nKrJRssSwsm8ApR/yO/p9c7dYj4EsfcwhxzsfgLdpu8SKZUUgHkSs+KWA2F3fHUawrHUZvl4xdkDqC/S4vi8CweW7ed/VvuriZXHgljCahrwhe2YRn0rZl3Kvsc3wz2L8XaRhusY1lT5Xy8rqsCiKFcuevI7DUCV2/c3uuhY08+5+qTihQwGlrJTQo8iTNr39o6lcoalqyKYeXWoQEKpUQP/SvTT5qhq+7NdJoB+q9JkU+q0aEQwqBOF+rdmRUeYEMWXmPiJ7NndcQGuAJg+M5pnbB25DUv2zP2Xqj/PjYypAJMMavI7YgoIlZ6VZ/L1yqU+PlABLp7+A93JgpG0hv221lEPIWY4+RNr3yyhPnCxtGA8obgUDu/6FIHqq+hxm+GfZx2DI2TQjgQs5yJiUyIVoXbmjjoBX0axEn1x3xsa7YlGVeFw1jeqFbgdIFN+KInG4kpJVd07c4BLJiITZFodHExoFD65tsX1SLXpZgdoljKwDo2DkacLCLiaV8PShqJEjo58uXdCu676mtSePbGyW0KZigAPGEpUEZ6zc1l9cZXjeDi2aLJpl6sphMR/B5aiIz6J7Afj3feUuq5qxxFHQC8jR1C1hPV7ZxF7Sub+U5iB+ynvUkt4iJd7kxJDARVbZPBbUSb9/ny0nBbzZmkRE6oi+0ocWxaH4ZnVrsL/NgnFPwKuG2IwbNCHls26kUeON7qS/+j0PLAXzBghwiRgBku1clT/tM30AS1mvJ6cKDjjLPMei7GwGHaJFfQqEjjikb7ktX5O1jVMlZTrNGliwOK1fTh3jE9b5K9AppT5IFuPxhbJ97+HMazBEPtMA9aZBIKXNFIvdPPCs0DHt05HzygjrejibsBA/SS2F+gSlANRlkrJinMIpt/gdlvUbjaxFrMupGmVCoMDfRDrxO053FTh8nto2pA2ActBghuqLM8p91U5FtVhXU+FI8whYX5WdWMmWc2E2wGzFz1aCKYJIC/qr4xzN305xQLxAVb2n0BQedGI+j38cc0ECk1NxJ2isVKvmhk5RyzSc6EPzB1884xko7roUM7NOu0FiPw+Zu4R8OGoHRYqsigkTRxlmL19aGEbBbdK9TmGBvwCd307SHj2GojSWN7DL9olp1+VMMYQ9UG8DTX47r23qkXZ4z3ctQl86rRjpzdj+70XvZb+h0FzgnyJmYSHxIIn2FWNYmvwPjyiBUgHYP5RoHhSJoeI6W+nkFnHijreTncsonIU5FKlqHQFGzzdc8s9U5sfrMFtR1SUYFYWj3C8KP0oQwiXZcn3AcqPkTqVU0o5kRZ2+QS+fJP1ozNeh6hKJSpUVSb2LZ9329cfBOPAJ7u8zYUqJZ8CIzIa26Qy5ADf5bco2Z18IcLHAulDYBXxaBCm2DXpryNEQMYWmMTHA0mVpIFVkmU5dfnNQykdZiAXU1l+Fw6kIjrMJ9AgF0xWiaZnOyTehWtuxU47hvUm8B2A9ociq2x5aFOxazc3YG5IB7IZmXercFhEWIMzMw63jvREmRjCT5ou+MIjmbi1na8d0SaLUudX5pUouPbc+4stjuNveU6cNACO0s+nbAlVyZyCeRMAPk5C+11kHcwSNd8IZugXSih5eJ4xPoIW0knz0365CjhNUfz9+31qYzK0lZNMUCuf2K0vrUBB/i3T3gdXMGSeldKp3Lx+tz/bpKXTHtUzzsvdS9Gs+uMIZ1XK6AxFyeCxOJ+cU9XN1fBnLPe2JYUlJUmCu4tiwsprlamaRzZQNWlUxombEZeKC7q3mwHcZM5wU0ICwEnLfTxW0VL9N10+batqOKxQnIspanPsw1ez2cuwr/hQSPXqoP2gIkFZnmAqUKUX8GZ5ib+C60pulz4Uxz/QvZW7V2SAAGcUwS30VsW6U2Ld2v5UbOfEQCxPdOHJZw75sKgEdyVdN1FDl4JC6s8IUclP+LD6R/CXIEDhbSWuXdTsAinSZLlMH1LzCXp6Cqvih/NReD6FJezE4Hi0sUGxti+4YngNBTWhUOblVY4+ioJs/kpVyXoAksKXh+Fe1j1PG2gbHkCQQWWCDqufQCEypj+dCoj37UreY26CogoUkVCnNUXQ5jZNFOPeXjh336gUEGzTt9qLgRwsxEJpQKH+aCWZALuJHtCVlK1WQMM6eM15EjMtRabejRb7eD3Us4WqESLYxpZ5KCobtmQDzV/4vOlvq0BSClPNORXWKygxQ2J9casayyd9DxvL77P41vt3k3fsT5PB1d6WR+6JZWwYJGZTdxyDyiFJDCKV9TuCeGkZQ26g1V0sV/H5a1xciwxOCNt7GgQOajs3aR4wpXxg4GbU0nOR0c9Ii/Sn27VMt4BqnAj5W4fx8q4ecJlPHlG3tSjqKSUsP0rlyg7JRFXcxCUGv7QMYc2K9WLvLEHbBOcM/ZD87o+UaQ3CvTwOkQTDq8hUeOBRxcerQV5Xi6Y+Hh6Vg4aeMpoGdUV7xXbw5oVh/mkSLP70aWsGQ3UbqZLFHrxQzLeDFkYJX6q069Lp/1X+lGTY+5ykXDRtK1n+GarP5tNWi4nd81eFXdracJWwcYk2GA6MbdjMnoaTrfSHXO3EXgrlq6ko5DABSrMg+9kF88aW5LAVOxGADYFS8bniGvdKVXnEhhQDJVCYKqqWKYGpAek5BGeVRWSbwLCKdQ5BcBnn+oEsmp46uK3k8KO72Pn+1hPMbgE6xWxVYPqAe7HVPPjNRiQS6cQGOxU1gdlAuEJ4V7ip4o+TgDM2/M4bthC6c4SBMQaMfRZfL5ko/uf3U2MXch54RJ2/LQRAy3AHiOI6enjY+L88VIvjU+hnmwro8yEflSD4tEMeFIkrxEW19Gycl1BDXpDVbs9nrU5MMIGx6QxCFw8FibHOtcRcI71o8s+OvDCQFsw7ZVMslGVDaprGZZmJ2j4uTgxrn15ihGv020yixBNktFCYgTyPlxA1f36ciarunxld8CPUVUPV/D/XFX5s/Neg2cdPqmSlO/fpnXxz4UJnIlB6hSl82wNGKJud1KoVyDHmmjI+EKBSUO7kNuvrQ/fY3duE75BX/HUAeUiLFKBZ1O2/mThw8t0Wq782ApG12/Jvza+94ENybWDDpLLmTddfEP7cYjFtZZONpGuxNkP8FAAD//w==" + ]; + + // Test that fixes #191501. Ensures compressed data can be streamed out correctly. + #[test] + fn test_flatestream_decodes_191501() { + let mut dec = ClientMessageDecoder::new_compressed(); + let mut len = 0; + for b in TEST_191501_BUFS { + let b = general_purpose::STANDARD + .decode(b) + .expect("expected no decode error"); + let s = dec.decode(&b).expect("expected no decompress error"); + len += s.len(); + } + + assert_eq!(len, 265 + 101 + 10370); + } } From 87fd7b79d9fa8eb8bce41dbb74617c20074aca3f Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Mon, 28 Aug 2023 13:02:11 -0700 Subject: [PATCH 039/198] Update workspace trust dialog for ai generated workspaces (#191474) * Update workspace trust options for ai generated workspaces * Make this.productService.aiGeneratedWorkspaceTrust optional --- src/vs/base/common/product.ts | 9 ++++ .../browser/workspace.contribution.ts | 53 ++++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index 47b2de558c4..ea129e9298a 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -186,6 +186,7 @@ export interface IProductConfiguration { readonly profileTemplatesUrl?: string; readonly commonlyUsedSettings?: string[]; + readonly aiGeneratedWorkspaceTrust?: IAiGeneratedWorkspaceTrust; } export interface ITunnelApplicationConfig { @@ -279,3 +280,11 @@ export interface ISurveyData { editCount: number; userProbability: number; } + +export interface IAiGeneratedWorkspaceTrust { + readonly title: string; + readonly checkboxText: string; + readonly trustOption: string; + readonly dontTrustOption: string; + readonly startupTrustRequestLearnMore: string; +} diff --git a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts index 8bc95f4f591..a488d01724c 100644 --- a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts +++ b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts @@ -47,6 +47,9 @@ import { isWeb } from 'vs/base/common/platform'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { securityConfigurationNodeBase } from 'vs/workbench/common/configuration'; import { basename, dirname as uriDirname } from 'vs/base/common/resources'; +import { URI } from 'vs/base/common/uri'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { IFileService } from 'vs/platform/files/common/files'; const BANNER_RESTRICTED_MODE = 'workbench.banner.restrictedMode'; const STARTUP_PROMPT_SHOWN_KEY = 'workspace.trust.startupPrompt.shown'; @@ -237,6 +240,8 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon @IHostService private readonly hostService: IHostService, @IProductService private readonly productService: IProductService, @IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService, + @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IFileService private readonly fileService: IFileService, ) { super(); @@ -303,10 +308,26 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon this.updateWorkbenchIndicators(trusted); })); - this._register(this.workspaceTrustRequestService.onDidInitiateWorkspaceTrustRequestOnStartup(() => { - const title = this.useWorkspaceLanguage ? + this._register(this.workspaceTrustRequestService.onDidInitiateWorkspaceTrustRequestOnStartup(async () => { + + let titleString: string | undefined; + let checkboxString: string | undefined; + let learnMoreString: string | undefined; + let trustOption: string | undefined; + let dontTrustOption: string | undefined; + if (await this.isAiGeneratedWorkspace() && this.productService.aiGeneratedWorkspaceTrust) { + titleString = this.productService.aiGeneratedWorkspaceTrust.title; + checkboxString = this.productService.aiGeneratedWorkspaceTrust.checkboxText; + learnMoreString = this.productService.aiGeneratedWorkspaceTrust.startupTrustRequestLearnMore; + trustOption = this.productService.aiGeneratedWorkspaceTrust.startupTrustRequestLearnMore; + dontTrustOption = this.productService.aiGeneratedWorkspaceTrust.dontTrustOption; + } else { + console.warn('AI generated workspace trust dialog contents not available.'); + } + + const title = titleString ?? (this.useWorkspaceLanguage ? localize('workspaceTrust', "Do you trust the authors of the files in this workspace?") : - localize('folderTrust', "Do you trust the authors of the files in this folder?"); + localize('folderTrust', "Do you trust the authors of the files in this folder?")); let checkboxText: string | undefined; const workspaceIdentifier = toWorkspaceIdentifier(this.workspaceContextService.getWorkspace()); @@ -314,19 +335,19 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon const isEmptyWindow = isEmptyWorkspaceIdentifier(workspaceIdentifier); if (this.workspaceTrustManagementService.canSetParentFolderTrust()) { const name = basename(uriDirname((workspaceIdentifier as ISingleFolderWorkspaceIdentifier).uri)); - checkboxText = localize('checkboxString', "Trust the authors of all files in the parent folder '{0}'", name); + checkboxText = checkboxString ?? localize('checkboxString', "Trust the authors of all files in the parent folder '{0}'", name); } // Show Workspace Trust Start Dialog this.doShowModal( title, - { label: localize({ key: 'trustOption', comment: ['&& denotes a mnemonic'] }, "&&Yes, I trust the authors"), sublabel: isSingleFolderWorkspace ? localize('trustFolderOptionDescription', "Trust folder and enable all features") : localize('trustWorkspaceOptionDescription', "Trust workspace and enable all features") }, - { label: localize({ key: 'dontTrustOption', comment: ['&& denotes a mnemonic'] }, "&&No, I don't trust the authors"), sublabel: isSingleFolderWorkspace ? localize('dontTrustFolderOptionDescription', "Browse folder in restricted mode") : localize('dontTrustWorkspaceOptionDescription', "Browse workspace in restricted mode") }, + { label: trustOption ?? localize({ key: 'trustOption', comment: ['&& denotes a mnemonic'] }, "&&Yes, I trust the authors"), sublabel: isSingleFolderWorkspace ? localize('trustFolderOptionDescription', "Trust folder and enable all features") : localize('trustWorkspaceOptionDescription', "Trust workspace and enable all features") }, + { label: dontTrustOption ?? localize({ key: 'dontTrustOption', comment: ['&& denotes a mnemonic'] }, "&&No, I don't trust the authors"), sublabel: isSingleFolderWorkspace ? localize('dontTrustFolderOptionDescription', "Browse folder in restricted mode") : localize('dontTrustWorkspaceOptionDescription', "Browse workspace in restricted mode") }, [ !isSingleFolderWorkspace ? localize('workspaceStartupTrustDetails', "{0} provides features that may automatically execute files in this workspace.", this.productService.nameShort) : localize('folderStartupTrustDetails', "{0} provides features that may automatically execute files in this folder.", this.productService.nameShort), - localize('startupTrustRequestLearnMore', "If you don't trust the authors of these files, we recommend to continue in restricted mode as the files may be malicious. See [our docs](https://aka.ms/vscode-workspace-trust) to learn more."), + learnMoreString ?? localize('startupTrustRequestLearnMore', "If you don't trust the authors of these files, we recommend to continue in restricted mode as the files may be malicious. See [our docs](https://aka.ms/vscode-workspace-trust) to learn more."), !isEmptyWindow ? `\`${this.labelService.getWorkspaceLabel(workspaceIdentifier, { verbose: Verbosity.LONG })}\`` : '', ], @@ -436,6 +457,24 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon return !isSingleFolderWorkspaceIdentifier(toWorkspaceIdentifier(this.workspaceContextService.getWorkspace())); } + private async isAiGeneratedWorkspace(): Promise { + const aiGeneratedWorkspaces = URI.joinPath(this.environmentService.workspaceStorageHome, 'aiGeneratedWorkspaces.json'); + return await this.fileService.exists(aiGeneratedWorkspaces).then(async result => { + if (result) { + try { + const content = await this.fileService.readFile(aiGeneratedWorkspaces); + const workspaces = JSON.parse(content.value.toString()) as string[]; + if (workspaces.indexOf(this.workspaceContextService.getWorkspace().folders[0].uri.toString()) > -1) { + return true; + } + } catch (e) { + // Ignore errors when resolving file contents + } + } + return false; + }); + } + //#endregion //#region Banner From c70624f23b3b88f54e236da0c893624a83ec1d73 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 13:10:05 -0700 Subject: [PATCH 040/198] add go to symbol placeholder for accessible view --- src/vs/workbench/contrib/accessibility/browser/accessibleView.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 2c7b4780c06..42e95d10c93 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -583,6 +583,7 @@ class AccessibleViewSymbolQuickPick { } show(provider: IAccessibleContentProvider): void { const quickPick = this._quickInputService.createQuickPick(); + quickPick.placeholder = localize('accessibleViewSymbolQuickPickPlaceholder', "Type to search symbols"); quickPick.title = localize('accessibleViewSymbolQuickPickTitle', "Go to Symbol Accessible View"); const picks = []; const symbols = this._accessibleView.getSymbols(); From 6dd57c91d05a84dd430ddf177fca0f8915e37eaf Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 13:16:06 -0700 Subject: [PATCH 041/198] change none description --- .../workbench/contrib/terminal/common/terminalConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index b997c5e3c72..1e097672b6b 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -618,7 +618,7 @@ const terminalConfiguration: IConfigurationNode = { localize('terminal.integrated.focusAfterRun.auto', "Set to `terminal` when in screen reader optimized mode and `none` otherwise."), localize('terminal.integrated.focusAfterRun.terminal', "Always focus the terminal."), localize('terminal.integrated.focusAfterRun.accessible-buffer', "Always focus the accessible buffer."), - localize('terminal.integrated.focusAfterRun.none', "Keep the focus in the editor."), + localize('terminal.integrated.focusAfterRun.none', "Do nothing."), ] } } From 8d43226a4a92db3e78e90642a4a03919458a8bf4 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Mon, 28 Aug 2023 13:20:51 -0700 Subject: [PATCH 042/198] add requestFocus --- src/vs/workbench/contrib/terminal/browser/terminal.ts | 1 + .../workbench/contrib/terminal/browser/terminalActions.ts | 7 +++---- .../browser/terminal.accessibility.contribution.ts | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 28b600107aa..bba8941c31b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -40,6 +40,7 @@ export const ITerminalInstanceService = createDecorator Date: Mon, 28 Aug 2023 13:35:46 -0700 Subject: [PATCH 043/198] fix #188329 --- .../browser/terminal.accessibility.contribution.ts | 4 ++-- .../browser/terminalAccessibleBuffer.ts | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 7fd8369f2ea..f404c684fbd 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -116,8 +116,8 @@ registerTerminalAction({ precondition: ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated), keybinding: [ { - primary: KeyMod.Shift | KeyCode.Tab, - secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow, KeyMod.Alt | KeyCode.F2], + primary: KeyMod.Alt | KeyCode.F2, + secondary: [KeyMod.CtrlCmd | KeyCode.UpArrow], weight: KeybindingWeight.WorkbenchContrib, when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, TerminalContextKeys.focus, ContextKeyExpr.or(terminalTabFocusModeContextKey, TerminalContextKeys.accessibleBufferFocus.negate())) } diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts index 41992fae298..8e6c44210bb 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleBuffer.ts @@ -62,18 +62,6 @@ export class AccessibleBufferWidget extends TerminalAccessibleWidget { this.element.ariaRoleDescription = localize('terminal.integrated.accessibleBuffer', 'Terminal buffer'); _instance.onDidRequestFocus(() => this.hide(true)); this.updateEditor(); - this.add(this.editorWidget.onDidFocusEditorText(async () => { - if (this.element.classList.contains(ClassName.Active)) { - // the user has focused the editor via mouse or - // Go to Command was run so we've already updated the editor - return; - } - // if the editor is focused via tab, we need to update the model - // and show it - this.registerListeners(); - await this.updateEditor(); - this.element.classList.add(ClassName.Active); - })); // xterm's initial layout call has already happened this.layout(); } From fd4d801227201d7b288b6f2547fd6f607c644daa Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 28 Aug 2023 23:31:54 +0200 Subject: [PATCH 044/198] [css/json/html] update dependencies (#191522) --- extensions/css-language-features/package.json | 2 +- .../css-language-features/server/package.json | 6 +- .../css-language-features/server/yarn.lock | 56 +-- extensions/css-language-features/yarn.lock | 38 +- .../html-language-features/package.json | 4 +- .../server/package.json | 8 +- .../html-language-features/server/yarn.lock | 66 +-- extensions/html-language-features/yarn.lock | 414 +++++++++++++----- .../json-language-features/package.json | 4 +- .../server/package.json | 6 +- .../json-language-features/server/yarn.lock | 61 ++- extensions/json-language-features/yarn.lock | 414 +++++++++++++----- 12 files changed, 715 insertions(+), 364 deletions(-) diff --git a/extensions/css-language-features/package.json b/extensions/css-language-features/package.json index b267163da39..e2fed901bce 100644 --- a/extensions/css-language-features/package.json +++ b/extensions/css-language-features/package.json @@ -994,7 +994,7 @@ ] }, "dependencies": { - "vscode-languageclient": "^8.2.0-next.1", + "vscode-languageclient": "^8.2.0-next.3", "vscode-uri": "^3.0.7" }, "devDependencies": { diff --git a/extensions/css-language-features/server/package.json b/extensions/css-language-features/server/package.json index bdb66297271..874ce1e8202 100644 --- a/extensions/css-language-features/server/package.json +++ b/extensions/css-language-features/server/package.json @@ -10,9 +10,9 @@ "main": "./out/node/cssServerMain", "browser": "./dist/browser/cssServerMain", "dependencies": { - "@vscode/l10n": "^0.0.14", - "vscode-css-languageservice": "^6.2.6", - "vscode-languageserver": "^8.2.0-next.1", + "@vscode/l10n": "^0.0.16", + "vscode-css-languageservice": "^6.2.7", + "vscode-languageserver": "^8.2.0-next.3", "vscode-uri": "^3.0.7" }, "devDependencies": { diff --git a/extensions/css-language-features/server/yarn.lock b/extensions/css-language-features/server/yarn.lock index 649160819e3..296912060e4 100644 --- a/extensions/css-language-features/server/yarn.lock +++ b/extensions/css-language-features/server/yarn.lock @@ -12,55 +12,55 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/l10n@^0.0.14": - version "0.0.14" - resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.14.tgz#431e5814c35c3cb11ee21873bc70a4b0fbf90fcf" - integrity sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg== +"@vscode/l10n@^0.0.16": + version "0.0.16" + resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.16.tgz#f075db346d0b08419a12540171b230bd803c42be" + integrity sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg== -vscode-css-languageservice@^6.2.6: - version "6.2.6" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.6.tgz#bc26c2abaaa2eb117b143fdb9387ee1701d9661a" - integrity sha512-SA2WkeOecIpUiEbZnjOsP/fI5CRITZEiQGSHXKiDQDwLApfKcnLhZwMtOBbIifSzESVcQa7b/shX/nbnF4NoCg== +vscode-css-languageservice@^6.2.7: + version "6.2.7" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.7.tgz#d64e347e9a432d2b9c1a12d1ea5bc77996a2e9dc" + integrity sha512-Jd8wpIg5kJ15CfrieoEPvu3gGFc36sbM3qXCtjVq5zrnLEX5NhHxikMDtf8AgQsYklXiDqiZLKoBnzkJtRbTHQ== dependencies: - "@vscode/l10n" "^0.0.14" + "@vscode/l10n" "^0.0.16" vscode-languageserver-textdocument "^1.0.8" vscode-languageserver-types "^3.17.3" vscode-uri "^3.0.7" -vscode-jsonrpc@8.2.0-next.0: - version "8.2.0-next.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c" - integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg== +vscode-jsonrpc@8.2.0-next.2: + version "8.2.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68" + integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A== -vscode-languageserver-protocol@3.17.4-next.1: - version "3.17.4-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616" - integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg== +vscode-languageserver-protocol@3.17.4-next.3: + version "3.17.4-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c" + integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ== dependencies: - vscode-jsonrpc "8.2.0-next.0" - vscode-languageserver-types "3.17.4-next.0" + vscode-jsonrpc "8.2.0-next.2" + vscode-languageserver-types "3.17.4-next.2" vscode-languageserver-textdocument@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0" integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q== -vscode-languageserver-types@3.17.4-next.0: - version "3.17.4-next.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2" - integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag== +vscode-languageserver-types@3.17.4-next.2: + version "3.17.4-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d" + integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A== vscode-languageserver-types@^3.17.3: version "3.17.3" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== -vscode-languageserver@^8.2.0-next.1: - version "8.2.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.1.tgz#ad2558d74392b1cfaccd427febe9a368fc328f8b" - integrity sha512-994AXMKBijzjlnpf8p9M+ntsNJDjR8pr55NJPYxKjy/nUhVkg962dAomelH6Z94401kBZmSbfP/K/20cB54aFA== +vscode-languageserver@^8.2.0-next.3: + version "8.2.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.3.tgz#72e4998392260173fb0c35d2d556fb4015f56ce3" + integrity sha512-fqHRwcIRoxfKke7iLDSeUmdo3uk7o/uWNn/44xdWa4urdhsvpTZ5c1GsL1EX4TAvdDg0qeXy89NBZ5Gld2DkgQ== dependencies: - vscode-languageserver-protocol "3.17.4-next.1" + vscode-languageserver-protocol "3.17.4-next.3" vscode-uri@^3.0.7: version "3.0.7" diff --git a/extensions/css-language-features/yarn.lock b/extensions/css-language-features/yarn.lock index acd761d8f5b..826e0bb3306 100644 --- a/extensions/css-language-features/yarn.lock +++ b/extensions/css-language-features/yarn.lock @@ -40,32 +40,32 @@ semver@^7.3.7: dependencies: lru-cache "^6.0.0" -vscode-jsonrpc@8.2.0-next.0: - version "8.2.0-next.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c" - integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg== +vscode-jsonrpc@8.2.0-next.2: + version "8.2.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68" + integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A== -vscode-languageclient@^8.2.0-next.1: - version "8.2.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.1.tgz#a3f98b80cfa3225fde0583aa6a5c9b20219fa37e" - integrity sha512-oITaqHQ10PM3zXCUu/104wriMeDutXMkQXMaRBWh1jKihcNcUBLC/os7RhqiVGypY0nl+F0pwStAf4Koc8inaw== +vscode-languageclient@^8.2.0-next.3: + version "8.2.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.3.tgz#a5086f451a679ce77106d8fd1e05c8cbf8e9b886" + integrity sha512-Ojo6L2cb7GSiyD864k8vGb9fHxBdZeciHQQOF595C3IDHWg0w4KQ7iN7qGWVdl4wDNwlGTX3wWZawGfPTxnrPQ== dependencies: minimatch "^5.1.0" semver "^7.3.7" - vscode-languageserver-protocol "3.17.4-next.1" + vscode-languageserver-protocol "3.17.4-next.3" -vscode-languageserver-protocol@3.17.4-next.1: - version "3.17.4-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616" - integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg== +vscode-languageserver-protocol@3.17.4-next.3: + version "3.17.4-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c" + integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ== dependencies: - vscode-jsonrpc "8.2.0-next.0" - vscode-languageserver-types "3.17.4-next.0" + vscode-jsonrpc "8.2.0-next.2" + vscode-languageserver-types "3.17.4-next.2" -vscode-languageserver-types@3.17.4-next.0: - version "3.17.4-next.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2" - integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag== +vscode-languageserver-types@3.17.4-next.2: + version "3.17.4-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d" + integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A== vscode-uri@^3.0.7: version "3.0.7" diff --git a/extensions/html-language-features/package.json b/extensions/html-language-features/package.json index 58bd75f70e9..422fce5e7f6 100644 --- a/extensions/html-language-features/package.json +++ b/extensions/html-language-features/package.json @@ -258,8 +258,8 @@ ] }, "dependencies": { - "@vscode/extension-telemetry": "^0.7.5", - "vscode-languageclient": "^8.2.0-next.1", + "@vscode/extension-telemetry": "^0.8.4", + "vscode-languageclient": "^8.2.0-next.3", "vscode-uri": "^3.0.7" }, "devDependencies": { diff --git a/extensions/html-language-features/server/package.json b/extensions/html-language-features/server/package.json index 3304c243b35..1816dca28f5 100644 --- a/extensions/html-language-features/server/package.json +++ b/extensions/html-language-features/server/package.json @@ -9,10 +9,10 @@ }, "main": "./out/node/htmlServerMain", "dependencies": { - "@vscode/l10n": "^0.0.14", - "vscode-css-languageservice": "^6.2.6", - "vscode-html-languageservice": "^5.0.6", - "vscode-languageserver": "^8.2.0-next.1", + "@vscode/l10n": "^0.0.16", + "vscode-css-languageservice": "^6.2.7", + "vscode-html-languageservice": "^5.0.7", + "vscode-languageserver": "^8.2.0-next.3", "vscode-languageserver-textdocument": "^1.0.8", "vscode-uri": "^3.0.7" }, diff --git a/extensions/html-language-features/server/yarn.lock b/extensions/html-language-features/server/yarn.lock index fe6c91e3cf8..22f945e7f84 100644 --- a/extensions/html-language-features/server/yarn.lock +++ b/extensions/html-language-features/server/yarn.lock @@ -12,65 +12,65 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/l10n@^0.0.14": - version "0.0.14" - resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.14.tgz#431e5814c35c3cb11ee21873bc70a4b0fbf90fcf" - integrity sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg== +"@vscode/l10n@^0.0.16": + version "0.0.16" + resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.16.tgz#f075db346d0b08419a12540171b230bd803c42be" + integrity sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg== -vscode-css-languageservice@^6.2.6: - version "6.2.6" - resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.6.tgz#bc26c2abaaa2eb117b143fdb9387ee1701d9661a" - integrity sha512-SA2WkeOecIpUiEbZnjOsP/fI5CRITZEiQGSHXKiDQDwLApfKcnLhZwMtOBbIifSzESVcQa7b/shX/nbnF4NoCg== +vscode-css-languageservice@^6.2.7: + version "6.2.7" + resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-6.2.7.tgz#d64e347e9a432d2b9c1a12d1ea5bc77996a2e9dc" + integrity sha512-Jd8wpIg5kJ15CfrieoEPvu3gGFc36sbM3qXCtjVq5zrnLEX5NhHxikMDtf8AgQsYklXiDqiZLKoBnzkJtRbTHQ== dependencies: - "@vscode/l10n" "^0.0.14" + "@vscode/l10n" "^0.0.16" vscode-languageserver-textdocument "^1.0.8" vscode-languageserver-types "^3.17.3" vscode-uri "^3.0.7" -vscode-html-languageservice@^5.0.6: - version "5.0.6" - resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-5.0.6.tgz#e7a7f78e9f98d0f5341c5518dd9305e3cc438bb6" - integrity sha512-gCixNg6fjPO7+kwSMBAVXcwDRHdjz1WOyNfI0n5Wx0J7dfHG8ggb3zD1FI8E2daTZrwS1cooOiSoc1Xxph4qRQ== +vscode-html-languageservice@^5.0.7: + version "5.0.7" + resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-5.0.7.tgz#8d27773e0197799a9db777ee4fc134cf1c669d84" + integrity sha512-jX+7/kUXrdOaRT8vqYR/jLxrGDib+Far8I7n/A6apuEl88k+mhIHZPwc6ezuLeiCKUCaLG4b0dqFwjVa7QL3/w== dependencies: - "@vscode/l10n" "^0.0.14" + "@vscode/l10n" "^0.0.16" vscode-languageserver-textdocument "^1.0.8" vscode-languageserver-types "^3.17.3" vscode-uri "^3.0.7" -vscode-jsonrpc@8.2.0-next.0: - version "8.2.0-next.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c" - integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg== +vscode-jsonrpc@8.2.0-next.2: + version "8.2.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68" + integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A== -vscode-languageserver-protocol@3.17.4-next.1: - version "3.17.4-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616" - integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg== +vscode-languageserver-protocol@3.17.4-next.3: + version "3.17.4-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c" + integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ== dependencies: - vscode-jsonrpc "8.2.0-next.0" - vscode-languageserver-types "3.17.4-next.0" + vscode-jsonrpc "8.2.0-next.2" + vscode-languageserver-types "3.17.4-next.2" vscode-languageserver-textdocument@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0" integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q== -vscode-languageserver-types@3.17.4-next.0: - version "3.17.4-next.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2" - integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag== +vscode-languageserver-types@3.17.4-next.2: + version "3.17.4-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d" + integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A== vscode-languageserver-types@^3.17.3: version "3.17.3" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== -vscode-languageserver@^8.2.0-next.1: - version "8.2.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.1.tgz#ad2558d74392b1cfaccd427febe9a368fc328f8b" - integrity sha512-994AXMKBijzjlnpf8p9M+ntsNJDjR8pr55NJPYxKjy/nUhVkg962dAomelH6Z94401kBZmSbfP/K/20cB54aFA== +vscode-languageserver@^8.2.0-next.3: + version "8.2.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.3.tgz#72e4998392260173fb0c35d2d556fb4015f56ce3" + integrity sha512-fqHRwcIRoxfKke7iLDSeUmdo3uk7o/uWNn/44xdWa4urdhsvpTZ5c1GsL1EX4TAvdDg0qeXy89NBZ5Gld2DkgQ== dependencies: - vscode-languageserver-protocol "3.17.4-next.1" + vscode-languageserver-protocol "3.17.4-next.3" vscode-uri@^3.0.7: version "3.0.7" diff --git a/extensions/html-language-features/yarn.lock b/extensions/html-language-features/yarn.lock index 8bf14ed8f82..57d4562ac85 100644 --- a/extensions/html-language-features/yarn.lock +++ b/extensions/html-language-features/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,39 +185,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -170,15 +264,30 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/extension-telemetry@^0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -187,22 +296,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -236,6 +347,11 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -260,7 +376,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -272,17 +388,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -300,6 +416,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -317,6 +445,23 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -343,24 +488,52 @@ minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.3.7: +semver@^7.3.7, semver@^7.5.1, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -shimmer@^1.1.0, shimmer@^1.2.0: +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -370,6 +543,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -380,32 +558,32 @@ uuid@^8.3.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -vscode-jsonrpc@8.2.0-next.0: - version "8.2.0-next.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c" - integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg== +vscode-jsonrpc@8.2.0-next.2: + version "8.2.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68" + integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A== -vscode-languageclient@^8.2.0-next.1: - version "8.2.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.1.tgz#a3f98b80cfa3225fde0583aa6a5c9b20219fa37e" - integrity sha512-oITaqHQ10PM3zXCUu/104wriMeDutXMkQXMaRBWh1jKihcNcUBLC/os7RhqiVGypY0nl+F0pwStAf4Koc8inaw== +vscode-languageclient@^8.2.0-next.3: + version "8.2.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.3.tgz#a5086f451a679ce77106d8fd1e05c8cbf8e9b886" + integrity sha512-Ojo6L2cb7GSiyD864k8vGb9fHxBdZeciHQQOF595C3IDHWg0w4KQ7iN7qGWVdl4wDNwlGTX3wWZawGfPTxnrPQ== dependencies: minimatch "^5.1.0" semver "^7.3.7" - vscode-languageserver-protocol "3.17.4-next.1" + vscode-languageserver-protocol "3.17.4-next.3" -vscode-languageserver-protocol@3.17.4-next.1: - version "3.17.4-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616" - integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg== +vscode-languageserver-protocol@3.17.4-next.3: + version "3.17.4-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c" + integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ== dependencies: - vscode-jsonrpc "8.2.0-next.0" - vscode-languageserver-types "3.17.4-next.0" + vscode-jsonrpc "8.2.0-next.2" + vscode-languageserver-types "3.17.4-next.2" -vscode-languageserver-types@3.17.4-next.0: - version "3.17.4-next.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2" - integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag== +vscode-languageserver-types@3.17.4-next.2: + version "3.17.4-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d" + integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A== vscode-uri@^3.0.7: version "3.0.7" diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 05075ec1389..cd9e69d69b4 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -164,9 +164,9 @@ ] }, "dependencies": { - "@vscode/extension-telemetry": "^0.7.5", + "@vscode/extension-telemetry": "^0.8.4", "request-light": "^0.7.0", - "vscode-languageclient": "^8.2.0-next.1" + "vscode-languageclient": "^8.2.0-next.3" }, "devDependencies": { "@types/node": "18.x" diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index b0012a72816..8d100ef9087 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -12,11 +12,11 @@ }, "main": "./out/node/jsonServerMain", "dependencies": { - "@vscode/l10n": "^0.0.14", + "@vscode/l10n": "^0.0.16", "jsonc-parser": "^3.2.0", "request-light": "^0.7.0", - "vscode-json-languageservice": "^5.3.5", - "vscode-languageserver": "^8.2.0-next.1", + "vscode-json-languageservice": "^5.3.6", + "vscode-languageserver": "^8.2.0-next.3", "vscode-uri": "^3.0.7" }, "devDependencies": { diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index 48f16a0f42f..c433012b1a3 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -12,15 +12,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/l10n@^0.0.13": - version "0.0.13" - resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.13.tgz#f51ff130b8c98f189476c5f812d214b8efb09590" - integrity sha512-A3uY356uOU9nGa+TQIT/i3ziWUgJjVMUrGGXSrtRiTwklyCFjGVWIOHoEIHbJpiyhDkJd9kvIWUOfXK1IkK8XQ== - -"@vscode/l10n@^0.0.14": - version "0.0.14" - resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.14.tgz#431e5814c35c3cb11ee21873bc70a4b0fbf90fcf" - integrity sha512-/yrv59IEnmh655z1oeDnGcvMYwnEzNzHLgeYcQCkhYX0xBvYWrAuefoiLcPBUkMpJsb46bqQ6Yv4pwTTQ4d3Qg== +"@vscode/l10n@^0.0.16": + version "0.0.16" + resolved "https://registry.yarnpkg.com/@vscode/l10n/-/l10n-0.0.16.tgz#f075db346d0b08419a12540171b230bd803c42be" + integrity sha512-JT5CvrIYYCrmB+dCana8sUqJEcGB1ZDXNLMQ2+42bW995WmNoenijWMUdZfwmuQUTQcEVVIa2OecZzTYWUW9Cg== jsonc-parser@^3.2.0: version "3.2.0" @@ -32,51 +27,51 @@ request-light@^0.7.0: resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a" integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q== -vscode-json-languageservice@^5.3.5: - version "5.3.5" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.3.5.tgz#20acd827e13ea4bdeb9976df84ec2bfbb2452c73" - integrity sha512-DasT+bKtpaS2rTPEB4VMROnvO1WES2KD8RZZxXbumnk9sk5wco10VdB6sJgTlsKQN14tHQLZDXuHnSoSAlE8LQ== +vscode-json-languageservice@^5.3.6: + version "5.3.6" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.3.6.tgz#8cbe39dfdf29e7f7e97c9b6966b76031991290f6" + integrity sha512-P4kthBi3GMLKi7Lmp24nkKHAWxbFfCsIDBPlMrK1Tag1aqbl3l60UferDkfAasupDVBM2dekbArzGycUjw8OHA== dependencies: - "@vscode/l10n" "^0.0.13" + "@vscode/l10n" "^0.0.16" jsonc-parser "^3.2.0" vscode-languageserver-textdocument "^1.0.8" vscode-languageserver-types "^3.17.3" vscode-uri "^3.0.7" -vscode-jsonrpc@8.2.0-next.0: - version "8.2.0-next.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c" - integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg== +vscode-jsonrpc@8.2.0-next.2: + version "8.2.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68" + integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A== -vscode-languageserver-protocol@3.17.4-next.1: - version "3.17.4-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616" - integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg== +vscode-languageserver-protocol@3.17.4-next.3: + version "3.17.4-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c" + integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ== dependencies: - vscode-jsonrpc "8.2.0-next.0" - vscode-languageserver-types "3.17.4-next.0" + vscode-jsonrpc "8.2.0-next.2" + vscode-languageserver-types "3.17.4-next.2" vscode-languageserver-textdocument@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz#9eae94509cbd945ea44bca8dcfe4bb0c15bb3ac0" integrity sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q== -vscode-languageserver-types@3.17.4-next.0: - version "3.17.4-next.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2" - integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag== +vscode-languageserver-types@3.17.4-next.2: + version "3.17.4-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d" + integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A== vscode-languageserver-types@^3.17.3: version "3.17.3" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz#72d05e47b73be93acb84d6e311b5786390f13f64" integrity sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA== -vscode-languageserver@^8.2.0-next.1: - version "8.2.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.1.tgz#ad2558d74392b1cfaccd427febe9a368fc328f8b" - integrity sha512-994AXMKBijzjlnpf8p9M+ntsNJDjR8pr55NJPYxKjy/nUhVkg962dAomelH6Z94401kBZmSbfP/K/20cB54aFA== +vscode-languageserver@^8.2.0-next.3: + version "8.2.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.2.0-next.3.tgz#72e4998392260173fb0c35d2d556fb4015f56ce3" + integrity sha512-fqHRwcIRoxfKke7iLDSeUmdo3uk7o/uWNn/44xdWa4urdhsvpTZ5c1GsL1EX4TAvdDg0qeXy89NBZ5Gld2DkgQ== dependencies: - vscode-languageserver-protocol "3.17.4-next.1" + vscode-languageserver-protocol "3.17.4-next.3" vscode-uri@^3.0.7: version "3.0.7" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 98083a9489f..1ea64055bdd 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -17,7 +17,16 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" -"@azure/core-rest-pipeline@^1.10.0": +"@azure/core-auth@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.5.0.tgz#a41848c5c31cb3b7c84c409885267d55a2c92e44" + integrity sha512-udzoBuYG1VBoHVohDTrvKjyzel34zt77Bhp7dQntVGGD0ehVq48owENbBG8fIgkHRNUBQH5k1r0hpoMu5L8+kw== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-util" "^1.1.0" + tslib "^2.2.0" + +"@azure/core-rest-pipeline@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz#348290847ca31b9eecf9cf5de7519aaccdd30968" integrity sha512-Kji9k6TOFRDB5ZMTw8qUf2IJ+CeJtsuMdAHox9eqpTf1cefiNMpzrfnF6sINEBZJsaVaWgQ0o48B6kcUH68niA== @@ -33,13 +42,21 @@ tslib "^2.2.0" uuid "^8.3.0" -"@azure/core-tracing@^1.0.1": +"@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" +"@azure/core-util@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.2.0.tgz#3499deba1fc36dda6f1912b791809b6f15d4a392" + integrity sha512-ffGIw+Qs8bNKNLxz5UPkz4/VBM/EZY07mPve1ZYFqYUdPwFqRj0RPk0U7LZMOfT7GCck9YjuT1Rfp1PApNl1ng== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/core-util@^1.0.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.1.tgz#8f87b3dd468795df0f0849d9f096c3e7b29452c1" @@ -48,6 +65,14 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-util@^1.1.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.4.0.tgz#c120a56b3e48a9e4d20619a0b00268ae9de891c7" + integrity sha512-eGAyJpm3skVQoLiRqm/xPa+SXi/NPDdSHMxbRAz2lSprd+Zs+qrpQGQQ2VQ3Nttu+nSZR4XoYQC71LbEI7jsig== + dependencies: + "@azure/abort-controller" "^1.0.0" + tslib "^2.2.0" + "@azure/logger@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" @@ -55,66 +80,100 @@ dependencies: tslib "^2.2.0" -"@microsoft/1ds-core-js@3.2.8", "@microsoft/1ds-core-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.8.tgz#1b6b7d9bb858238c818ccf4e4b58ece7aeae5760" - integrity sha512-9o9SUAamJiTXIYwpkQDuueYt83uZfXp8zp8YFix1IwVPwC9RmE36T2CX9gXOeq1nDckOuOduYpA8qHvdh5BGfQ== +"@azure/opentelemetry-instrumentation-azure-sdk@^1.0.0-beta.5": + version "1.0.0-beta.5" + resolved "https://registry.yarnpkg.com/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz#78809e6c005d08450701e5d37f087f6fce2f86eb" + integrity sha512-fsUarKQDvjhmBO4nIfaZkfNSApm1hZBzcvpNbSrXdcUBxu7lRvKsV5DnwszX7cnhLyVOW9yl1uigtRQ1yDANjA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" + "@azure/core-tracing" "^1.0.0" + "@azure/logger" "^1.0.0" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/instrumentation" "^0.41.2" + tslib "^2.2.0" + +"@microsoft/1ds-core-js@3.2.13", "@microsoft/1ds-core-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.13.tgz#0c105ed75091bae3f1555c0334704fa9911c58fb" + integrity sha512-CluYTRWcEk0ObG5EWFNWhs87e2qchJUn0p2D21ZUa3PWojPZfPSBs4//WIE0MYV8Qg1Hdif2ZTwlM7TbYUjfAg== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.15" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/1ds-post-js@^3.2.8": - version "3.2.8" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.8.tgz#46793842cca161bf7a2a5b6053c349f429e55110" - integrity sha512-SjlRoNcXcXBH6WQD/5SkkaCHIVqldH3gDu+bI7YagrOVJ5APxwT1Duw9gm3L1FjFa9S2i81fvJ3EVSKpp9wULA== +"@microsoft/1ds-post-js@^3.2.13": + version "3.2.13" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.13.tgz#560aacac8a92fdbb79e8c2ebcb293d56e19f51aa" + integrity sha512-HgS574fdD19Bo2vPguyznL4eDw7Pcm1cVNpvbvBLWiW3x4e1FCQ3VMXChWnAxCae8Hb0XqlA2sz332ZobBavTA== dependencies: - "@microsoft/1ds-core-js" "3.2.8" + "@microsoft/1ds-core-js" "3.2.13" "@microsoft/applicationinsights-shims" "^2.0.2" "@microsoft/dynamicproto-js" "^1.1.7" -"@microsoft/applicationinsights-channel-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.9.tgz#840656f3c716de8b3eb0a98c122aa1b92bb8ebfb" - integrity sha512-fMBsAEB7pWtPn43y72q9Xy5E5y55r6gMuDQqRRccccVoQDPXyS57VCj5IdATblctru0C6A8XpL2vRyNmEsu0Vg== +"@microsoft/applicationinsights-channel-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.0.2.tgz#be49fbf74831c7b8c97950027c5052ea99d2a8a5" + integrity sha512-jDBNKbCHsJgmpv0CKNhJ/uN9ZphvfGdb93Svk+R4LjO8L3apNNMbDDPxBvXXi0uigRmA1TBcmyBG4IRKjabGhw== dependencies: - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-common@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.9.tgz#a75e4a3143a7fd797687830c0ddd2069fd900827" - integrity sha512-mObn1moElyxZaGIRF/IU3cOaeKMgxghXnYEoHNUCA2e+rNwBIgxjyKkblFIpmGuHf4X7Oz3o3yBWpaC6AoMpig== +"@microsoft/applicationinsights-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-3.0.2.tgz#37670bb07f4858ed41ff9759119e0759007d6e05" + integrity sha512-y+WXWop+OVim954Cu1uyYMnNx6PWO8okHpZIQi/1YSqtqaYdtJVPv4P0AVzwJdohxzVfgzKvqj9nec/VWqE2Zg== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" -"@microsoft/applicationinsights-core-js@2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.9.tgz#0e5d207acfae6986a6fc97249eeb6117e523bf1b" - integrity sha512-HRuIuZ6aOWezcg/G5VyFDDWGL8hDNe/ljPP01J7ImH2kRPEgbtcfPSUMjkamGMefgdq81GZsSoC/NNGTP4pp2w== +"@microsoft/applicationinsights-core-js@2.8.15": + version "2.8.15" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.15.tgz#8fa466474260e01967fe649f14dd9e5ff91dcdc8" + integrity sha512-yYAs9MyjGr2YijQdUSN9mVgT1ijI1FPMgcffpaPmYbHAVbQmF7bXudrBWHxmLzJlwl5rfep+Zgjli2e67lwUqQ== dependencies: "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/dynamicproto-js" "^1.1.9" + +"@microsoft/applicationinsights-core-js@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.0.2.tgz#108e20df8c162bec92b1f66f9de2530a25d9f51a" + integrity sha512-WQhVhzlRlLDrQzn3OShCW/pL3BW5WC57t0oywSknX3q7lMzI3jDg7Ihh0iuIcNTzGCTbDkuqr4d6IjEDWIMtJQ== + dependencies: + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== -"@microsoft/applicationinsights-web-basic@^2.8.9": - version "2.8.9" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.9.tgz#eed2f3d1e19069962ed2155915c1656e6936e1d5" - integrity sha512-CH0J8JFOy7MjK8JO4pXXU+EML+Ilix+94PMZTX5EJlBU1in+mrik74/8qSg3UC4ekPi12KwrXaHCQSVC3WseXQ== +"@microsoft/applicationinsights-shims@3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz#3865b73ace8405b9c4618cc5c571f2fe3876f06f" + integrity sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg== dependencies: - "@microsoft/applicationinsights-channel-js" "2.8.9" - "@microsoft/applicationinsights-common" "2.8.9" - "@microsoft/applicationinsights-core-js" "2.8.9" - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" + +"@microsoft/applicationinsights-web-basic@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-3.0.2.tgz#f777a4d24b79dde3ae396d3b819e1fce06b7240a" + integrity sha512-6Lq0DE/pZp9RvSV+weGbcxN1NDmfczj6gNPhvZKV2YSQ3RK0LZE3+wjTWLXfuStq8a+nCBdsRpWk8tOKgsoxcg== + dependencies: + "@microsoft/applicationinsights-channel-js" "3.0.2" + "@microsoft/applicationinsights-common" "3.0.2" + "@microsoft/applicationinsights-core-js" "3.0.2" + "@microsoft/applicationinsights-shims" "3.0.1" + "@microsoft/dynamicproto-js" "^2.0.2" + "@nevware21/ts-async" ">= 0.2.4 < 2.x" + "@nevware21/ts-utils" ">= 0.9.5 < 2.x" "@microsoft/applicationinsights-web-snippet@^1.0.1": version "1.0.1" @@ -126,39 +185,74 @@ resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== -"@opentelemetry/api@^1.0.4": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" - integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== +"@microsoft/dynamicproto-js@^1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6" + integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ== -"@opentelemetry/core@1.7.0", "@opentelemetry/core@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.7.0.tgz#83bdd1b7a4ceafcdffd6590420657caec5f7b34c" - integrity sha512-AVqAi5uc8DrKJBimCTFUT4iFI+5eXpo4sYmGbQ0CypG0piOTHE2g9c5aSoTGYXu3CzOmJZf7pT6Xh+nwm5d6yQ== +"@microsoft/dynamicproto-js@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.2.tgz#e57fbec2e7067d48b7e8e1e1c1d354028ef718a6" + integrity sha512-MB8trWaFREpmb037k/d0bB7T2BP7Ai24w1e1tbz3ASLB0/lwphsq3Nq8S9I5AsI5vs4zAQT+SB5nC5/dLYTiOg== dependencies: - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.9.4 < 2.x" -"@opentelemetry/resources@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.7.0.tgz#90ccd3a6a86b4dfba4e833e73944bd64958d78c5" - integrity sha512-u1M0yZotkjyKx8dj+46Sg5thwtOTBmtRieNXqdCRiWUp6SfFiIP0bI+1XK3LhuXqXkBXA1awJZaTqKduNMStRg== +"@nevware21/ts-async@>= 0.2.4 < 2.x": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@nevware21/ts-async/-/ts-async-0.3.0.tgz#a8b97ba01065fc930de9a3f4dd4a05e862becc6c" + integrity sha512-ZUcgUH12LN/F6nzN0cYd0F/rJaMLmXr0EHVTyYfaYmK55bdwE4338uue4UiVoRqHVqNW4KDUrJc49iGogHKeWA== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@nevware21/ts-utils" ">= 0.10.0 < 2.x" -"@opentelemetry/sdk-trace-base@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.7.0.tgz#b498424e0c6340a9d80de63fd408c5c2130a60a5" - integrity sha512-Iz84C+FVOskmauh9FNnj4+VrA+hG5o+tkMzXuoesvSfunVSioXib0syVFeNXwOm4+M5GdWCuW632LVjqEXStIg== +"@nevware21/ts-utils@>= 0.10.0 < 2.x", "@nevware21/ts-utils@>= 0.9.4 < 2.x", "@nevware21/ts-utils@>= 0.9.5 < 2.x": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@nevware21/ts-utils/-/ts-utils-0.10.1.tgz#aa65abc71eba06749a396598f22263d26f796ac7" + integrity sha512-pMny25NnF2/MJwdqC3Iyjm2pGIXNxni4AROpcqDeWa+td9JMUY4bUS9uU9XW+BoBRqTLUL+WURF9SOd/6OQzRg== + +"@opentelemetry/api@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" + integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA== + +"@opentelemetry/core@1.15.2", "@opentelemetry/core@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" + integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== dependencies: - "@opentelemetry/core" "1.7.0" - "@opentelemetry/resources" "1.7.0" - "@opentelemetry/semantic-conventions" "1.7.0" + "@opentelemetry/semantic-conventions" "1.15.2" -"@opentelemetry/semantic-conventions@1.7.0", "@opentelemetry/semantic-conventions@^1.0.1": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.7.0.tgz#af80a1ef7cf110ea3a68242acd95648991bcd763" - integrity sha512-FGBx/Qd09lMaqQcogCHyYrFEpTx4cAjeS+48lMIR12z7LdH+zofGDVQSubN59nL6IpubfKqTeIDu9rNO28iHVA== +"@opentelemetry/instrumentation@^0.41.2": + version "0.41.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.41.2.tgz#cae11fa64485dcf03dae331f35b315b64bc6189f" + integrity sha512-rxU72E0pKNH6ae2w5+xgVYZLzc5mlxAbGzF4shxMVK8YC2QQsfN38B2GPbj0jvrKWWNUElfclQ+YTykkNg/grw== + dependencies: + "@types/shimmer" "^1.0.2" + import-in-the-middle "1.4.2" + require-in-the-middle "^7.1.1" + semver "^7.5.1" + shimmer "^1.2.1" + +"@opentelemetry/resources@1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.15.2.tgz#0c9e26cb65652a1402834a3c030cce6028d6dd9d" + integrity sha512-xmMRLenT9CXmm5HMbzpZ1hWhaUowQf8UB4jMjFlAxx1QzQcsD3KFNAVX/CAWzFPtllTyTplrA4JrQ7sCH3qmYw== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/sdk-trace-base@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.15.2.tgz#4821f94033c55a6c8bbd35ae387b715b6108517a" + integrity sha512-BEaxGZbWtvnSPchV98qqqqa96AOcb41pjgvhfzDij10tkBhIu9m0Jd6tZ1tJB5ZHfHbTffqYVYE0AOGobec/EQ== + dependencies: + "@opentelemetry/core" "1.15.2" + "@opentelemetry/resources" "1.15.2" + "@opentelemetry/semantic-conventions" "1.15.2" + +"@opentelemetry/semantic-conventions@1.15.2", "@opentelemetry/semantic-conventions@^1.15.2": + version "1.15.2" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" + integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== "@tootallnate/once@2": version "2.0.0" @@ -170,15 +264,30 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== -"@vscode/extension-telemetry@^0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b" - integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w== +"@types/shimmer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/shimmer/-/shimmer-1.0.2.tgz#93eb2c243c351f3f17d5c580c7467ae5d686b65f" + integrity sha512-dKkr1bTxbEsFlh2ARpKzcaAmsYixqt9UyCdoEZk8rHyE4iQYcDCyvSjDSf7JUWJHlJiTtbIoQjxKh6ViywqDAg== + +"@vscode/extension-telemetry@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz#c078c6f55df1c9e0592de3b4ce0f685dd345bfe7" + integrity sha512-UqM9+KZDDK3MyoHTsg6XNM+XO6pweQxzCpqJz33BoBEYAGsbBviRYcVpJglgay2oReuDD2pOI1Nio3BKNDLhWA== dependencies: - "@microsoft/1ds-core-js" "^3.2.8" - "@microsoft/1ds-post-js" "^3.2.8" - "@microsoft/applicationinsights-web-basic" "^2.8.9" - applicationinsights "2.4.1" + "@microsoft/1ds-core-js" "^3.2.13" + "@microsoft/1ds-post-js" "^3.2.13" + "@microsoft/applicationinsights-web-basic" "^3.0.2" + applicationinsights "^2.7.1" + +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== agent-base@6: version "6.0.2" @@ -187,22 +296,24 @@ agent-base@6: dependencies: debug "4" -applicationinsights@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d" - integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA== +applicationinsights@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.7.3.tgz#8781454d29c0b14c9773f2e892b4cf5e7468ffa5" + integrity sha512-JY8+kTEkjbA+kAVNWDtpfW2lqsrDALfDXuxOs74KLPu2y13fy/9WB52V4LfYVTVcW1/jYOXjTxNS2gPZIDh1iw== dependencies: - "@azure/core-auth" "^1.4.0" - "@azure/core-rest-pipeline" "^1.10.0" + "@azure/core-auth" "^1.5.0" + "@azure/core-rest-pipeline" "1.10.1" + "@azure/core-util" "1.2.0" + "@azure/opentelemetry-instrumentation-azure-sdk" "^1.0.0-beta.5" "@microsoft/applicationinsights-web-snippet" "^1.0.1" - "@opentelemetry/api" "^1.0.4" - "@opentelemetry/core" "^1.0.1" - "@opentelemetry/sdk-trace-base" "^1.0.1" - "@opentelemetry/semantic-conventions" "^1.0.1" + "@opentelemetry/api" "^1.4.1" + "@opentelemetry/core" "^1.15.2" + "@opentelemetry/sdk-trace-base" "^1.15.2" + "@opentelemetry/semantic-conventions" "^1.15.2" cls-hooked "^4.2.2" continuation-local-storage "^3.2.1" - diagnostic-channel "1.1.0" - diagnostic-channel-publishers "1.0.5" + diagnostic-channel "1.1.1" + diagnostic-channel-publishers "1.0.7" async-hook-jl@^1.7.6: version "1.7.6" @@ -236,6 +347,11 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + cls-hooked@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908" @@ -260,7 +376,7 @@ continuation-local-storage@^3.2.1: async-listener "^0.6.0" emitter-listener "^1.1.1" -debug@4: +debug@4, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -272,17 +388,17 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -diagnostic-channel-publishers@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae" - integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg== +diagnostic-channel-publishers@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.7.tgz#9b7f8d5ee1295481aee19c827d917e96fedf2c4a" + integrity sha512-SEECbY5AiVt6DfLkhkaHNeshg1CogdLLANA8xlG/TKvS+XUgvIKl7VspJGYiEdL5OUyzMVnr7o0AwB7f+/Mjtg== -diagnostic-channel@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e" - integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ== +diagnostic-channel@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.1.tgz#44b60972de9ee055c16216535b0e9db3f6a0efd0" + integrity sha512-r2HV5qFkUICyoaKlBEpLKHjxMXATUf/l+h8UZPGBHGLy4DDiY2sOLcIctax4eRnTw5wH2jTMExLntGPJ8eOJxw== dependencies: - semver "^5.3.0" + semver "^7.5.3" emitter-listener@^1.0.1, emitter-listener@^1.1.1: version "1.1.2" @@ -300,6 +416,18 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + http-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" @@ -317,6 +445,23 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== + dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" + module-details-from-path "^1.0.3" + +is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== + dependencies: + has "^1.0.3" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -343,29 +488,57 @@ minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" +module-details-from-path@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" + integrity sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + request-light@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.7.0.tgz#885628bb2f8040c26401ebf258ec51c4ae98ac2a" integrity sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q== +require-in-the-middle@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/require-in-the-middle/-/require-in-the-middle-7.2.0.tgz#b539de8f00955444dc8aed95e17c69b0a4f10fcf" + integrity sha512-3TLx5TGyAY6AOqLBoXmHkNql0HIf2RGbuMgCDT2WO/uGVAPJs6h7Kl+bN6TIZGd9bWhWPwnDnTHGtW8Iu77sdw== + dependencies: + debug "^4.1.1" + module-details-from-path "^1.0.3" + resolve "^1.22.1" + +resolve@^1.22.1: + version "1.22.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.4.tgz#1dc40df46554cdaf8948a486a10f6ba1e2026c34" + integrity sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + semver@^5.3.0, semver@^5.4.1: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.3.7: +semver@^7.3.7, semver@^7.5.1, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -shimmer@^1.1.0, shimmer@^1.2.0: +shimmer@^1.1.0, shimmer@^1.2.0, shimmer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== @@ -375,6 +548,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + tslib@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" @@ -385,32 +563,32 @@ uuid@^8.3.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -vscode-jsonrpc@8.2.0-next.0: - version "8.2.0-next.0" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.0.tgz#41409413c8cebf10f2f1b7cc87e330f0e292814c" - integrity sha512-13jYzaFQpTz5qQ2P+l5c/iTVsj1wUpflP0CR/v4XaEpM0oToLEXZBTcuuox1WaGIbu3Av3xxmGNU4Hydl1iNKg== +vscode-jsonrpc@8.2.0-next.2: + version "8.2.0-next.2" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0-next.2.tgz#09d72832353fc7fb43b33c9c68b083907f6a8a68" + integrity sha512-1FQrqLselaLLe5ApFSU/8qGUbJ8tByWbqczMkT2PEDpDYthCQTe5wONPuVphe7BB+FvZwvBFI2kFkY7FtyHc1A== -vscode-languageclient@^8.2.0-next.1: - version "8.2.0-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.1.tgz#a3f98b80cfa3225fde0583aa6a5c9b20219fa37e" - integrity sha512-oITaqHQ10PM3zXCUu/104wriMeDutXMkQXMaRBWh1jKihcNcUBLC/os7RhqiVGypY0nl+F0pwStAf4Koc8inaw== +vscode-languageclient@^8.2.0-next.3: + version "8.2.0-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.2.0-next.3.tgz#a5086f451a679ce77106d8fd1e05c8cbf8e9b886" + integrity sha512-Ojo6L2cb7GSiyD864k8vGb9fHxBdZeciHQQOF595C3IDHWg0w4KQ7iN7qGWVdl4wDNwlGTX3wWZawGfPTxnrPQ== dependencies: minimatch "^5.1.0" semver "^7.3.7" - vscode-languageserver-protocol "3.17.4-next.1" + vscode-languageserver-protocol "3.17.4-next.3" -vscode-languageserver-protocol@3.17.4-next.1: - version "3.17.4-next.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.1.tgz#a15480e1bc663853ae90ded226efafc5ab333616" - integrity sha512-qrK4BycgPR/+nkRN9PRVTblkLp+kUPUmAgF6rDhFzZIPXW4/MqWwFUT8uswIMGdlTPPgCEkFO/AYEZK1fDXODg== +vscode-languageserver-protocol@3.17.4-next.3: + version "3.17.4-next.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.4-next.3.tgz#7d1d4fcaaa3213a8f2b8a6f1efa8187163251b7c" + integrity sha512-GnW3ldfzlsDK9B1/L1edBW1ddSakC59r+DRipTYCcXIT/zCCbLID998Dxn+exgrL33e3/XLQ+7hQQiSz6TnhKQ== dependencies: - vscode-jsonrpc "8.2.0-next.0" - vscode-languageserver-types "3.17.4-next.0" + vscode-jsonrpc "8.2.0-next.2" + vscode-languageserver-types "3.17.4-next.2" -vscode-languageserver-types@3.17.4-next.0: - version "3.17.4-next.0" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.0.tgz#4b5238d21cceaeb836d36a05d23c61a8c0238de2" - integrity sha512-2FPKboHnT04xYjfM8JpJVBz4a/tryMw58jmzucaabZMZN5hzoFBrhc97jNG4n6edr9JUb9+QSwwcAcYpDTAoag== +vscode-languageserver-types@3.17.4-next.2: + version "3.17.4-next.2" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.4-next.2.tgz#4099ff39b38edbd2680df13bfb1c05f0c07bfe8d" + integrity sha512-r6tXyCXyXQH7b6VHkvRT0Nd9v+DWQiosgTR6HQajCb4iJ1myr3KgueWEGBF1Ph5/YAiDy8kXUhf8dHl7wE1H2A== yallist@^4.0.0: version "4.0.0" From 9bfbb69c30ceb61d7e96bc4c16712a284038099b Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Mon, 28 Aug 2023 14:57:24 -0700 Subject: [PATCH 045/198] Add unit testing for nb sticky scroll (#191524) * static computeContent for sticky testing * nb sticky refactor for testing * move helper fxns to test suite --- .../viewParts/notebookEditorStickyScroll.ts | 290 +++++++------- ...hould_render_empty___scrollTop_at_0_0.snap | 1 + ...ld_render_0-_1___visible_range_3-_8_0.snap | 1 + ...ng_next_2_against_following_section_0.snap | 1 + ...1___collapsing_against_third_header_0.snap | 1 + ...___scrolltop_halfway_through_cell_0_0.snap | 1 + ...___scrolltop_halfway_through_cell_2_0.snap | 1 + ...___scrolltop_halfway_through_cell_7_0.snap | 1 + ...1___collapsing_against_next_section_0.snap | 1 + .../test/browser/notebookStickyScroll.test.ts | 369 ++++++++++++++++++ .../test/browser/testNotebookEditor.ts | 54 ++- 11 files changed, 565 insertions(+), 156 deletions(-) create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test0__should_render_empty___scrollTop_at_0_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test1__should_render_0-_1___visible_range_3-_8_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test2__should_render_0____visible_range_6-_9_so_collapsing_next_2_against_following_section_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_third_header_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test4__should_render_0____scrolltop_halfway_through_cell_0_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test5__should_render_0-_2___scrolltop_halfway_through_cell_2_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test6__should_render_6-_7___scrolltop_halfway_through_cell_7_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test7__should_render_0-_1___collapsing_against_next_section_0.snap create mode 100644 src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts index 824835d21d0..7b490223afd 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts @@ -5,6 +5,7 @@ import { localize } from 'vs/nls'; import * as DOM from 'vs/base/browser/dom'; +import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; @@ -16,7 +17,6 @@ import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookB import { INotebookCellList } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon'; import { NotebookCellOutlineProvider, OutlineEntry } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider'; import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; -import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; export class ToggleNotebookStickyScroll extends Action2 { @@ -48,7 +48,7 @@ export class ToggleNotebookStickyScroll extends Action2 { } } -class NotebookStickyLine extends Disposable { +export class NotebookStickyLine extends Disposable { constructor( public readonly element: HTMLElement, public readonly entry: OutlineEntry, @@ -79,10 +79,9 @@ class NotebookStickyLine extends Disposable { } } - export class NotebookStickyScroll extends Disposable { private readonly _disposables = new DisposableStore(); - private currentStickyLines = new Map(); + private currentStickyLines = new Map(); getDomNode(): HTMLElement { return this.domNode; @@ -92,6 +91,10 @@ export class NotebookStickyScroll extends Disposable { return this.currentStickyLines.size * 22; } + private setCurrentStickyLines(newStickyLines: Map) { + this.currentStickyLines = newStickyLines; + } + constructor( private readonly domNode: HTMLElement, private readonly notebookEditor: INotebookEditor, @@ -132,9 +135,7 @@ export class NotebookStickyScroll extends Disposable { this.init(); } else { this._disposables.clear(); - this.currentStickyLines.forEach((value) => { - value.dispose(); - }); + this.disposeCurrentStickyLines(); DOM.clearNode(this.domNode); this.updateDisplay(); } @@ -153,7 +154,9 @@ export class NotebookStickyScroll extends Disposable { this.initializeContent(); this._disposables.add(this.notebookOutline.onDidChange(() => { - this.updateContent(); + DOM.clearNode(this.domNode); + this.disposeCurrentStickyLines(); + this.updateContent(computeContent(this.domNode, this.notebookEditor, this.notebookCellList, this.notebookOutline.entries)); })); this._disposables.add(this.notebookEditor.onDidAttachViewModel(() => { @@ -162,18 +165,20 @@ export class NotebookStickyScroll extends Disposable { })); this._disposables.add(this.notebookEditor.onDidScroll(() => { - this.updateContent(); + DOM.clearNode(this.domNode); + this.disposeCurrentStickyLines(); + this.updateContent(computeContent(this.domNode, this.notebookEditor, this.notebookCellList, this.notebookOutline.entries)); })); } - private getVisibleOutlineEntry(visibleIndex: number): OutlineEntry | undefined { + static getVisibleOutlineEntry(visibleIndex: number, notebookOutlineEntries: OutlineEntry[]): OutlineEntry | undefined { let left = 0; - let right = this.notebookOutline.entries.length - 1; + let right = notebookOutlineEntries.length - 1; let bucket = -1; while (left <= right) { const mid = Math.floor((left + right) / 2); - if (this.notebookOutline.entries[mid].index < visibleIndex) { + if (notebookOutlineEntries[mid].index < visibleIndex) { bucket = mid; left = mid + 1; } else { @@ -182,7 +187,7 @@ export class NotebookStickyScroll extends Disposable { } if (bucket !== -1) { - const rootEntry = this.notebookOutline.entries[bucket]; + const rootEntry = notebookOutlineEntries[bucket]; const flatList: OutlineEntry[] = []; rootEntry.asFlatList(flatList); return flatList.find(entry => entry.index === visibleIndex); @@ -206,7 +211,7 @@ export class NotebookStickyScroll extends Disposable { for (let i = visibleRange.start; i < visibleRange.end; i++) { if (i === 0) { // don't show headers when you're viewing the top cell this.updateDisplay(); - this.currentStickyLines = new Map(); + this.setCurrentStickyLines(new Map()); return; } const cell = this.notebookEditor.cellAt(i); @@ -226,12 +231,12 @@ export class NotebookStickyScroll extends Disposable { // store the bottom scroll position of this cell sectionBottom = this.notebookCellList.getCellViewScrollBottom(cell); // compute sticky scroll height - const entry = this.getVisibleOutlineEntry(i); + const entry = NotebookStickyScroll.getVisibleOutlineEntry(i, this.notebookOutline.entries); if (!entry) { return; } // using 22 instead of stickyscrollheight, as we don't necessarily render each line. 22 starts rendering sticky when we have space for at least 1 of them - const newStickyHeight = this.computeStickyHeight(entry!); + const newStickyHeight = NotebookStickyScroll.computeStickyHeight(entry!); if (editorScrollTop + newStickyHeight < sectionBottom) { trackedEntry = entry; break; @@ -243,7 +248,7 @@ export class NotebookStickyScroll extends Disposable { } else { // there is no next cell, so use the bottom of the editor as the sectionBottom, using scrolltop + height sectionBottom = this.notebookEditor.scrollTop + this.notebookEditor.getLayoutInfo().scrollHeight; - trackedEntry = this.getVisibleOutlineEntry(i); + trackedEntry = NotebookStickyScroll.getVisibleOutlineEntry(i, this.notebookOutline.entries); break; } } // cell loop close @@ -253,130 +258,14 @@ export class NotebookStickyScroll extends Disposable { // compute the space available for sticky lines, and render sticky lines const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); - let newMap: Map | undefined = new Map(); - newMap = this.renderStickyLines(trackedEntry?.parent, this.domNode, linesToRender, newMap); - if (!newMap) { - newMap = new Map(); - } - this.currentStickyLines = newMap; + let newMap: Map = new Map(); + newMap = NotebookStickyScroll.renderStickyLines(trackedEntry?.parent, this.domNode, linesToRender, newMap, this.notebookEditor); + this.setCurrentStickyLines(newMap); this.updateDisplay(); } - - private updateContent() { - // find first code cell in visible range. this marks the start of the first section - // find the last code cell in the first section of the visible range, store the bottom scroll position in a const sectionBottom - // compute sticky scroll height, and check if editorScrolltop + stickyScrollHeight < sectionBottom - // if that condition is true, break out of the loop with that cell as the tracked cell - // if that condition is false, continue to next cell - - DOM.clearNode(this.domNode); - // iterate over current map and dispose each notebookstickyline - this.currentStickyLines.forEach((value) => { - value.dispose(); - }); - - const editorScrollTop = this.notebookEditor.scrollTop; - - // find last code cell of section, store bottom scroll position in sectionBottom - const visibleRange = this.notebookEditor.visibleRanges[0]; - if (!visibleRange) { - this.updateDisplay(); - this.currentStickyLines = new Map(); - return; - } - - let trackedEntry = undefined; - let sectionBottom = 0; - for (let i = visibleRange.start; i < visibleRange.end; i++) { - if (i === 0) { // don't show headers when you're viewing the top cell - this.updateDisplay(); - this.currentStickyLines = new Map(); - return; - } - const cell = this.notebookEditor.cellAt(i); - if (!cell) { - return; - } - if (cell.cellKind === CellKind.Markup) { - continue; - } - - // if we are here, the cell is a code cell. - // check next cell, if markdown, that means this is the end of the section - const nextVisibleCell = this.notebookEditor.cellAt(i + 1); - if (nextVisibleCell && i + 1 < visibleRange.end) { - if (nextVisibleCell.cellKind === CellKind.Markup) { - // this is the end of the section - // store the bottom scroll position of this cell - sectionBottom = this.notebookCellList.getCellViewScrollBottom(cell); - // compute sticky scroll height - const entry = this.getVisibleOutlineEntry(i); - if (!entry) { - return; - } - // check if we can render this section of sticky - const currentSectionStickyHeight = this.computeStickyHeight(entry!); - if (editorScrollTop + currentSectionStickyHeight < sectionBottom) { - const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); - let newMap: Map | undefined = new Map(); - newMap = this.renderStickyLines(entry?.parent, this.domNode, linesToRender, newMap); - if (!newMap) { - newMap = new Map(); - } - this.currentStickyLines = newMap; - break; - } - - let nextSectionEntry = undefined; - for (let j = 1; j < visibleRange.end - i; j++) { - // find next code cell after this one - const cellCheck = this.notebookEditor.cellAt(i + j); - if (cellCheck && cellCheck.cellKind === CellKind.Code) { - nextSectionEntry = this.getVisibleOutlineEntry(i + j); - break; - } - } - const nextSectionStickyHeight = this.computeStickyHeight(nextSectionEntry!); - - // this block of logic cleans transitions between two sections that share a parent. - // if the current section and the next section share a parent, then we can render the next section's sticky lines to avoid pop-in between - if (entry?.parent?.parent === nextSectionEntry?.parent) { - const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22) + 1; - let newMap: Map | undefined = new Map(); - newMap = this.renderStickyLines(nextSectionEntry?.parent, this.domNode, linesToRender, newMap); - if (!newMap) { - newMap = new Map(); - } - this.currentStickyLines = newMap; - break; - } else if (Math.abs(currentSectionStickyHeight - nextSectionStickyHeight) > 22) { // only shrink sticky - const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); - let newMap: Map | undefined = new Map(); - newMap = this.renderStickyLines(entry?.parent, this.domNode, linesToRender, newMap); - if (!newMap) { - newMap = new Map(); - } - this.currentStickyLines = newMap; - break; - } - } - } else { - // there is no next cell, so use the bottom of the editor as the sectionBottom, using scrolltop + height - sectionBottom = this.notebookEditor.scrollTop + this.notebookEditor.getLayoutInfo().scrollHeight; - trackedEntry = this.getVisibleOutlineEntry(i); - const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); - - let newMap: Map | undefined = new Map(); - newMap = this.renderStickyLines(trackedEntry?.parent, this.domNode, linesToRender, newMap); - if (!newMap) { - newMap = new Map(); - } - this.currentStickyLines = newMap; - - break; - } - } // cell loop close + private updateContent(newMap: Map) { + this.setCurrentStickyLines(newMap); this.updateDisplay(); } @@ -390,7 +279,7 @@ export class NotebookStickyScroll extends Disposable { this.setTop(); } - private computeStickyHeight(entry: OutlineEntry) { + static computeStickyHeight(entry: OutlineEntry) { let height = 0; while (entry.parent) { height += 22; @@ -399,19 +288,19 @@ export class NotebookStickyScroll extends Disposable { return height; } - private renderStickyLines(entry: OutlineEntry | undefined, containerElement: HTMLElement, numLinesToRender: number, newMap: Map) { + static renderStickyLines(entry: OutlineEntry | undefined, containerElement: HTMLElement, numLinesToRender: number, newMap: Map, notebookEditor: INotebookEditor) { const partial = false; let currentEntry = entry; const elementsToRender = []; while (currentEntry) { if (currentEntry.level === 7) { - // level 7 represents a comment in python, which we don't want to render + // level 7 represents a non-header entry, which we don't want to render currentEntry = currentEntry.parent; continue; } - const lineToRender = this.createStickyElement(currentEntry, partial); - newMap.set(currentEntry, lineToRender); + const lineToRender = NotebookStickyScroll.createStickyElement(currentEntry, partial, notebookEditor); + newMap.set(currentEntry, { line: lineToRender, rendered: false }); elementsToRender.unshift(lineToRender); currentEntry = currentEntry.parent; } @@ -423,33 +312,128 @@ export class NotebookStickyScroll extends Disposable { break; } containerElement.append(elementsToRender[i].element); + newMap.set(elementsToRender[i].entry, { line: elementsToRender[i], rendered: true }); } containerElement.append(DOM.$('div', { class: 'notebook-shadow' })); // ensure we have dropShadow at base of sticky scroll return newMap; } - private createStickyElement(entry: OutlineEntry, partial: boolean) { + static createStickyElement(entry: OutlineEntry, partial: boolean, notebookEditor: INotebookEditor) { const stickyElement = document.createElement('div'); stickyElement.classList.add('notebook-sticky-scroll-line'); stickyElement.innerText = '#'.repeat(entry.level) + ' ' + entry.label; - // todo: partial line rendering for animater - if (partial) { - // const partialHeight = Math.floor(remainder * 22); - // stickyLine.style.height = `${partialHeight}px`; - } + // todo: partial line rendering for animation + // if (partial) { + // const partialHeight = Math.floor(remainder * 22); + // stickyLine.style.height = `${partialHeight}px`; + // } - return new NotebookStickyLine(stickyElement, entry, this.notebookEditor); + return new NotebookStickyLine(stickyElement, entry, notebookEditor); + } + + private disposeCurrentStickyLines() { + this.currentStickyLines.forEach((value) => { + value.line.dispose(); + }); } override dispose() { this._disposables.dispose(); - this.currentStickyLines.forEach((value) => { - value.dispose(); - }); + this.disposeCurrentStickyLines(); super.dispose(); } } +export function computeContent(domNode: HTMLElement, notebookEditor: INotebookEditor, notebookCellList: INotebookCellList, notebookOutlineEntries: OutlineEntry[]): Map { + // find first code cell in visible range. this marks the start of the first section + // find the last code cell in the first section of the visible range, store the bottom scroll position in a const sectionBottom + // compute sticky scroll height, and check if editorScrolltop + stickyScrollHeight < sectionBottom + // if that condition is true, break out of the loop with that cell as the tracked cell + // if that condition is false, continue to next cell + + const editorScrollTop = notebookEditor.scrollTop; + + // find last code cell of section, store bottom scroll position in sectionBottom + const visibleRange = notebookEditor.visibleRanges[0]; + if (!visibleRange) { + return new Map(); + } + + let trackedEntry = undefined; + let sectionBottom = 0; + for (let i = visibleRange.start; i < visibleRange.end; i++) { + if (i === 0) { // don't show headers when you're viewing the top cell + return new Map(); + } + const cell = notebookEditor.cellAt(i); + if (!cell) { + return new Map(); + } + if (cell.cellKind === CellKind.Markup) { + continue; + } + + // if we are here, the cell is a code cell. + // check next cell, if markdown, that means this is the end of the section + const nextVisibleCell = notebookEditor.cellAt(i + 1); + if (nextVisibleCell && i + 1 < visibleRange.end) { + if (nextVisibleCell.cellKind === CellKind.Markup) { + // this is the end of the section + // store the bottom scroll position of this cell + sectionBottom = notebookCellList.getCellViewScrollBottom(cell); + // compute sticky scroll height + const entry = NotebookStickyScroll.getVisibleOutlineEntry(i, notebookOutlineEntries); + if (!entry) { + return new Map(); + } + // check if we can render this section of sticky + const currentSectionStickyHeight = NotebookStickyScroll.computeStickyHeight(entry!); + if (editorScrollTop + currentSectionStickyHeight < sectionBottom) { + const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); + let newMap: Map = new Map(); + newMap = NotebookStickyScroll.renderStickyLines(entry?.parent, domNode, linesToRender, newMap, notebookEditor); + return newMap; + } + + let nextSectionEntry = undefined; + for (let j = 1; j < visibleRange.end - i; j++) { + // find next code cell after this one + const cellCheck = notebookEditor.cellAt(i + j); + if (cellCheck && cellCheck.cellKind === CellKind.Code) { + nextSectionEntry = NotebookStickyScroll.getVisibleOutlineEntry(i + j, notebookOutlineEntries); + break; + } + } + const nextSectionStickyHeight = NotebookStickyScroll.computeStickyHeight(nextSectionEntry!); + + // this block of logic cleans transitions between two sections that share a parent. + // if the current section and the next section share a parent, then we can render the next section's sticky lines to avoid pop-in between + if (entry?.parent?.parent === nextSectionEntry?.parent) { + const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22) + 1; + let newMap: Map = new Map(); + newMap = NotebookStickyScroll.renderStickyLines(nextSectionEntry?.parent, domNode, linesToRender, newMap, notebookEditor); + return newMap; + } else if (Math.abs(currentSectionStickyHeight - nextSectionStickyHeight) > 22) { // only shrink sticky + const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); + let newMap: Map = new Map(); + newMap = NotebookStickyScroll.renderStickyLines(entry?.parent, domNode, linesToRender, newMap, notebookEditor); + return newMap; + } + } + } else { + // there is no next cell, so use the bottom of the editor as the sectionBottom, using scrolltop + height + sectionBottom = notebookEditor.getLayoutInfo().scrollHeight; + trackedEntry = NotebookStickyScroll.getVisibleOutlineEntry(i, notebookOutlineEntries); + const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); + + let newMap: Map = new Map(); + newMap = NotebookStickyScroll.renderStickyLines(trackedEntry?.parent, domNode, linesToRender, newMap, notebookEditor); + return newMap; + } + } // for cell loop close + return new Map(); +} + registerAction2(ToggleNotebookStickyScroll); diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test0__should_render_empty___scrollTop_at_0_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test0__should_render_empty___scrollTop_at_0_0.snap new file mode 100644 index 00000000000..f6ffad5cb32 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test0__should_render_empty___scrollTop_at_0_0.snap @@ -0,0 +1 @@ +[ ] \ No newline at end of file diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test1__should_render_0-_1___visible_range_3-_8_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test1__should_render_0-_1___visible_range_3-_8_0.snap new file mode 100644 index 00000000000..1bcf0a58d43 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test1__should_render_0-_1___visible_range_3-_8_0.snap @@ -0,0 +1 @@ +[ "# header a", "## header aa" ] \ No newline at end of file diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test2__should_render_0____visible_range_6-_9_so_collapsing_next_2_against_following_section_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test2__should_render_0____visible_range_6-_9_so_collapsing_next_2_against_following_section_0.snap new file mode 100644 index 00000000000..3f23335f240 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test2__should_render_0____visible_range_6-_9_so_collapsing_next_2_against_following_section_0.snap @@ -0,0 +1 @@ +[ "# header a" ] \ No newline at end of file diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_third_header_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_third_header_0.snap new file mode 100644 index 00000000000..1bcf0a58d43 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_third_header_0.snap @@ -0,0 +1 @@ +[ "# header a", "## header aa" ] \ No newline at end of file diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test4__should_render_0____scrolltop_halfway_through_cell_0_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test4__should_render_0____scrolltop_halfway_through_cell_0_0.snap new file mode 100644 index 00000000000..3f23335f240 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test4__should_render_0____scrolltop_halfway_through_cell_0_0.snap @@ -0,0 +1 @@ +[ "# header a" ] \ No newline at end of file diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test5__should_render_0-_2___scrolltop_halfway_through_cell_2_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test5__should_render_0-_2___scrolltop_halfway_through_cell_2_0.snap new file mode 100644 index 00000000000..cf5583b0ab9 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test5__should_render_0-_2___scrolltop_halfway_through_cell_2_0.snap @@ -0,0 +1 @@ +[ "# header a", "## header aa", "### header aaa" ] diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test6__should_render_6-_7___scrolltop_halfway_through_cell_7_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test6__should_render_6-_7___scrolltop_halfway_through_cell_7_0.snap new file mode 100644 index 00000000000..77fe21fe781 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test6__should_render_6-_7___scrolltop_halfway_through_cell_7_0.snap @@ -0,0 +1 @@ +[ "# header b", "## header bb" ] \ No newline at end of file diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test7__should_render_0-_1___collapsing_against_next_section_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test7__should_render_0-_1___collapsing_against_next_section_0.snap new file mode 100644 index 00000000000..1bcf0a58d43 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test7__should_render_0-_1___collapsing_against_next_section_0.snap @@ -0,0 +1 @@ +[ "# header a", "## header aa" ] \ No newline at end of file diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts new file mode 100644 index 00000000000..46bd58ded14 --- /dev/null +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts @@ -0,0 +1,369 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { Event } from 'vs/base/common/event'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { mock } from 'vs/base/test/common/mock'; +import { assertSnapshot } from 'vs/base/test/common/snapshot'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { NotebookCellOutline } from 'vs/workbench/contrib/notebook/browser/contrib/outline/notebookOutline'; +import { INotebookEditor, INotebookEditorPane } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; +import { INotebookCellList } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon'; +import { OutlineEntry } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider'; +import { NotebookStickyLine, computeContent } from 'vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll'; +import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; +import { createNotebookCellList, setupInstantiationService, withTestNotebook } from 'vs/workbench/contrib/notebook/test/browser/testNotebookEditor'; +import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline'; + + +suite('NotebookEditorStickyScroll', () => { + + let disposables: DisposableStore; + let instantiationService: TestInstantiationService; + + const domNode: HTMLElement = document.createElement('div'); + + suiteSetup(() => { + disposables = new DisposableStore(); + instantiationService = setupInstantiationService(disposables); + }); + + suiteTeardown(() => disposables.dispose()); + + function getOutline(editor: any) { + if (!editor.hasModel()) { + assert.ok(false, 'MUST have active text editor'); + } + const outline = instantiationService.createInstance(NotebookCellOutline, new class extends mock() { + override getControl() { + return editor; + } + override onDidChangeModel: Event = Event.None; + }, OutlineTarget.QuickPick); + return outline; + } + + function nbStickyTestHelper(domNode: HTMLElement, notebookEditor: INotebookEditor, notebookCellList: INotebookCellList, notebookOutlineEntries: OutlineEntry[]) { + const output = computeContent(domNode, notebookEditor, notebookCellList, notebookOutlineEntries); + return createStickyTestElement(output.values()); + } + + function createStickyTestElement(stickyLines: IterableIterator<{ line: NotebookStickyLine; rendered: boolean }>) { + const outputElements = []; + for (const stickyLine of stickyLines) { + if (stickyLine.rendered) { + outputElements.unshift(stickyLine.line.element.innerText); + } + } + return outputElements; + } + + test('test0: should render empty, scrollTop at 0', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], + ['## header aa', 'markdown', CellKind.Markup, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['# header b', 'markdown', CellKind.Markup, [], {}], + ['var c = 2;', 'javascript', CellKind.Code, [], {}] + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 8 }, () => false), + editorViewStates: Array.from({ length: 8 }, () => null), + cellTotalHeights: Array.from({ length: 8 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(0); + editor.visibleRanges = [{ start: 0, end: 8 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + test('test1: should render 0->1, visible range 3->8', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], // 0 + ['## header aa', 'markdown', CellKind.Markup, [], {}], // 50 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 100 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 150 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 200 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 250 + ['# header b', 'markdown', CellKind.Markup, [], {}], // 300 + ['var c = 2;', 'javascript', CellKind.Code, [], {}] // 350 + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 8 }, () => false), + editorViewStates: Array.from({ length: 8 }, () => null), + cellTotalHeights: Array.from({ length: 8 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(175); + editor.visibleRanges = [{ start: 3, end: 8 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + test('test2: should render 0, visible range 6->9 so collapsing next 2 against following section', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], // 0 + ['## header aa', 'markdown', CellKind.Markup, [], {}], // 50 + ['### header aaa', 'markdown', CellKind.Markup, [], {}],// 100 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 150 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 200 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 250 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 300 + ['# header b', 'markdown', CellKind.Markup, [], {}], // 350 + ['var c = 2;', 'javascript', CellKind.Code, [], {}] // 400 + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 9 }, () => false), + editorViewStates: Array.from({ length: 9 }, () => null), + cellTotalHeights: Array.from({ length: 9 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(325); // room for a single header + editor.visibleRanges = [{ start: 6, end: 9 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + // waiting on behavior push to fix this. + test.skip('test3: should render 0->1, collapsing against equivalent level header', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], // 0 + ['## header aa', 'markdown', CellKind.Markup, [], {}], // 50 + ['### header aaa', 'markdown', CellKind.Markup, [], {}],// 100 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 150 + ['### header aab', 'markdown', CellKind.Markup, [], {}],// 200 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 250 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 300 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], // 350 + ['# header b', 'markdown', CellKind.Markup, [], {}], // 400 + ['var c = 2;', 'javascript', CellKind.Code, [], {}] // 450 + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 10 }, () => false), + editorViewStates: Array.from({ length: 10 }, () => null), + cellTotalHeights: Array.from({ length: 10 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(175); // room for a single header + editor.visibleRanges = [{ start: 3, end: 10 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + // waiting on behavior push to fix this. + test.skip('test4: should render 0, scrolltop halfway through cell 0', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], + ['## header aa', 'markdown', CellKind.Markup, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['# header b', 'markdown', CellKind.Markup, [], {}], + ['var c = 2;', 'javascript', CellKind.Code, [], {}] + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 8 }, () => false), + editorViewStates: Array.from({ length: 8 }, () => null), + cellTotalHeights: Array.from({ length: 8 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(25); + editor.visibleRanges = [{ start: 0, end: 8 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + // waiting on behavior push to fix this. + test.skip('test5: should render 0->2, scrolltop halfway through cell 2', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], + ['## header aa', 'markdown', CellKind.Markup, [], {}], + ['### header aaa', 'markdown', CellKind.Markup, [], {}], + ['#### header aaaa', 'markdown', CellKind.Markup, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['# header b', 'markdown', CellKind.Markup, [], {}], + ['var c = 2;', 'javascript', CellKind.Code, [], {}] + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 10 }, () => false), + editorViewStates: Array.from({ length: 10 }, () => null), + cellTotalHeights: Array.from({ length: 10 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(125); + editor.visibleRanges = [{ start: 2, end: 10 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + // waiting on behavior push to fix this. + test.skip('test6: should render 6->7, scrolltop halfway through cell 7', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], + ['## header aa', 'markdown', CellKind.Markup, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['var b = 1;', 'javascript', CellKind.Code, [], {}], + ['# header b', 'markdown', CellKind.Markup, [], {}], + ['## header bb', 'markdown', CellKind.Markup, [], {}], + ['### header bbb', 'markdown', CellKind.Markup, [], {}], + ['var c = 2;', 'javascript', CellKind.Code, [], {}] + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 10 }, () => false), + editorViewStates: Array.from({ length: 10 }, () => null), + cellTotalHeights: Array.from({ length: 10 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(375); + editor.visibleRanges = [{ start: 7, end: 10 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + // waiting on behavior push to fix this. + test.skip('test7: should render 0->1, collapsing against next section', async function () { + await withTestNotebook( + [ + ['# header a', 'markdown', CellKind.Markup, [], {}], //0 + ['## header aa', 'markdown', CellKind.Markup, [], {}], //50 + ['### header aaa', 'markdown', CellKind.Markup, [], {}], //100 + ['#### header aaaa', 'markdown', CellKind.Markup, [], {}], //150 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], //200 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], //250 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], //300 + ['var b = 1;', 'javascript', CellKind.Code, [], {}], //350 + ['# header b', 'markdown', CellKind.Markup, [], {}], //400 + ['## header bb', 'markdown', CellKind.Markup, [], {}], //450 + ['### header bbb', 'markdown', CellKind.Markup, [], {}], + ['var c = 2;', 'javascript', CellKind.Code, [], {}] + ], + async (editor, viewModel) => { + viewModel.restoreEditorViewState({ + editingCells: Array.from({ length: 12 }, () => false), + editorViewStates: Array.from({ length: 12 }, () => null), + cellTotalHeights: Array.from({ length: 12 }, () => 50), + cellLineNumberStates: {}, + collapsedInputCells: {}, + collapsedOutputCells: {}, + }); + + const cellList = createNotebookCellList(instantiationService); + cellList.attachViewModel(viewModel); + cellList.layout(400, 100); + + editor.setScrollTop(350); + editor.visibleRanges = [{ start: 7, end: 12 }]; + + const notebookOutlineEntries = getOutline(editor).entries; + const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); + + await assertSnapshot(resultingMap); + }); + }); + + +}); diff --git a/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts b/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts index 54cdf355fcf..c7bcfcf6d3b 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/testNotebookEditor.ts @@ -42,7 +42,7 @@ import { IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/work import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { EditorModel } from 'vs/workbench/common/editor/editorModel'; import { CellFindMatchWithIndex, IActiveNotebookEditorDelegate, IBaseCellEditorOptions, ICellViewModel, INotebookEditorDelegate } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; -import { NotebookCellStateChangedEvent } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents'; +import { NotebookCellStateChangedEvent, NotebookLayoutInfo } from 'vs/workbench/contrib/notebook/browser/notebookViewEvents'; import { NotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/browser/services/notebookCellStatusBarServiceImpl'; import { ListViewInfoAccessor, NotebookCellList } from 'vs/workbench/contrib/notebook/browser/view/notebookCellList'; import { BaseCellRenderTemplate } from 'vs/workbench/contrib/notebook/browser/view/notebookRenderingCommon'; @@ -61,6 +61,8 @@ import { IWorkingCopySaveEvent } from 'vs/workbench/services/workingCopy/common/ import { TestWorkspaceTrustRequestService } from 'vs/workbench/services/workspaces/test/common/testWorkspaceTrustService'; import { TestLayoutService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; +import { FontInfo } from 'vs/editor/common/config/fontInfo'; +import { EditorFontLigatures, EditorFontVariations } from 'vs/editor/common/config/editorOptions'; export class TestCell extends NotebookCellTextModel { constructor( @@ -218,6 +220,8 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic cellList.attachViewModel(viewModel); const listViewInfoAccessor = new ListViewInfoAccessor(cellList); + let visibleRanges: ICellRange[] = [{ start: 0, end: 100 }]; + const notebookEditor: IActiveNotebookEditorDelegate = new class extends mock() { override dispose() { viewModel.dispose(); @@ -289,8 +293,48 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic } override deltaCellDecorations() { return []; } override onDidChangeVisibleRanges = Event.None; - override visibleRanges: ICellRange[] = [{ start: 0, end: 100 }]; + + override get visibleRanges() { + return visibleRanges; + } + + override set visibleRanges(_ranges: ICellRange[]) { + visibleRanges = _ranges; + } + override getId(): string { return ''; } + override setScrollTop(scrollTop: number): void { + cellList.scrollTop = scrollTop; + } + override get scrollTop(): number { + return cellList.scrollTop; + } + override getLayoutInfo(): NotebookLayoutInfo { + return { + width: 0, + height: 0, + scrollHeight: cellList.getScrollHeight(), + fontInfo: new FontInfo({ + pixelRatio: 1, + fontFamily: 'mockFont', + fontWeight: 'normal', + fontSize: 14, + fontFeatureSettings: EditorFontLigatures.OFF, + fontVariationSettings: EditorFontVariations.OFF, + lineHeight: 19, + letterSpacing: 1.5, + isMonospace: true, + typicalHalfwidthCharacterWidth: 10, + typicalFullwidthCharacterWidth: 20, + canUseHalfwidthRightwardsArrow: true, + spaceWidth: 10, + middotWidth: 10, + wsmiddotWidth: 10, + maxDigitWidth: 10, + }, true), + stickyHeight: 0 + }; + } }; return { editor: notebookEditor, viewModel }; @@ -345,7 +389,11 @@ export async function withTestNotebookDiffModel(originalCells: [source: return res; } -export async function withTestNotebook(cells: [source: string, lang: string, kind: CellKind, output?: IOutputDto[], metadata?: NotebookCellMetadata][], callback: (editor: IActiveNotebookEditorDelegate, viewModel: NotebookViewModel, accessor: TestInstantiationService) => Promise | R, accessor?: TestInstantiationService): Promise { +interface IActiveTestNotebookEditorDelegate extends IActiveNotebookEditorDelegate { + visibleRanges: ICellRange[]; +} + +export async function withTestNotebook(cells: [source: string, lang: string, kind: CellKind, output?: IOutputDto[], metadata?: NotebookCellMetadata][], callback: (editor: IActiveTestNotebookEditorDelegate, viewModel: NotebookViewModel, accessor: TestInstantiationService) => Promise | R, accessor?: TestInstantiationService): Promise { const disposables = new DisposableStore(); const instantiationService = accessor ?? setupInstantiationService(disposables); const notebookEditor = _createTestNotebookEditor(instantiationService, cells); From 3d1cf4c6ae0692ba5b8ab515640d521b3cae2df0 Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Mon, 28 Aug 2023 15:00:41 -0700 Subject: [PATCH 046/198] Fix trustOption string content (#191525) --- .../contrib/workspace/browser/workspace.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts index a488d01724c..077b248bc0f 100644 --- a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts +++ b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts @@ -319,7 +319,7 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon titleString = this.productService.aiGeneratedWorkspaceTrust.title; checkboxString = this.productService.aiGeneratedWorkspaceTrust.checkboxText; learnMoreString = this.productService.aiGeneratedWorkspaceTrust.startupTrustRequestLearnMore; - trustOption = this.productService.aiGeneratedWorkspaceTrust.startupTrustRequestLearnMore; + trustOption = this.productService.aiGeneratedWorkspaceTrust.trustOption; dontTrustOption = this.productService.aiGeneratedWorkspaceTrust.dontTrustOption; } else { console.warn('AI generated workspace trust dialog contents not available.'); From e50a22d888b8552f9f1237520ab4e0212d5b72ea Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 28 Aug 2023 15:09:44 -0700 Subject: [PATCH 047/198] React to window resize and remove hardcoded maxHeight in Quick Chat (#191531) more Quick Chat polish --- .../contrib/chat/browser/chatQuick.ts | 17 +++++++++---- .../contrib/chat/browser/chatWidget.ts | 24 +++++++++++++++++-- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index 76bea4666b7..e30fdf3ca0d 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -11,6 +11,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; +import { ILayoutService } from 'vs/platform/layout/browser/layoutService'; import { IQuickInputService, IQuickWidget } from 'vs/platform/quickinput/common/quickInput'; import { inputBackground, quickInputBackground, quickInputForeground } from 'vs/platform/theme/common/colorRegistry'; import { IChatWidgetService, IQuickChatService } from 'vs/workbench/contrib/chat/browser/chat'; @@ -121,7 +122,7 @@ export class QuickChatService extends Disposable implements IQuickChatService { class QuickChat extends Disposable { // TODO@TylerLeonhardt: be responsive to window size static DEFAULT_MIN_HEIGHT = 200; - static DEFAULT_MAX_HEIGHT = 900; + private static readonly DEFAULT_HEIGHT_OFFSET = 100; private widget!: ChatWidget; private sash!: Sash; @@ -133,7 +134,8 @@ class QuickChat extends Disposable { @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextKeyService private readonly contextKeyService: IContextKeyService, @IChatService private readonly chatService: IChatService, - @IChatWidgetService private readonly _chatWidgetService: IChatWidgetService + @IChatWidgetService private readonly _chatWidgetService: IChatWidgetService, + @ILayoutService private readonly layoutService: ILayoutService ) { super(); } @@ -182,13 +184,20 @@ class QuickChat extends Disposable { })); this.widget.render(parent); this.widget.setVisible(true); - this.widget.setDynamicChatTreeItemLayout(2, QuickChat.DEFAULT_MAX_HEIGHT); + this.widget.setDynamicChatTreeItemLayout(2, this.maxHeight); this.updateModel(); this.sash = this._register(new Sash(parent, { getHorizontalSashTop: () => parent.offsetHeight }, { orientation: Orientation.HORIZONTAL })); this.registerListeners(parent); } + private get maxHeight(): number { + return this.layoutService.dimension.height - QuickChat.DEFAULT_HEIGHT_OFFSET; + } + private registerListeners(parent: HTMLElement): void { + this._register(this.layoutService.onDidLayout(() => { + this.widget.updateDynamicChatTreeItemLayout(2, this.maxHeight); + })); this._register(this.widget.inputEditor.onDidChangeModelContent((e) => { this._currentQuery = this.widget.inputEditor.getValue(); })); @@ -196,7 +205,7 @@ class QuickChat extends Disposable { this._register(this.widget.onDidChangeHeight((e) => this.sash.layout())); const width = parent.offsetWidth; this._register(this.sash.onDidChange((e) => { - if (e.currentY < QuickChat.DEFAULT_MIN_HEIGHT || e.currentY > QuickChat.DEFAULT_MAX_HEIGHT) { + if (e.currentY < QuickChat.DEFAULT_MIN_HEIGHT || e.currentY > this.maxHeight) { return; } this.widget.layout(e.currentY, width); diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 500ff2b372b..6e1d8b3df5e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -546,14 +546,34 @@ export class ChatWidget extends Disposable implements IChatWidget { return; } - const newHeight = Math.min(renderHeight + diff, maxHeight); + const possibleMaxHeight = (this._dynamicMessageLayoutData?.maxHeight ?? maxHeight); const width = this.bodyDimension?.width ?? this.container.offsetWidth; - const inputPartHeight = this.inputPart.layout(newHeight, width); + const inputPartHeight = this.inputPart.layout(possibleMaxHeight, width); + const newHeight = Math.min(renderHeight + diff, possibleMaxHeight - inputPartHeight); this.layout(newHeight + inputPartHeight, width); }); })); } + updateDynamicChatTreeItemLayout(numOfChatTreeItems: number, maxHeight: number) { + this._dynamicMessageLayoutData = { numOfMessages: numOfChatTreeItems, maxHeight }; + let hasChanged = false; + let height = this.bodyDimension!.height; + let width = this.bodyDimension!.width; + if (maxHeight < this.bodyDimension!.height) { + height = maxHeight; + hasChanged = true; + } + const containerWidth = this.container.offsetWidth; + if (this.bodyDimension?.width !== containerWidth) { + width = containerWidth; + hasChanged = true; + } + if (hasChanged) { + this.layout(height, width); + } + } + layoutDynamicChatTreeItemMode(): void { if (!this.viewModel) { return; From de17d483b24a3a86581e0b2a5abd8c4454495730 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 28 Aug 2023 15:50:21 -0700 Subject: [PATCH 048/198] Have sash take over layouting of Quick Chat until reset (double click) (#191533) The new behavior is that when you use the sash to change the height, then you are locked into that. It's not until you double click, or clear the chat that it returns to the original behavior of being open for just the last question. --- .../contrib/chat/browser/chatQuick.ts | 7 ++++++ .../contrib/chat/browser/chatWidget.ts | 23 +++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index e30fdf3ca0d..03420bc79b4 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -204,6 +204,9 @@ class QuickChat extends Disposable { this._register(this.widget.onDidClear(() => this.clear())); this._register(this.widget.onDidChangeHeight((e) => this.sash.layout())); const width = parent.offsetWidth; + this._register(this.sash.onDidStart(() => { + this.widget.isDynamicChatTreeItemLayoutEnabled = false; + })); this._register(this.sash.onDidChange((e) => { if (e.currentY < QuickChat.DEFAULT_MIN_HEIGHT || e.currentY > this.maxHeight) { return; @@ -211,6 +214,10 @@ class QuickChat extends Disposable { this.widget.layout(e.currentY, width); this.sash.layout(); })); + this._register(this.sash.onDidReset(() => { + this.widget.isDynamicChatTreeItemLayoutEnabled = true; + this.widget.layoutDynamicChatTreeItemMode(); + })); } async acceptInput(): Promise { diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 6e1d8b3df5e..7e65ed72d20 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -207,6 +207,9 @@ export class ChatWidget extends Disposable implements IChatWidget { } clear(): void { + if (this._dynamicMessageLayoutData) { + this._dynamicMessageLayoutData.enabled = true; + } this._onDidClear.fire(); } @@ -525,13 +528,14 @@ export class ChatWidget extends Disposable implements IChatWidget { this._onDidChangeHeight.fire(height); } - private _dynamicMessageLayoutData?: { numOfMessages: number; maxHeight: number }; + private _dynamicMessageLayoutData?: { numOfMessages: number; maxHeight: number; enabled: boolean }; // An alternative to layout, this allows you to specify the number of ChatTreeItems // you want to show, and the max height of the container. It will then layout the // tree to show that many items. + // TODO@TylerLeonhardt: This could use some refactoring to make it clear which layout strategy is being used setDynamicChatTreeItemLayout(numOfChatTreeItems: number, maxHeight: number) { - this._dynamicMessageLayoutData = { numOfMessages: numOfChatTreeItems, maxHeight }; + this._dynamicMessageLayoutData = { numOfMessages: numOfChatTreeItems, maxHeight, enabled: true }; this._register(this.renderer.onDidChangeItemHeight(() => this.layoutDynamicChatTreeItemMode())); const mutableDisposable = this._register(new MutableDisposable()); @@ -556,7 +560,7 @@ export class ChatWidget extends Disposable implements IChatWidget { } updateDynamicChatTreeItemLayout(numOfChatTreeItems: number, maxHeight: number) { - this._dynamicMessageLayoutData = { numOfMessages: numOfChatTreeItems, maxHeight }; + this._dynamicMessageLayoutData = { numOfMessages: numOfChatTreeItems, maxHeight, enabled: true }; let hasChanged = false; let height = this.bodyDimension!.height; let width = this.bodyDimension!.width; @@ -574,8 +578,19 @@ export class ChatWidget extends Disposable implements IChatWidget { } } + get isDynamicChatTreeItemLayoutEnabled(): boolean { + return this._dynamicMessageLayoutData?.enabled ?? false; + } + + set isDynamicChatTreeItemLayoutEnabled(value: boolean) { + if (!this._dynamicMessageLayoutData) { + return; + } + this._dynamicMessageLayoutData.enabled = value; + } + layoutDynamicChatTreeItemMode(): void { - if (!this.viewModel) { + if (!this.viewModel || !this._dynamicMessageLayoutData?.enabled) { return; } const inputHeight = this.inputPart.layout(this._dynamicMessageLayoutData!.maxHeight, this.container.offsetWidth); From 4a6352a816da125e250b736bcb4924ce6428e32b Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Mon, 28 Aug 2023 15:54:00 -0700 Subject: [PATCH 049/198] Remove toolbar button to @-mention a response (#191534) --- .../chat/browser/actions/chatTitleActions.ts | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts index 1b26cbba32b..19bd054e7b8 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts @@ -104,44 +104,6 @@ export function registerChatTitleActions() { } }); - registerAction2(class MentionAction extends Action2 { - constructor() { - super({ - id: 'workbench.action.chat.mention', - title: { - value: localize('interactive.mention.label', "Mention"), - original: 'Mention' - }, - f1: false, - category: CHAT_CATEGORY, - icon: Codicon.add, - menu: { - id: MenuId.ChatMessageTitle, - group: 'navigation', - order: 3, - when: CONTEXT_RESPONSE - } - }); - } - - run(accessor: ServicesAccessor, ...args: any[]) { - const item = args[0]; - if (!isResponseVM(item)) { - return; - } - - const chatWidgetService = accessor.get(IChatWidgetService); - const widget = chatWidgetService.lastFocusedWidget!; - const num = widget.viewModel!.getItems() - .filter(isResponseVM) - .indexOf(item) + 1; - widget.inputEditor.setValue(`${widget.inputEditor.getValue()} @response:${num} `); - const lastLine = widget.inputEditor.getModel()!.getLineCount(); - const lastCol = widget.inputEditor.getModel()!.getLineLength(lastLine); - widget.inputEditor.setSelection({ startColumn: lastCol, endColumn: lastCol, startLineNumber: lastLine, endLineNumber: lastLine }); - } - }); - registerAction2(class InsertToNotebookAction extends Action2 { constructor() { super({ From 3af6e2b9d18c5d92d212f377d57195996fbdc3e2 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Mon, 28 Aug 2023 16:25:14 -0700 Subject: [PATCH 050/198] behavior fixes, align more closely with editor --- .../viewParts/notebookEditorStickyScroll.ts | 92 +++++++++++++------ 1 file changed, 63 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts index 7b490223afd..414acaa14be 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts @@ -79,6 +79,16 @@ export class NotebookStickyLine extends Disposable { } } +// TODO @Yoyokrazy: +// BEHAVIOR +// - [ ] bug with some popping around the cell transition +// - [ ] bug with only bottom most sticky being partially transitioned +// - partial rendering/transition only occuring when the headers shrink against a new section +// - **and only for BOTTOM of that initial sticky tree** +// - issues with HC themes +// UX +// - [ ] render symbols instead of #'s? +// - maybe 'Hx >' where x is the level export class NotebookStickyScroll extends Disposable { private readonly _disposables = new DisposableStore(); private currentStickyLines = new Map(); @@ -178,7 +188,10 @@ export class NotebookStickyScroll extends Disposable { while (left <= right) { const mid = Math.floor((left + right) / 2); - if (notebookOutlineEntries[mid].index < visibleIndex) { + if (notebookOutlineEntries[mid].index === visibleIndex) { + bucket = mid; + break; + } else if (notebookOutlineEntries[mid].index < visibleIndex) { bucket = mid; left = mid + 1; } else { @@ -218,15 +231,13 @@ export class NotebookStickyScroll extends Disposable { if (!cell) { return; } - if (cell.cellKind === CellKind.Markup) { - continue; - } // if we are here, the cell is a code cell. - // check next visible cell, if markdown, that means this is the end of the section - const nextVisibleCell = this.notebookEditor.cellAt(i + 1); - if (nextVisibleCell && i + 1 < visibleRange.end) { - if (nextVisibleCell.cellKind === CellKind.Markup) { + // check next cell, if markdown, that means this is the end of the section + // check if cell is within visible range + const nextCell = this.notebookEditor.cellAt(i + 1); + if (nextCell && i + 1 < visibleRange.end) { + if (nextCell.cellKind === CellKind.Markup) { // this is the end of the section // store the bottom scroll position of this cell sectionBottom = this.notebookCellList.getCellViewScrollBottom(cell); @@ -281,6 +292,9 @@ export class NotebookStickyScroll extends Disposable { static computeStickyHeight(entry: OutlineEntry) { let height = 0; + if (entry.cell.cellKind === CellKind.Markup) { + height += 22; + } while (entry.parent) { height += 22; entry = entry.parent; @@ -289,7 +303,6 @@ export class NotebookStickyScroll extends Disposable { } static renderStickyLines(entry: OutlineEntry | undefined, containerElement: HTMLElement, numLinesToRender: number, newMap: Map, notebookEditor: INotebookEditor) { - const partial = false; let currentEntry = entry; const elementsToRender = []; @@ -299,12 +312,24 @@ export class NotebookStickyScroll extends Disposable { currentEntry = currentEntry.parent; continue; } - const lineToRender = NotebookStickyScroll.createStickyElement(currentEntry, partial, notebookEditor); + const lineToRender = NotebookStickyScroll.createStickyElement(currentEntry, notebookEditor); newMap.set(currentEntry, { line: lineToRender, rendered: false }); elementsToRender.unshift(lineToRender); currentEntry = currentEntry.parent; } + // TODO: clean up partial cell animation + // [ ] slight pop as lines finish disappearing + // [ ] only actually works when shrunk against new section. **and only for BOTTOM of that initial sticky tree** + // [ ] issues with HC themes + // use negative margins to render the bottom sticky line as a partial element + // todo: partial render logic here + // if (numLinesToRender % 1 !== 0) { + // const partialHeight = 22 - Math.floor((numLinesToRender % 1) * 22); + // elementsToRender[elementsToRender.length - 1].element.style.zIndex = '-1'; + // elementsToRender[elementsToRender.length - 1].element.style.marginTop = `-${partialHeight}px`; + // } + // iterate over elements to render, and append to container // break when we reach numLinesToRender for (let i = 0; i < elementsToRender.length; i++) { @@ -319,17 +344,10 @@ export class NotebookStickyScroll extends Disposable { return newMap; } - static createStickyElement(entry: OutlineEntry, partial: boolean, notebookEditor: INotebookEditor) { + static createStickyElement(entry: OutlineEntry, notebookEditor: INotebookEditor) { const stickyElement = document.createElement('div'); stickyElement.classList.add('notebook-sticky-scroll-line'); stickyElement.innerText = '#'.repeat(entry.level) + ' ' + entry.label; - - // todo: partial line rendering for animation - // if (partial) { - // const partialHeight = Math.floor(remainder * 22); - // stickyLine.style.height = `${partialHeight}px`; - // } - return new NotebookStickyLine(stickyElement, entry, notebookEditor); } @@ -364,15 +382,26 @@ export function computeContent(domNode: HTMLElement, notebookEditor: INotebookEd let trackedEntry = undefined; let sectionBottom = 0; for (let i = visibleRange.start; i < visibleRange.end; i++) { - if (i === 0) { // don't show headers when you're viewing the top cell - return new Map(); - } const cell = notebookEditor.cellAt(i); if (!cell) { return new Map(); } + + // account for transitions between top level headers if (cell.cellKind === CellKind.Markup) { - continue; + sectionBottom = notebookCellList.getCellViewScrollBottom(cell); + const entry = NotebookStickyScroll.getVisibleOutlineEntry(i, notebookOutlineEntries); + if (!entry) { + return new Map(); + } + + if (!entry.parent) { + // if the cell is a top level header, only render once we have scrolled past the bottom of the cell + // todo: (polish) figure out what padding value to use here. need to account properly for bottom insert cell toolbar, cell toolbar, and md cell bottom padding + if (sectionBottom > editorScrollTop) { + return new Map(); + } + } } // if we are here, the cell is a code cell. @@ -393,37 +422,42 @@ export function computeContent(domNode: HTMLElement, notebookEditor: INotebookEd if (editorScrollTop + currentSectionStickyHeight < sectionBottom) { const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); let newMap: Map = new Map(); - newMap = NotebookStickyScroll.renderStickyLines(entry?.parent, domNode, linesToRender, newMap, notebookEditor); + newMap = NotebookStickyScroll.renderStickyLines(entry, domNode, linesToRender, newMap, notebookEditor); return newMap; } let nextSectionEntry = undefined; for (let j = 1; j < visibleRange.end - i; j++) { - // find next code cell after this one + // find next section after this one const cellCheck = notebookEditor.cellAt(i + j); - if (cellCheck && cellCheck.cellKind === CellKind.Code) { + if (cellCheck) { nextSectionEntry = NotebookStickyScroll.getVisibleOutlineEntry(i + j, notebookOutlineEntries); - break; + if (nextSectionEntry) { + break; + } } } const nextSectionStickyHeight = NotebookStickyScroll.computeStickyHeight(nextSectionEntry!); + // recompute section bottom based on the top of the next section + sectionBottom = notebookCellList.getCellViewScrollTop(nextSectionEntry!.cell) - 10; + // this block of logic cleans transitions between two sections that share a parent. // if the current section and the next section share a parent, then we can render the next section's sticky lines to avoid pop-in between if (entry?.parent?.parent === nextSectionEntry?.parent) { - const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22) + 1; + const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22) + 100; let newMap: Map = new Map(); newMap = NotebookStickyScroll.renderStickyLines(nextSectionEntry?.parent, domNode, linesToRender, newMap, notebookEditor); return newMap; } else if (Math.abs(currentSectionStickyHeight - nextSectionStickyHeight) > 22) { // only shrink sticky - const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); + const linesToRender = (sectionBottom - editorScrollTop) / 22; let newMap: Map = new Map(); newMap = NotebookStickyScroll.renderStickyLines(entry?.parent, domNode, linesToRender, newMap, notebookEditor); return newMap; } } } else { - // there is no next cell, so use the bottom of the editor as the sectionBottom, using scrolltop + height + // there is no next visible cell, so use the bottom of the editor as the sectionBottom, using scrolltop + height sectionBottom = notebookEditor.getLayoutInfo().scrollHeight; trackedEntry = NotebookStickyScroll.getVisibleOutlineEntry(i, notebookOutlineEntries); const linesToRender = Math.floor((sectionBottom - editorScrollTop) / 22); From c0c489f19111c64c05e711d809ab4c3ce32687a9 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Mon, 28 Aug 2023 17:00:51 -0700 Subject: [PATCH 051/198] behavior fixes for nb sticky scroll + css fix --- .../browser/media/notebookEditorStickyScroll.css | 10 ++++++++++ .../browser/viewParts/notebookEditorStickyScroll.ts | 7 ++++--- ...llapsing_against_equivalent_level_header_0.snap} | 0 .../test/browser/notebookStickyScroll.test.ts | 13 ++++++------- 4 files changed, 20 insertions(+), 10 deletions(-) rename src/vs/workbench/contrib/notebook/test/browser/__snapshots__/{NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_third_header_0.snap => NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_equivalent_level_header_0.snap} (100%) diff --git a/src/vs/workbench/contrib/notebook/browser/media/notebookEditorStickyScroll.css b/src/vs/workbench/contrib/notebook/browser/media/notebookEditorStickyScroll.css index 8107bfb1282..5750b20cd65 100644 --- a/src/vs/workbench/contrib/notebook/browser/media/notebookEditorStickyScroll.css +++ b/src/vs/workbench/contrib/notebook/browser/media/notebookEditorStickyScroll.css @@ -15,7 +15,17 @@ .notebookOverlay .notebook-sticky-scroll-container .notebook-sticky-scroll-line { + background-color: var(--vscode-notebook-editorBackground); + position: relative; + z-index: 0; padding-left: 12px; + /* transition: margin-top 0.2s ease-in-out; */ +} + +.monaco-workbench.hc-light .notebookOverlay .notebook-sticky-scroll-container, +.monaco-workbench.hc-black .notebookOverlay .notebook-sticky-scroll-container { + background-color: var(--vscode-editorStickyScroll-background); + border-bottom: 1px solid var(--vscode-contrastBorder); } .monaco-workbench diff --git a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts index 414acaa14be..426f767e89d 100644 --- a/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts +++ b/src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll.ts @@ -387,6 +387,8 @@ export function computeContent(domNode: HTMLElement, notebookEditor: INotebookEd return new Map(); } + const nextCell = notebookEditor.cellAt(i + 1); + // account for transitions between top level headers if (cell.cellKind === CellKind.Markup) { sectionBottom = notebookCellList.getCellViewScrollBottom(cell); @@ -406,9 +408,8 @@ export function computeContent(domNode: HTMLElement, notebookEditor: INotebookEd // if we are here, the cell is a code cell. // check next cell, if markdown, that means this is the end of the section - const nextVisibleCell = notebookEditor.cellAt(i + 1); - if (nextVisibleCell && i + 1 < visibleRange.end) { - if (nextVisibleCell.cellKind === CellKind.Markup) { + if (nextCell && i + 1 < visibleRange.end) { + if (nextCell.cellKind === CellKind.Markup) { // this is the end of the section // store the bottom scroll position of this cell sectionBottom = notebookCellList.getCellViewScrollBottom(cell); diff --git a/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_third_header_0.snap b/src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_equivalent_level_header_0.snap similarity index 100% rename from src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_third_header_0.snap rename to src/vs/workbench/contrib/notebook/test/browser/__snapshots__/NotebookEditorStickyScroll_test3__should_render_0-_1___collapsing_against_equivalent_level_header_0.snap diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts index 46bd58ded14..708b8b7aea8 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts @@ -170,8 +170,7 @@ suite('NotebookEditorStickyScroll', () => { }); }); - // waiting on behavior push to fix this. - test.skip('test3: should render 0->1, collapsing against equivalent level header', async function () { + test('test3: should render 0->1, collapsing against equivalent level header', async function () { await withTestNotebook( [ ['# header a', 'markdown', CellKind.Markup, [], {}], // 0 @@ -209,7 +208,7 @@ suite('NotebookEditorStickyScroll', () => { }); }); - // waiting on behavior push to fix this. + // outdated/improper behavior test.skip('test4: should render 0, scrolltop halfway through cell 0', async function () { await withTestNotebook( [ @@ -236,7 +235,7 @@ suite('NotebookEditorStickyScroll', () => { cellList.attachViewModel(viewModel); cellList.layout(400, 100); - editor.setScrollTop(25); + editor.setScrollTop(50); editor.visibleRanges = [{ start: 0, end: 8 }]; const notebookOutlineEntries = getOutline(editor).entries; @@ -246,7 +245,7 @@ suite('NotebookEditorStickyScroll', () => { }); }); - // waiting on behavior push to fix this. + // outdated/improper behavior test.skip('test5: should render 0->2, scrolltop halfway through cell 2', async function () { await withTestNotebook( [ @@ -285,7 +284,7 @@ suite('NotebookEditorStickyScroll', () => { }); }); - // waiting on behavior push to fix this. + // outdated/improper behavior test.skip('test6: should render 6->7, scrolltop halfway through cell 7', async function () { await withTestNotebook( [ @@ -325,7 +324,7 @@ suite('NotebookEditorStickyScroll', () => { }); // waiting on behavior push to fix this. - test.skip('test7: should render 0->1, collapsing against next section', async function () { + test('test7: should render 0->1, collapsing against next section', async function () { await withTestNotebook( [ ['# header a', 'markdown', CellKind.Markup, [], {}], //0 From 8ef696178913af8c62ae7ee1f613904395dcf34e Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Mon, 28 Aug 2023 17:48:09 -0700 Subject: [PATCH 052/198] server-web: implement secret storage provider (#191538) Works quite similarly to vscode.dev. The client has a key stored in secret storage. The server has a key stored server-side, and issues an http-only cookie to the client. The client can ask the server to combine its key and the http-only cookie key to a key component, which it combines with its local key to encrypt and decrypt data. This logic kicks in if the web server bits see a `vscode-secret-key-path` cookie set when it loads. --- cli/src/commands/serve_web.rs | 177 ++++++++++++-- cli/src/tunnels/socket_signal.rs | 2 +- src/vs/code/browser/workbench/workbench.ts | 266 ++++++++++++++++----- 3 files changed, 366 insertions(+), 79 deletions(-) diff --git a/cli/src/commands/serve_web.rs b/cli/src/commands/serve_web.rs index 4a3af432444..8d37427dd33 100644 --- a/cli/src/commands/serve_web.rs +++ b/cli/src/commands/serve_web.rs @@ -10,6 +10,7 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; +use const_format::concatcp; use hyper::service::{make_service_fn, service_fn}; use hyper::{Body, Request, Response, Server}; use tokio::io::{AsyncBufReadExt, BufReader}; @@ -23,6 +24,7 @@ use crate::constants::VSCODE_CLI_QUALITY; use crate::download_cache::DownloadCache; use crate::log; use crate::options::Quality; +use crate::state::{LauncherPaths, PersistedState}; use crate::update_service::{ unzip_downloaded_release, Platform, Release, TargetKind, UpdateService, }; @@ -48,6 +50,22 @@ const SERVER_ACTIVE_TIMEOUT_SECS: u64 = SERVER_IDLE_TIMEOUT_SECS * 24 * 30 * 12; /// How long to cache the "latest" version we get from the update service. const RELEASE_CACHE_SECS: u64 = 60 * 60; +/// Number of bytes for the secret keys. See workbench.ts for their usage. +const SECRET_KEY_BYTES: usize = 32; +/// Path to mint the key combining server and client parts. +const SECRET_KEY_MINT_PATH: &str = "/_vscode-cli/mint-key"; +/// Cookie set to the `SECRET_KEY_MINT_PATH` +const PATH_COOKIE_NAME: &str = "vscode-secret-key-path"; +/// Cookie set to the `SECRET_KEY_MINT_PATH` +const PATH_COOKIE_VALUE: &str = concatcp!( + PATH_COOKIE_NAME, + "=", + SECRET_KEY_MINT_PATH, + "; SameSite=Strict; Path=/" +); +/// HTTP-only cookie where the client's secret half is stored. +const SECRET_KEY_COOKIE_NAME: &str = "vscode-cli-secret-half"; + /// Implements the vscode "server of servers". Clients who go to the URI get /// served the latest version of the VS Code server whenever they load the /// page. The VS Code server prefixes all assets and connections it loads with @@ -69,10 +87,14 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result(service) } }; @@ -106,35 +128,82 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result, log: log::Logger, - req: Request, -) -> Result, Infallible> { - let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), cm.platform) { + server_secret_key: SecretKeyPart, +} + +/// Handler function for an inbound request +async fn handle(ctx: HandleContext, req: Request) -> Result, Infallible> { + let client_key_half = get_client_key_half(&req); + let mut res = match req.uri().path() { + SECRET_KEY_MINT_PATH => handle_secret_mint(ctx, req), + _ => handle_proxied(ctx, req).await, + }; + + append_secret_headers(&mut res, &client_key_half); + + Ok(res) +} + +async fn handle_proxied(ctx: HandleContext, req: Request) -> Response { + let release = if let Some((r, _)) = get_release_from_path(req.uri().path(), ctx.cm.platform) { r } else { - match cm.get_latest_release().await { + match ctx.cm.get_latest_release().await { Ok(r) => r, Err(e) => { - error!(log, "error getting latest version: {}", e); - return Ok(response::code_err(e)); + error!(ctx.log, "error getting latest version: {}", e); + return response::code_err(e); } } }; - Ok(match cm.get_connection(release).await { + match ctx.cm.get_connection(release).await { Ok(rw) => { if req.headers().contains_key(hyper::header::UPGRADE) { - forward_ws_req_to_server(cm.log.clone(), rw, req).await + forward_ws_req_to_server(ctx.log.clone(), rw, req).await } else { forward_http_req_to_server(rw, req).await } } Err(CodeError::ServerNotYetDownloaded) => response::wait_for_download(), Err(e) => response::code_err(e), - }) + } +} + +fn handle_secret_mint(ctx: HandleContext, req: Request) -> Response { + use sha2::{Digest, Sha256}; + + let mut hasher = Sha256::new(); + hasher.update(ctx.server_secret_key.0.as_ref()); + hasher.update(get_client_key_half(&req).0.as_ref()); + let hash = hasher.finalize(); + let hash = hash[..SECRET_KEY_BYTES].to_vec(); + response::secret_key(hash) +} + +/// Appends headers to response to maintain the secret storage of the workbench: +/// sets the `PATH_COOKIE_VALUE` so workbench.ts knows about the 'mint' endpoint, +/// and maintains the http-only cookie the client will use for cookies. +fn append_secret_headers(res: &mut Response, client_key_half: &SecretKeyPart) { + let headers = res.headers_mut(); + headers.append( + hyper::header::SET_COOKIE, + PATH_COOKIE_VALUE.parse().unwrap(), + ); + headers.append( + hyper::header::SET_COOKIE, + format!( + "{}={}; SameSite=Strict; HttpOnly; Max-Age=2592000; Path=/", + SECRET_KEY_COOKIE_NAME, + client_key_half.encode() + ) + .parse() + .unwrap(), + ); } /// Gets the release info from the VS Code path prefix, which is in the @@ -258,6 +327,77 @@ fn is_commit_hash(s: &str) -> bool { s.len() == COMMIT_HASH_LEN && s.chars().all(|c| c.is_ascii_hexdigit()) } +/// Gets a cookie from the request by name. +fn extract_cookie(req: &Request, name: &str) -> Option { + for h in req.headers().get_all(hyper::header::COOKIE) { + if let Ok(str) = h.to_str() { + for pair in str.split("; ") { + let i = match pair.find('=') { + Some(i) => i, + None => continue, + }; + + if &pair[..i] == name { + return Some(pair[i + 1..].to_string()); + } + } + } + } + + None +} + +#[derive(Clone)] +struct SecretKeyPart(Box<[u8; SECRET_KEY_BYTES]>); + +impl SecretKeyPart { + pub fn new() -> Self { + let key: [u8; SECRET_KEY_BYTES] = rand::random(); + Self(Box::new(key)) + } + + pub fn decode(s: &str) -> Result { + use base64::{engine::general_purpose, Engine as _}; + let mut key: [u8; SECRET_KEY_BYTES] = [0; SECRET_KEY_BYTES]; + let v = general_purpose::URL_SAFE.decode(s)?; + if v.len() != SECRET_KEY_BYTES { + return Err(base64::DecodeSliceError::OutputSliceTooSmall); + } + + key.copy_from_slice(&v); + Ok(Self(Box::new(key))) + } + + pub fn encode(&self) -> String { + use base64::{engine::general_purpose, Engine as _}; + general_purpose::URL_SAFE.encode(self.0.as_ref()) + } +} + +/// Gets the server's half of the secret key. +fn get_server_key_half(paths: &LauncherPaths) -> SecretKeyPart { + let ps = PersistedState::new(paths.root().join("serve-web-key-half")); + let value: String = ps.load(); + if let Ok(sk) = SecretKeyPart::decode(&value) { + return sk; + } + + let key = SecretKeyPart::new(); + let _ = ps.save(key.encode()); + key +} + +/// Gets the client's half of the secret key. +fn get_client_key_half(req: &Request) -> SecretKeyPart { + if let Some(c) = extract_cookie(req, SECRET_KEY_COOKIE_NAME) { + if let Ok(sk) = SecretKeyPart::decode(&c) { + return sk; + } + } + + SecretKeyPart::new() +} + /// Module holding original responses the CLI's server makes. mod response { use const_format::concatcp; @@ -287,6 +427,14 @@ mod response { .body(Body::from(concatcp!("The latest version of the ", QUALITYLESS_SERVER_NAME, " is downloading, please wait a moment...", ))) .unwrap() } + + pub fn secret_key(hash: Vec) -> Response { + Response::builder() + .status(200) + .header("Content-Type", "application/octet-stream") // todo: get latest + .body(Body::from(hash)) + .unwrap() + } } /// Handle returned when getting a stream to the server, used to refcount @@ -515,6 +663,7 @@ impl ConnectionManager { let executable = path .join("bin") .join(args.release.quality.server_entrypoint()); + let socket_path = get_socket_name(); #[cfg(not(windows))] diff --git a/cli/src/tunnels/socket_signal.rs b/cli/src/tunnels/socket_signal.rs index 69feddade61..53e6cd51567 100644 --- a/cli/src/tunnels/socket_signal.rs +++ b/cli/src/tunnels/socket_signal.rs @@ -288,7 +288,7 @@ mod tests { } } - const TEST_191501_BUFS: [&'static str; 3] = [ + const TEST_191501_BUFS: [&str; 3] = [ "TMzLSsQwFIDhfSDv0NXsYs2kubQQXIgX0IUwHVyfpCdjaSYZmkjRpxdEBnf/5vufHsZmK0PbxuwhfuRS2zmVecKVBd1rEYTUqL3gCoxBY7g2RoWOg+nE7Z4H1N3dij6nhL7OOY15wWTBeN87IVkACayTijMXcGJagevkxJ3i/e4/swFiwV1Z5ss7ukP2C9bHFc5YbF0/sXkex7eW33BK7q9maI6X0woTUvIXQ7OhK7+YkgN6dn2xF/wamhTgVM8xHl8Tr2kvvv2SymYtJZT8AAAA//8=", "YmJAgIhqpZLKglQlK6XE0pIMJR0IZaVUlJqbX5JaXAwSSkksSQQK+WUkung5BWam6TumVaWEFhQHJBuUGrg4WUY4eQV4GOTnhwVkWJiX5lRmOdoq1QIAAAD//w==", "jHdTdCZQk23UsW3btpOObeuLbdu2bdvs2E46tm17+p+71ty5b/ect13aVbte6n8XmfmfIv9rev8BaP8BNjYWzv8s/78S/ItxsjCzNTEW/T+s2DhZaNSE5Bi41B0kFBjZ2VjYtAzlzTWUHJWtJC2dPFUclDmZPW2EFQEAGkN3Rb7/tGPiZOFoYizy/1LhZvnXu6OZEzG3F/F/duNf6v/Zk39B9naO/yAuRi5GHx8FeWUVQob/JZTEPx9uQiZmDnrGf5/pv93+KeX0b7OEzExs/9kALo7WDBz0nEz0/wxCAICJ/T+QmoH6v0V2/udCJ2Nia+Zs/i8L47/3f+H/cOMmNLS3t7YAGP6HLIM7nZubG52pnaMN3b+kJrYAO2MT4//IGvKquY+4Oly7Z01ajWRItkE1jacYu9tcSU339/OnBkYgUbBD9rHonA9pvJV7heYuoFUpRcnKi8RwoJrSkW7ePD6N3ANHPr1UW7wPu5907dLnd4hlXwziROJkDgejfKv5ztZzPgXoUaEPEsM6y752iLyMJdkKwrSo+LAiaFp4HSRvSAnMT2Ck9JHIyQNuaFslDhaLQMIP+B7AGRyZFXeqpFF8HvfFVkQHqGejNjdizFvRHkndAl8AtfEqRHfxPFAit0twsNMyaONmusi/YHvmbQhpTRnyOV0gg+tXzisWmDsLBFAutCcGRHR0Cigere6p3A7NDGmBxHAZSmK/LGHKCeyUqN9fyBIUmyCtV99ptMaQWt4KAny5Fg+nTU1gBvBq4RvHlGCF9WL+2ZxKDfB2gr2GQaUY76Tv7x79VKbxwC5GITg2q02XPy6ZNFnLryVCGskiYPFPQLAsU+LrTvbyQTk7KNUFHwzBUTP1MiKg9LCdWAs8BZx3FHYaJyvIPw4nJpUAP3rP8GPdJeb3iIJ7i8xf15F71iT47rNv+qCXaQD9NBo8PcRVqnEy3vyrPG5SO8HwSDk9PhQJe2xo4Q52soIDB3v1jYYmR8ZkuoNq3Moy6BDjR1WBCTFJEHjdSSADxzRJ2hnozSOLmzTLuKgwWnFU1aGpQ5S8Ry7ME7gVb+CwnFvVtrpofL+DXvE3CY9Fhqe0y4Sq1yLyn/vcgA7ShFG+QnTB5zaKS3Ndj6LSCxwiNivY9R9TsAXobw4Exqog7xCAjYxNIbDuo/fC1QKpFUzvxw+7Rjc8J2lJg80YveK++I5fqJVAFu0Gb4SuJAd8ernBkpyy9lbou0enEfQMOjjucNiy+rgpU4pl+ERgt/Be+8G9l0RbeUwthLZp4ARnBHAB2mcB2o1cJIbhXnMiYStLmjwI+i+NOhBvRV8nmAVslkGdsEVU6Q3hYy/cT/QRTbEF0W58bkYPCyx93ESp7/sWkTG5i9GInCwW+zw1NIRfi2zkuz7KIzOlg33b5/R60L2tjlPtcLjZYL9qGWXwgPApKkndbDq0HhRCQYTyEZ1nC4MFi9NuasFm4t4UV4/W4L0A8YwsXH2m8Rh7hl1No5oIIlAGi5Er/amKw5mAA/Hvwbzfd4TGx66MHWA9t6NAA2WPx538griN7LCqE2315o09fNbOumI6fM1CN0AJT2FheQgaG4tdPFPn6uAeDXUDT8OkTdRFNi6Av4rwo6NnyfLnLYxBNdAhHs75bAedI5egbRrWLC48JT7aKsV+VsOmLsk0TGh6ISxI3WzskVbVFr6HGLy8jee1ZiMF0wzd/B4LvlyGIMa6HD+JBsGOH6vukgqV7ywTl6P+Wo8mTZHo12d7u09Z59eyXJcZKnqY4YzEzGUrlGzvO0Rgfgsse3RMPWJSpsETWqo5zMTtzYk9HANeoA5ubNoO/jjtLyModk/iH6XLiFD1591q+nXNb3Ve2v/aHlJQQYaytpOULvnsEYGIQH9+y3eK1Rgqgs7fxD3uzpv06A/afiToieIJpbjLhy3JZBEAmtN5UgJm6SuCbqgKJ+fDsuwMp/m0fCNVqrYORcBpKTvIWFzWF/leWJntKUis0dPrWy5x7Yu2GhqJh3GN2bT8w1uIh1haSlBmhMOzV3yNUmNcjqFV+GziNt6twoPDJ+4m7TE7hP2E9mEhiYihUDjT0X2Q4k0GIqdIl6fpoFPK0zdfRfbEkP2Ulr7fzfVqCYp9iuxtZFqBafBWLNHVjYtIn9/Z6Z3mP8DBfOYrXbMXldLjKW6rHr3w/LACe+LINkxcxQ9rxxBffepkhhj8NQ7vpyXpudfYmfPMsnai+b5VI5QMcyZly26kxMo6KGGilNYyX/hLaowV4GjIEY7kHRCNmJIBNevb1ag4w98wLWMtfyPMLn18o9cFKiJk2kjZmRBFh0S0Bd7AjxiNO8YdDQ83lBGS5JrxmLG+hW2oGYQllWS2UjK3+loONmC6NpPNgUiNhDQ05s24iRJZ/bzrgBskPLGukoMu8NK8CQNKZE8zzmsCrnkU53iPeZd/UT8ox6WMMZOtDv8YyQpTmhbzXCQW9ogbfgqH447dJFZuPkT4MGfKw+0c5L6aLWqAadBU9yLftFVsi8GZOSB9Ctv9/fJZ5SmlNgt25uGvspB9y1PQGEmLQyjFiGK7kveEw4Knn9lv/9GV2YlCdeRTAUyOS56k6G4ajfxNtMHPaDqIWTM1yBem3dShwkhD0nMXit14/wHRHosy59T+nkuvxG1MbTx8GJM45rvrOmUW0nwxNNdsdqFCNPWn+GcYzIdwCNFtHmdSKNOecfZZVJnKzuGbs41wRQIkv1E1p6ITiPxv+zKWflEU76wHOPrDx4rmyw3Z6MqaP316eOcW43JwBvp9hJuMUHr0TFkvjd5KzvmUSrZfYvpPZ2humVwOsjChiFzc7aoBMt8MdXyf2LIhuhBAg8Ue3wLqlg3cEYBS2z+uzrS5bJzmzH3NGmI+M/WbHOkbqcNtSoZjwp4NI5bSpCKWs7BqrK8sfsUC+UpA08Lfc4CpcBmsTyuHncO2gLc9jPMT+SBAgiZxTDncaiM+YG19ntqYSttys+jpASZDwEWjYRN8QURClAIs0G0KKoY0jjWcc0rypYXiCsHD9+kjtnYJHuzeZw2GQ5U5j7acLM8nyuy8bSJaKZXFq8TJkQ/p4lSkKHpVQPi+dWF4jYaQFEGiPAuiLOGzOE/f8B2rePs9zps7QivUyIiM8fsbPx5mwaC7FbjdihjbM198akLx99SpXAF4fh6d/xwLppw2kFrKa0UsTa/emTuV+6l2/8WmVWLd8JJAhcE+qbMrJBrohgGdDNZIRxJOrsFCzSmu2ykTCZnZlPITlbK/hUA/+DwdtJbmzKczEWAS9ENNbxHNSbn4Nqsz0yvhUE2a/FT6tvnBbXm/X2yLQQhxuVyNCsK2TeUNifqlsCEAJAALqqNI/NX+owJEAk+KehT/fpCsXGTsT3kFsUiPNWAkOEuHviK3Nzpu53edKRZgInWOWhGnd8aD6k7kio0tLT8i/PkxVrdZftlNrqPZfiEXkqX3hM526HzLGVzlr+CvTBKxsU8ROxHvBGWzJk4Tt0uDhZessy5BDFVx2xiYxMTXfQyv8NF0Op3CKCFvH1KbE2Z2TGCvpOEH7LKVK5TyTVSP+yah8TkpL1cHorIRxz2a5cMNMZGgdooqszII7PJuT3Ii0GpCCXe3v5mzysGhVKBulynWOeMrlJ4jKA4xzAXIg7ReLCGOntAOvU7qD+5UBufLWxx/3cqhuMcZDnR2dUjJuFG5LuFiwnvboFRMjVTvVJkcNdUc7b+0auIQWC1E3hTQx422OCMuGvayP3WMCGe8IClwSw4f1uA5LkoDYZbVQo1SUzETYNPQUK5BTJy7YRq4ln9vLvDHDImNd3TiWnsL7Zp9qWVSSTfSVSyZTT4fJqKIZ/Kcy7IkXFyv0Frw64R7y0vM+tAu+0kebn9y+DlN2xmi7nmf81iI1xffS5+ehMzQJTIa8SjVc8kCf14eOLiR7TgCnHcJieDFQI9r9K9co2G0hpitdihrbb56XvossnHl8Fu4JRLBPgKXsAQyX3v3BUHuw42rmeQXz74oZzmEIG13oteilg9HOUyoR5NHE94cYtIqP80qheAh9uQA9e3+TSmiLy6dsU625mYOYcPixVm9ZYuiOtLWQ3tT8j2T111qqjqNu6yUSxlIAh0+ANUEhEh9Uoj9v89/WqlGXNWPDmKfRtn+yFVoyggl8PjW0GB7qfreaEuoqouCGoV+lWma6sNZyKYQGIn51nzIyO1uUlRQZq5j8aTQgcXlNYi5rXALJ2Kj8nEbJT8OqXEt0fbWPKaLQZch23yR9RLyaXMpTIzzRBkoFY5g0MfTWFLbcMynydkZITcfLTSDeD/fxSqUzWmgjk9j1aQ07KUBInTRErSbfEhgCVikEENWXpOubo3XV4YBv9CJYSuXnSv0d3jLQdHefqwT7+Gyqy0ZJYicFYw3ma+acapIZw2r4qg4BNKbSbkMKOuWidsr1dxjS9bjSYoNH/VDBdbgXpXTpPJosDIjwMHsV48OfhwZjvnAC0r2yJ3+NPhBP4g/GU14mpdefzvR08OElSHLpZidGsL5GGtpzcohM5sQ48TMsOs6Cy3vvgKR1oanGjGa8dRN+UaaAWm1dieSOjvXzIIVPp3zoKEgVu9zlP2W5NtNSVDfceVy/cA2IFjOlKa5EiLEEA57fuxvGmOvxCB+ZROvg6KOi6EbxLMylQEbvzctlbmEJ0S32x1usYisIWFfCLX/SEETVFuAxZJej9AcvkolOkSLNlohZdKzOYeRMfQM/RMT4JwSfFqHgIq4XeYPtTzMO2ZkTdOjdrrWL0ZMFosuXiKD/9qKKbo1FjqjwiT5a4uIaPdU95J52kiPoS7adOxUFiypbB9SrLFTABESJrPr0qMSVCi9cMME+Vt2Qq9gYFIvXoDRAR0SP04c/2A1r/tvxBu6JRGDB9cwYWOE1g8W+W/vju6WwPvifEO4AQ+KD3bGEhffrUWM1SnsAZBbJOgep/M1iU/HX4uNGb6Dmz+0PQdJAo7TkA2D+Wigyb9CQUfK16vwLvIIvMnylTcOOIAUtbiy2/lcdbmnQcFMt7ZZLQxBemf8S5L8jkyl1WLZyVNGDm5qf/72TQLs6KK4ljCJqMt0F6p8tidu/52WK95lYzKiZy6nlOSKadsCEWX5+eMzpJu8ZjYF5Qf1K54q5wO/T4Y+QYoWlUlXB6MoL0adwXmSs5T7Mht+6k8BO7T5I+3iI54WdYwixTnvlI/TNQSjwGJdxqJOmInihyKgkCx1lUyn/fx6jKZ+1MHPZwvfOg5V9TuCf+aXvjVhcgJHJBilS8ytrZh8FQh23yNbEIMoE6lYyWuYdSKv6831VdffGAP6gvaD3d9aUBJRkHquA1iqVB/ZG+bcJLpeMFJagd95AvGXUIuYwFKFmBtlKkjOuiEbKNKxv+SJ/NQCIGRBxVkm6oqcabuFnskNEhB4FnYnplnCIUZEfsuLirqsm6sSQZ2ZITdUAkmQ308cj5051V8FwogjNmZJyYuNNsOxYzumG33B7Z5k6QHkr2HC4aky5ZHP2bW8quZNaSXEcL5YGfZeTPTOVCv3TA+e4NLZeVocXTUYNWe7pyYjaf6EUeHdXOAMpZk9084KP8PBCwnlNfiZG2fXD+36bvn8sOVcsLvwAT01LEmVgo2E0geZqDPd8OIHJxDVB7VXNeFYIKjKgOjT63Bq49GLdBmwOlTKDljg00eYqLTQO66FPzSTWMc2EMGCae7sVr/OluTg/T4NKFt39gySNurVvPtlXZfqCo3GfCiyTV6iZWeuVMh69PrrozqgCX0mHJ+OyzMtQrTbqUB4BvHZe9Bfo/uyBDmRDWV0vTCz1mz0t+DTOjRkjEiAOFOKSQ5w/L3RgIwmuEgW3kqaQqtwAFIfWb9PxNuLvTLGMttZ3yO5P3aYl9G6jCSrrcr+3m0ICKOTBu8lH/lonRkZOq/08lpP5VtCEak6I+aSIT9tP9LJIZACn/IUe7qE88kjETKmnZT6F1D/1p58pEA0NI4g5CtdHlSXmg0s+zhAKS7tYpvNx96EPw5cCc5+VneGb0RDNvLaa+cEF4M/JuU0PcA9u9gu+PC+byS52tGqNA8yuH7El6JwFI8dXUvX07iAkC2VOvtt4kg0aeiHDyPHJpvvN4TaAH9Bz+WT5FDWNTAz4LC79GO6pQb9j5iojBlt+UUHvr8nfZN6AKa57RMsFTt9m0t0eBVUqR5fgpE/k6+57U9FtAQPZ5ufj66n0Ys1Chyr93K5jhX3GM64JjdryhghfffO150Q+hYrX3a5/fo2ULWBM27UoViPGVCFtmd0Yw1V5F+l8j58Mck1yUYxpU6tg+o1tara6THtW91V2dqC0+ha42qUVZhScMys1ygeqrpwVTvfhsaVH3/e0xXB7cO4UYkBg1ivB9O+90jwFfg1noBWOg7JpyGvPzYuLPz1CzNtVCqtRpqhMbCu4e2xQ++w8gJGD87TjODSjvgsXoDOs/Fs2qzhSatxvKrnW6pmKqwo9j4B12XZ4Sc+4oE2DIquGY8iyYrp9oBkSCQ8kOIkYVD74yj5C+Y/+JkFNVPwwBvarswkuyZUp8gjHCBLFkf0l+yBDWvJ/jZBXyUFSCGDIrpl1USocwndJFH5zst9/ZyaiKGKEO2nEBAuOCo1XTAyPLIjonN2pH7c01ySgFXymnEV0K0UGq78eDfUtxpmcGLtK+75NVraVGD2wNVNrpWJl1al+s+CM4OvabLcM6VnweXcGciDFRmghhWVoE4EqnhFUuFxCB3umtoyn8lKuEy1fmrRsweDOMtUNd0qA6IctHwIM0AOX2Sx0KxqjEhpp+YkfStkyLrzC33yJbUqRbgkDGq1fKfJDAdenpfQOVj6VMCsB208bbzJUcGOWzZtvfnETOnRLxb4LddrcPuP91CawvOVuAphNrIEUsiRon1SrCuL8GVF75tbSHcskqjIVLfycIZlvVjlywu9gBptiORxw/e1CZ7bDeKlTTIK67KQqosSEs1fnc/X0aAxlkqaOEZQdefKhrABuZFa/KTPRhQsFSncg6wI+niscy0rjfkkvg5fe4c17WCpa0eXot7t+4ot9O5+v0H/buYYniE4MzfrsDnJhqu1tLt1z0dNQ60Qz/8RxR7461d9KxJaNTelFLXDQwDHcTCBSk+0BrJVKT9Ls0bHgxr0zDoaDnbnlXjuu9+I+TH6sZYee1kDBqfPV/RKaXBx6yCFxEBosyCqvwmiuHUzItjvCMSpgREhM861FtvcyaGbN1+nFgM0NlPJQdpqz7bpEJcVw8HFp0yAAT61uYy8m51btG5zFKE74t+qEpjkQPOxPzxh52MDHVgMT0vIQcdA2GGXmjLInOlKHy44blBXKhSsvnWk6goe3xaY/vatI9iOJP0zdmqYuV/Z82spbMuwMwDVEEqrn/KPXqWl0G9AIAPPSA/DO5U9NZAn8nW5CcnB359CkSxVmBXbPBph/GvVrjZEiohjaAfRzdYgSBArwPcIhmfsE3ankfWrXOiw0qJgH4UvOuQphVkNCTIDl405MQMo+6Usm6YMkKx93V+wFSt0l6zoNYeELrp5hNwWNc35EVD0YJegiTIgVDqJykV3YM5po2UCDF4a1Ijhgu+mWL/+B3K8OcvmsGG8X/tKBCNPK/0jJT6PKfks/NEJDkcRcfm1ZDp9AFzldq53UZoT4o4zhRSpLA+f6VTIJx4/t78vpyZKMEJmc8RbIp/swFrbSGInwW4NCrovIK+oS5Z3zXeNbGSpuf2oWYAtpQvttaM2LNl4svcEwxvYor7JMy46l1f2SB0Q0PXLIehirHvMLhbfdWLQw0QB7Gq2O0khxvT1LjZ+H+euX7uZmkY9IvXdW0pnDhaNmZKT6nKj9K1bcLT3520W7lrdOzlEMHxtoSMMd9u2LtEkdtO0KIyfVvkXReY+ilkTyBUmcRCEWl27pABXdcl9jZn6A/16Ze1Lv9SFRncN42vpbOS3xkIBPtFwaDftP6IZLtchcxmj3xkeJFH8fFKg5f06HvCjPbxR3US46FTJqo49yM0H1L8wOjSC8wYHb4Mo6Zhh4i48snY9IOVfrIGqFfTsTQ5kxIctBPqGnMO7dl+iu4TUqeHkDk2IkmZSNjB7hp0mmLHKcTAB49JQDsZdlPlcOeADP/r7q/I5vXE8ZHzXqFmxW9v90+JMckU0V0AIrcJK9IQWl4LQR+dRuKRxJwDpy4wa4ymhqnBdjDMqQ/cetUExuVkzntiCPyOz6dMpAx9ZeidxQ02hYjPVqgFg8sCl1lTHTulvk7Nj698usBJMG+IKJorZp7+a97Tr226dW1h++Ic3ERIIDuFrJVY0UvO/vrTZrxZbzT2Ki+UvjN5Ins+P6gU7XLKlAlh4h3u54VXMJO6MqqpSFKXQlRY2fOOn/m5YDfOCvjmhsmrp63Wz9s+kowNsciO+DZa5Mce5qH9/ysvEHv7Sgb3AIZ4+zl1R9px1bU2HI/tcieQUvHkNG0N43uBelEbsrZTfVDAsk7KashZp+QG9k91BWuxlN00Hmaqd3foNx2EwoBe14MbFyJKr0PLJvFrMBQamhlWX31hknK3y9m7F3cIopvO2kIngxuVgZ/c3XOMnJysZcmgeVvouinM2GCcJF5k54InnSO0JJ0g4taICxSdD1NbXw4aVfuPXY2loCOKwXAsHW+vRvIu5yBYsAXeOX1J7LwWwVHOTLjQDRyIwgAsot1J4dr3tRO1u3s72SospfgKrMJdMYtrSJ6zvRQTEDXZcyk3fqtElG55syIjePTyPVPDGCGHVvaqOCWvYDXnsFAy9L3gVg8HaLMerTRuSzj6HjRmyZNheBBZkDOTRmc6yaJVhK/+NCpXgPsW3xyAX6ZGQ44NOAyn9U49Jz5VIUpEfXTK/hDaJeMgl/HmLcfxbBara5U+J5xi9IvwTcMMzxxN/sm/BjLc+34gP33ChIncbfHleQbbQvS6JMkySTA2PCbI/vwYonIZnymVtA3c4fC5zso+ZgTyvnxZkeJdDRPjTUtP6DFIAxMbIotg2e93CXfUp4ciADmTWa4IbuP3n602bqsqzTldZAt7UzolvY0gnTcmZWJC8dCoZhebkdcf9hd+jW/HdVo/YM6s39d1Mqm7PnG2dsXFSCn+yg1redbnDTPpUVi1+T1xd6dGeM7GddroA/qyNLl9dvdvCUGQvRL7BIFQFUZYXRdx27OAStt+iqORvuibZWfLufrRJVM6AoyJNpRo4rALSdtAcfW8d4HJGPEaP1cxl6ErnQz+yDbv+zRMTFCJiuPTJRDXD+ir8hz+eChUN323YpgVJ0Qjl9oqEj9H3SKORfnFaq0337C3oyz0eQ5PedG/d78nJzRP+BfQIOFMDzPSJ40yg+MAgX0P6ZPOiBIW7c/i2j6TQhVyeEUzsjRMYMMiGQl/lgTz9D6Kc/WP4tzbzhRb0Icoy5+sZRiap1rQFjaOVzGUEOXgMoME9voaumyWcTskYTxGdil9CvKBKsHCFx8iZ63V1xcmT2JnOVuYEAqOwD6bSc6KhJznv+nSyG7HNY+ycCXP1NBoG5Z8QgXEcJxUMl0SDUaMAqM4K/NL+ZiQHDbDL38U9eBa9zYaG7xronBtZ7ieC2yMOcMfz4tSvATwPeH+qlTOJQjBtFEzHkFV84bUdVYLaMj8/oM+rVU/4hZCpXR42AXjhfEZBT2M4YZv9ciCjNAo63zbfTv2zt7A6ZYVUkRFW3mRQw0EP7bmK8w4BcVzhy2U0zaJqlBAbc1i/4A+0lmSnyKBISJRF4lrGz1dIsCpZ5AeuDopJNc59Rb7viBjmnA5rBqdrxPhNnReYbJd2k3g7YPAV21Hx4wf7oUsVn8Mu6dgmChDCc1IEc9jxSnHYCWqlCA7YBeUtXTXIJf2qe7knGliksYKnYfX9RnXdeDoIbmKWGsV2mnK+oJPzOlF46TC391bf9GBe8T2rvcXJINCfZBmS60iO+5Yo2NNJQi+Qc9SebaaygxTZOj6rIbNwzdhDEUYCG8zfS9KmEhZKfcz5+9oCIG6mM8oh7q79yxzDIzdpaotBKCgJ9M8jtC/Ee5ZI8adPdXMkB1EEzaGWZBuBvzecpPmTyhzpKBy8FB0kKhEOjY0/utP7JAJKpId0xWuDDsFlSsbCqPgb4wbUqID7Qxu6FUJ1QGCxGYA+u/NXFQesgGrYlWKdm0zY62gtlUv89zV1PwQwB4TNtP16MrfZAuYhqgR2xJ7ON7tWJ49lVyjB5NbzlCGelLKJIkoicwMz1CSQ8b9SO2qk+WMWUPnXqCsHBSU7ews5rZ8ccw539tfEBj9UNPUqW30tjb9BIc5q0ypPa15S8ucZOGEpSGyRLaf8SdSxw1JDsq0vYF04PoWvvYyAIAVNl6ACzWEnCPSzVAb2orLKO2McQpRAY4I762BRDhBt0R6a1Qm9Hx9g0gUfQE6iXBniPe81OUTKzGHNKxHzV2sP3HgVlBmB2M3N2tJTzb65XnRGKLGOgMe2/eVvLj54lK4MRe5vTJG1QvZUKbxnK0YdMNE/N/eTPwJ3tB7tMyVVVDEUQpzKNtWqrbKvtQcxG1Dy42DjnsCW+DNlXdgmIKcG8ZpJT9vTihoR2UAK1ZG1WPhVF2oNNvQGU3z3hIQ8VNmdu0EMJlEu6v4iTlLYi3E68RpLs8Eq1d6csi6nKrJRssSwsm8ApR/yO/p9c7dYj4EsfcwhxzsfgLdpu8SKZUUgHkSs+KWA2F3fHUawrHUZvl4xdkDqC/S4vi8CweW7ed/VvuriZXHgljCahrwhe2YRn0rZl3Kvsc3wz2L8XaRhusY1lT5Xy8rqsCiKFcuevI7DUCV2/c3uuhY08+5+qTihQwGlrJTQo8iTNr39o6lcoalqyKYeXWoQEKpUQP/SvTT5qhq+7NdJoB+q9JkU+q0aEQwqBOF+rdmRUeYEMWXmPiJ7NndcQGuAJg+M5pnbB25DUv2zP2Xqj/PjYypAJMMavI7YgoIlZ6VZ/L1yqU+PlABLp7+A93JgpG0hv221lEPIWY4+RNr3yyhPnCxtGA8obgUDu/6FIHqq+hxm+GfZx2DI2TQjgQs5yJiUyIVoXbmjjoBX0axEn1x3xsa7YlGVeFw1jeqFbgdIFN+KInG4kpJVd07c4BLJiITZFodHExoFD65tsX1SLXpZgdoljKwDo2DkacLCLiaV8PShqJEjo58uXdCu676mtSePbGyW0KZigAPGEpUEZ6zc1l9cZXjeDi2aLJpl6sphMR/B5aiIz6J7Afj3feUuq5qxxFHQC8jR1C1hPV7ZxF7Sub+U5iB+ynvUkt4iJd7kxJDARVbZPBbUSb9/ny0nBbzZmkRE6oi+0ocWxaH4ZnVrsL/NgnFPwKuG2IwbNCHls26kUeON7qS/+j0PLAXzBghwiRgBku1clT/tM30AS1mvJ6cKDjjLPMei7GwGHaJFfQqEjjikb7ktX5O1jVMlZTrNGliwOK1fTh3jE9b5K9AppT5IFuPxhbJ97+HMazBEPtMA9aZBIKXNFIvdPPCs0DHt05HzygjrejibsBA/SS2F+gSlANRlkrJinMIpt/gdlvUbjaxFrMupGmVCoMDfRDrxO053FTh8nto2pA2ActBghuqLM8p91U5FtVhXU+FI8whYX5WdWMmWc2E2wGzFz1aCKYJIC/qr4xzN305xQLxAVb2n0BQedGI+j38cc0ECk1NxJ2isVKvmhk5RyzSc6EPzB1884xko7roUM7NOu0FiPw+Zu4R8OGoHRYqsigkTRxlmL19aGEbBbdK9TmGBvwCd307SHj2GojSWN7DL9olp1+VMMYQ9UG8DTX47r23qkXZ4z3ctQl86rRjpzdj+70XvZb+h0FzgnyJmYSHxIIn2FWNYmvwPjyiBUgHYP5RoHhSJoeI6W+nkFnHijreTncsonIU5FKlqHQFGzzdc8s9U5sfrMFtR1SUYFYWj3C8KP0oQwiXZcn3AcqPkTqVU0o5kRZ2+QS+fJP1ozNeh6hKJSpUVSb2LZ9329cfBOPAJ7u8zYUqJZ8CIzIa26Qy5ADf5bco2Z18IcLHAulDYBXxaBCm2DXpryNEQMYWmMTHA0mVpIFVkmU5dfnNQykdZiAXU1l+Fw6kIjrMJ9AgF0xWiaZnOyTehWtuxU47hvUm8B2A9ociq2x5aFOxazc3YG5IB7IZmXercFhEWIMzMw63jvREmRjCT5ou+MIjmbi1na8d0SaLUudX5pUouPbc+4stjuNveU6cNACO0s+nbAlVyZyCeRMAPk5C+11kHcwSNd8IZugXSih5eJ4xPoIW0knz0365CjhNUfz9+31qYzK0lZNMUCuf2K0vrUBB/i3T3gdXMGSeldKp3Lx+tz/bpKXTHtUzzsvdS9Gs+uMIZ1XK6AxFyeCxOJ+cU9XN1fBnLPe2JYUlJUmCu4tiwsprlamaRzZQNWlUxombEZeKC7q3mwHcZM5wU0ICwEnLfTxW0VL9N10+batqOKxQnIspanPsw1ez2cuwr/hQSPXqoP2gIkFZnmAqUKUX8GZ5ib+C60pulz4Uxz/QvZW7V2SAAGcUwS30VsW6U2Ld2v5UbOfEQCxPdOHJZw75sKgEdyVdN1FDl4JC6s8IUclP+LD6R/CXIEDhbSWuXdTsAinSZLlMH1LzCXp6Cqvih/NReD6FJezE4Hi0sUGxti+4YngNBTWhUOblVY4+ioJs/kpVyXoAksKXh+Fe1j1PG2gbHkCQQWWCDqufQCEypj+dCoj37UreY26CogoUkVCnNUXQ5jZNFOPeXjh336gUEGzTt9qLgRwsxEJpQKH+aCWZALuJHtCVlK1WQMM6eM15EjMtRabejRb7eD3Us4WqESLYxpZ5KCobtmQDzV/4vOlvq0BSClPNORXWKygxQ2J9casayyd9DxvL77P41vt3k3fsT5PB1d6WR+6JZWwYJGZTdxyDyiFJDCKV9TuCeGkZQ26g1V0sV/H5a1xciwxOCNt7GgQOajs3aR4wpXxg4GbU0nOR0c9Ii/Sn27VMt4BqnAj5W4fx8q4ecJlPHlG3tSjqKSUsP0rlyg7JRFXcxCUGv7QMYc2K9WLvLEHbBOcM/ZD87o+UaQ3CvTwOkQTDq8hUeOBRxcerQV5Xi6Y+Hh6Vg4aeMpoGdUV7xXbw5oVh/mkSLP70aWsGQ3UbqZLFHrxQzLeDFkYJX6q069Lp/1X+lGTY+5ykXDRtK1n+GarP5tNWi4nd81eFXdracJWwcYk2GA6MbdjMnoaTrfSHXO3EXgrlq6ko5DABSrMg+9kF88aW5LAVOxGADYFS8bniGvdKVXnEhhQDJVCYKqqWKYGpAek5BGeVRWSbwLCKdQ5BcBnn+oEsmp46uK3k8KO72Pn+1hPMbgE6xWxVYPqAe7HVPPjNRiQS6cQGOxU1gdlAuEJ4V7ip4o+TgDM2/M4bthC6c4SBMQaMfRZfL5ko/uf3U2MXch54RJ2/LQRAy3AHiOI6enjY+L88VIvjU+hnmwro8yEflSD4tEMeFIkrxEW19Gycl1BDXpDVbs9nrU5MMIGx6QxCFw8FibHOtcRcI71o8s+OvDCQFsw7ZVMslGVDaprGZZmJ2j4uTgxrn15ihGv020yixBNktFCYgTyPlxA1f36ciarunxld8CPUVUPV/D/XFX5s/Neg2cdPqmSlO/fpnXxz4UJnIlB6hSl82wNGKJud1KoVyDHmmjI+EKBSUO7kNuvrQ/fY3duE75BX/HUAeUiLFKBZ1O2/mThw8t0Wq782ApG12/Jvza+94ENybWDDpLLmTddfEP7cYjFtZZONpGuxNkP8FAAD//w==" diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 3ceea02d892..029cf8b10e7 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -4,99 +4,221 @@ *--------------------------------------------------------------------------------------------*/ import { isStandalone } from 'vs/base/browser/browser'; -import { parse } from 'vs/base/common/marshalling'; +import { VSBuffer, decodeBase64, encodeBase64 } from 'vs/base/common/buffer'; import { Emitter } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { parse } from 'vs/base/common/marshalling'; import { Schemas } from 'vs/base/common/network'; +import { posix } from 'vs/base/common/path'; import { isEqual } from 'vs/base/common/resources'; +import { ltrim } from 'vs/base/common/strings'; import { URI, UriComponents } from 'vs/base/common/uri'; import product from 'vs/platform/product/common/product'; +import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets'; import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/window/common/window'; -import { create } from 'vs/workbench/workbench.web.main'; -import { posix } from 'vs/base/common/path'; -import { ltrim } from 'vs/base/common/strings'; -import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService'; import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api'; import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService'; -import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets'; -import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService'; +import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService'; +import { create } from 'vs/workbench/workbench.web.main'; -class LocalStorageSecretStorageProvider implements ISecretStorageProvider { - private static readonly STORAGE_KEY = 'secrets.provider'; +interface ISecretStorageCrypto { + seal(data: string): Promise; + unseal(data: string): Promise; +} - private _secrets: Record | undefined; +class TransparentCrypto implements ISecretStorageCrypto { + async seal(data: string): Promise { + return data; + } + + async unseal(data: string): Promise { + return data; + } +} + +const enum AESConstants { + ALGORITHM = 'AES-GCM', + KEY_LENGTH = 256, + IV_LENGTH = 12, +} + +class ServerKeyedAESCrypto implements ISecretStorageCrypto { + private _serverKey: Uint8Array | undefined; + + /** Gets whether the algorithm is supported; requires a secure context */ + public static supported() { + return !!crypto.subtle; + } + + constructor(private readonly authEndpoint: string) { } + + async seal(data: string): Promise { + // Get a new key and IV on every change, to avoid the risk of reusing the same key and IV pair with AES-GCM + // (see also: https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams#properties) + const iv = window.crypto.getRandomValues(new Uint8Array(AESConstants.IV_LENGTH)); + // crypto.getRandomValues isn't a good-enough PRNG to generate crypto keys, so we need to use crypto.subtle.generateKey and export the key instead + const clientKeyObj = await window.crypto.subtle.generateKey( + { name: AESConstants.ALGORITHM as const, length: AESConstants.KEY_LENGTH as const }, + true, + ['encrypt', 'decrypt'] + ); + + const clientKey = new Uint8Array(await window.crypto.subtle.exportKey('raw', clientKeyObj)); + const key = await this.getKey(clientKey); + const dataUint8Array = new TextEncoder().encode(data); + const cipherText: ArrayBuffer = await window.crypto.subtle.encrypt( + { name: AESConstants.ALGORITHM as const, iv }, + key, + dataUint8Array + ); + + // Base64 encode the result and store the ciphertext, the key, and the IV in localStorage + // Note that the clientKey and IV don't need to be secret + const result = new Uint8Array([...clientKey, ...iv, ...new Uint8Array(cipherText)]); + return encodeBase64(VSBuffer.wrap(result)); + } + + async unseal(data: string): Promise { + // encrypted should contain, in order: the key (32-byte), the IV for AES-GCM (12-byte) and the ciphertext (which has the GCM auth tag at the end) + // Minimum length must be 44 (key+IV length) + 16 bytes (1 block encrypted with AES - regardless of key size) + const dataUint8Array = decodeBase64(data); + + if (dataUint8Array.byteLength < 60) { + throw Error('Invalid length for the value for credentials.crypto'); + } + + const keyLength = AESConstants.KEY_LENGTH / 8; + const clientKey = dataUint8Array.slice(0, keyLength); + const iv = dataUint8Array.slice(keyLength, keyLength + AESConstants.IV_LENGTH); + const cipherText = dataUint8Array.slice(keyLength + AESConstants.IV_LENGTH); + + // Do the decryption and parse the result as JSON + const key = await this.getKey(clientKey.buffer); + const decrypted = await window.crypto.subtle.decrypt( + { name: AESConstants.ALGORITHM as const, iv: iv.buffer }, + key, + cipherText.buffer + ); + + return new TextDecoder().decode(new Uint8Array(decrypted)); + } + + /** + * Given a clientKey, returns the CryptoKey object that is used to encrypt/decrypt the data. + * The actual key is (clientKey XOR serverKey) + */ + private async getKey(clientKey: Uint8Array): Promise { + if (!clientKey || clientKey.byteLength !== AESConstants.KEY_LENGTH / 8) { + throw Error('Invalid length for clientKey'); + } + + const serverKey = await this.getServerKeyPart(); + const keyData = new Uint8Array(AESConstants.KEY_LENGTH / 8); + + for (let i = 0; i < keyData.byteLength; i++) { + keyData[i] = clientKey[i]! ^ serverKey[i]!; + } + + return window.crypto.subtle.importKey( + 'raw', + keyData, + { + name: AESConstants.ALGORITHM as const, + length: AESConstants.KEY_LENGTH as const, + }, + true, + ['encrypt', 'decrypt'] + ); + } + + private async getServerKeyPart(): Promise { + if (this._serverKey) { + return this._serverKey; + } + + let attempt = 0; + let lastError: unknown | undefined; + + while (attempt <= 3) { + try { + const res = await fetch(this.authEndpoint, { credentials: 'include', method: 'POST' }); + if (!res.ok) { + throw new Error(res.statusText); + } + const serverKey = new Uint8Array(await await res.arrayBuffer()); + if (serverKey.byteLength !== AESConstants.KEY_LENGTH / 8) { + throw Error(`The key retrieved by the server is not ${AESConstants.KEY_LENGTH} bit long.`); + } + this._serverKey = serverKey; + return this._serverKey; + } catch (e) { + lastError = e; + attempt++; + + // exponential backoff + await new Promise(resolve => setTimeout(resolve, attempt * attempt * 100)); + } + } + + throw lastError; + } +} + +export class LocalStorageSecretStorageProvider implements ISecretStorageProvider { + private readonly _storageKey = 'secrets.provider'; + + private _secretsPromise: Promise> = this.load(); type: 'in-memory' | 'persisted' | 'unknown' = 'persisted'; - constructor() { - let authSessionInfo: (AuthenticationSessionInfo & { scopes: string[][] }) | undefined; - const authSessionElement = document.getElementById('vscode-workbench-auth-session'); - const authSessionElementAttribute = authSessionElement ? authSessionElement.getAttribute('data-settings') : undefined; - if (authSessionElementAttribute) { + constructor( + private readonly crypto: ISecretStorageCrypto, + ) { } + + private async load(): Promise> { + // Get the secrets from localStorage + const encrypted = window.localStorage.getItem(this._storageKey); + if (encrypted) { try { - authSessionInfo = JSON.parse(authSessionElementAttribute); - } catch (error) { /* Invalid session is passed. Ignore. */ } - } - - if (authSessionInfo) { - // Settings Sync Entry - this.set(`${product.urlProtocol}.loginAccount`, JSON.stringify(authSessionInfo)); - - // Auth extension Entry - if (authSessionInfo.providerId !== 'github') { - console.error(`Unexpected auth provider: ${authSessionInfo.providerId}. Expected 'github'.`); - return; + return JSON.parse(await this.crypto.unseal(encrypted)); + } catch (err) { + // TODO: send telemetry + console.error('Failed to decrypt secrets from localStorage', err); + window.localStorage.removeItem(this._storageKey); } - const authAccount = JSON.stringify({ extensionId: 'vscode.github-authentication', key: 'github.auth' }); - this.set(authAccount, JSON.stringify(authSessionInfo.scopes.map(scopes => ({ - id: authSessionInfo!.id, - scopes, - accessToken: authSessionInfo!.accessToken - })))); } + + return {}; } - get(key: string): Promise { - return Promise.resolve(this.secrets[key]); + async get(key: string): Promise { + const secrets = await this._secretsPromise; + return secrets[key]; } - set(key: string, value: string): Promise { - this.secrets[key] = value; + async set(key: string, value: string): Promise { + const secrets = await this._secretsPromise; + secrets[key] = value; + this._secretsPromise = Promise.resolve(secrets); this.save(); - - return Promise.resolve(); } async delete(key: string): Promise { - delete this.secrets[key]; - + const secrets = await this._secretsPromise; + delete secrets[key]; + this._secretsPromise = Promise.resolve(secrets); this.save(); - - return Promise.resolve(); } - private get secrets(): Record { - if (!this._secrets) { - try { - const serializedCredentials = window.localStorage.getItem(LocalStorageSecretStorageProvider.STORAGE_KEY); - if (serializedCredentials) { - this._secrets = JSON.parse(serializedCredentials); - } - } catch (error) { - // ignore - } - - if (!(this._secrets instanceof Object)) { - this._secrets = {}; - } + private async save(): Promise { + try { + const encrypted = await this.crypto.seal(JSON.stringify(await this._secretsPromise)); + window.localStorage.setItem(this._storageKey, encrypted); + } catch (err) { + console.error(err); } - - return this._secrets; - } - - private save(): void { - window.localStorage.setItem(LocalStorageSecretStorageProvider.STORAGE_KEY, JSON.stringify(this.secrets)); } } + class LocalStorageURLCallbackProvider extends Disposable implements IURLCallbackProvider { private static REQUEST_ID = 0; @@ -390,6 +512,17 @@ class WorkspaceProvider implements IWorkspaceProvider { } } +function readCookie(name: string): string | undefined { + const cookies = document.cookie.split('; '); + for (const cookie of cookies) { + if (cookie.startsWith(name + '=')) { + return cookie.substring(name.length + 1); + } + } + + return undefined; +} + (function () { // Find config by checking for DOM @@ -399,6 +532,9 @@ class WorkspaceProvider implements IWorkspaceProvider { throw new Error('Missing web configuration element'); } const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents; callbackRoute: string } = JSON.parse(configElementAttribute); + const secretStorageKeyPath = readCookie('vscode-secret-key-path'); + const secretStorageCrypto = secretStorageKeyPath && ServerKeyedAESCrypto.supported() + ? new ServerKeyedAESCrypto(secretStorageKeyPath) : new TransparentCrypto(); // Create workbench create(document.body, { @@ -407,6 +543,8 @@ class WorkspaceProvider implements IWorkspaceProvider { settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined, workspaceProvider: WorkspaceProvider.create(config), urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute), - secretStorageProvider: config.remoteAuthority ? undefined /* with a remote, we don't use a local secret storage provider */ : new LocalStorageSecretStorageProvider() + secretStorageProvider: config.remoteAuthority && !secretStorageKeyPath + ? undefined /* with a remote without embedder-preferred storage, store on the remote */ + : new LocalStorageSecretStorageProvider(secretStorageCrypto), }); })(); From 47fac5e7c05a16200fb0d774dde7ed398449c695 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 28 Aug 2023 19:13:58 -0700 Subject: [PATCH 053/198] A few tests for Related Information (#191547) --- .../aiRelatedInformationService.test.ts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/vs/workbench/services/aiRelatedInformation/test/common/aiRelatedInformationService.test.ts diff --git a/src/vs/workbench/services/aiRelatedInformation/test/common/aiRelatedInformationService.test.ts b/src/vs/workbench/services/aiRelatedInformation/test/common/aiRelatedInformationService.test.ts new file mode 100644 index 00000000000..6d521ca8777 --- /dev/null +++ b/src/vs/workbench/services/aiRelatedInformation/test/common/aiRelatedInformationService.test.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { AiRelatedInformationService } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformationService'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { CommandInformationResult, IAiRelatedInformationProvider, RelatedInformationType } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation'; +import { CancellationToken } from 'vs/base/common/cancellation'; + +suite('AiRelatedInformationService', () => { + let service: AiRelatedInformationService; + + setup(() => { + service = new AiRelatedInformationService(new NullLogService()); + }); + + test('should check if providers are registered', () => { + assert.equal(service.isEnabled(), false); + service.registerAiRelatedInformationProvider(RelatedInformationType.CommandInformation, { provideAiRelatedInformation: () => Promise.resolve([]) }); + assert.equal(service.isEnabled(), true); + }); + + test('should register and unregister providers', () => { + const provider: IAiRelatedInformationProvider = { provideAiRelatedInformation: () => Promise.resolve([]) }; + const disposable = service.registerAiRelatedInformationProvider(RelatedInformationType.CommandInformation, provider); + assert.strictEqual(service.isEnabled(), true); + disposable.dispose(); + assert.strictEqual(service.isEnabled(), false); + }); + + test('should get related information', async () => { + const command = 'command'; + const provider: IAiRelatedInformationProvider = { + provideAiRelatedInformation: () => Promise.resolve([{ type: RelatedInformationType.CommandInformation, command, weight: 1 }]) + }; + service.registerAiRelatedInformationProvider(RelatedInformationType.CommandInformation, provider); + const result = await service.getRelatedInformation('query', [RelatedInformationType.CommandInformation], CancellationToken.None); + assert.strictEqual(result.length, 1); + assert.strictEqual((result[0] as CommandInformationResult).command, command); + }); +}); From ebd67244fb2da33ab078bb2baa96106fda29f336 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Mon, 28 Aug 2023 19:14:10 -0700 Subject: [PATCH 054/198] Turn on Command Center by default (#191550) * Turn on Command Center by default Fixes https://github.com/microsoft/vscode/issues/191549 * remove tag --- src/vs/workbench/browser/workbench.contribution.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index 5b1d769a4a4..e41769f836d 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -583,8 +583,7 @@ const registry = Registry.as(ConfigurationExtensions.Con }, 'window.commandCenter': { type: 'boolean', - default: false, - tags: ['experimental'], + default: true, markdownDescription: isWeb ? localize('window.commandCenterWeb', "Show command launcher together with the window title.") : localize({ key: 'window.commandCenter', comment: ['{0} is a placeholder for a setting identifier.'] }, "Show command launcher together with the window title. This setting only has an effect when {0} is set to {1}.", '`#window.titleBarStyle#`', '`custom`') From fdb265d2214c933d18d6e75a44db4d9223703521 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 29 Aug 2023 05:52:08 -0700 Subject: [PATCH 055/198] Add GNU style link 'r-c.ce', 'r.c-re.ce' See https://www.gnu.org/prep/standards/html_node/Errors.html sourcefile:line1.column1-line2.column2: message sourcefile:line1.column1-column2: message sourcefile:line1-line2: message Fixes #190350 --- .../links/browser/terminalLinkParsing.ts | 12 ++++++++---- .../links/test/browser/terminalLinkParsing.test.ts | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts index 1e8b5bec80f..0c1a3dd16a0 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts @@ -63,9 +63,11 @@ function generateLinkSuffixRegex(eolOnly: boolean) { // The comments in the regex below use real strings/numbers for better readability, here's // the legend: - // - Path = foo - // - Row = 339 - // - Col = 12 + // - Path = foo + // - Row = 339 + // - Col = 12 + // - RowEnd = 341 + // - ColEnd = 14 // // These all support single quote ' in the place of " and [] in the place of () const lineAndColumnRegexClauses = [ @@ -78,7 +80,9 @@ function generateLinkSuffixRegex(eolOnly: boolean) { // "foo",339 // "foo",339:12 // "foo",339.12 - `(?::| |['"],)${r()}([:.]${c()})?` + eolSuffix, + // "foo",339.12-14 + // "foo",339.12-341.14 + `(?::| |['"],)${r()}([:.]${c()}(?:-(?:${re()}\.)?${ce()})?)?` + eolSuffix, // The quotes below are optional [#171652] // "foo", line 339 [#40468] // "foo", line 339, col 12 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 c200c575208..453b1f95ec4 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 @@ -47,6 +47,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-14', prefix: undefined, suffix: ' 339.12-14', hasRow: true, hasCol: true, hasRowEnd: false, hasColEnd: true }, + { link: 'foo 339.12-341.14', prefix: undefined, suffix: ' 339.12-341.14', hasRow: true, hasCol: true, hasRowEnd: true, hasColEnd: true }, // Double quotes { link: '"foo",339', prefix: '"', suffix: '",339', hasRow: true, hasCol: false }, From 24946e782463e5bd32601e5a0dfe32b3d97d39be Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Tue, 29 Aug 2023 15:13:28 +0200 Subject: [PATCH 056/198] fix #191374 --- .../environment/electron-main/environmentMainService.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/platform/environment/electron-main/environmentMainService.ts b/src/vs/platform/environment/electron-main/environmentMainService.ts index 748ff075783..aab03b3130f 100644 --- a/src/vs/platform/environment/electron-main/environmentMainService.ts +++ b/src/vs/platform/environment/electron-main/environmentMainService.ts @@ -6,6 +6,7 @@ import { memoize } from 'vs/base/common/decorators'; import { join } from 'vs/base/common/path'; import { isLinux } from 'vs/base/common/platform'; +import { URI } from 'vs/base/common/uri'; import { createStaticIPCHandle } from 'vs/base/parts/ipc/node/ipc.net'; import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; @@ -68,6 +69,9 @@ export class EnvironmentMainService extends NativeEnvironmentService implements @memoize get useCodeCache(): boolean { return !!this.codeCachePath; } + @memoize + override get userRoamingDataHome(): URI { return this.appSettingsHome; } + unsetSnapExportedVariables() { if (!isLinux) { return; From fbd61d106cd10077bd941abbd8a55af6858200ef Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 30 Aug 2023 00:14:02 +0900 Subject: [PATCH 057/198] chore: update distro (#191633) --- package.json | 2 +- remote/.yarnrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4dbaa275413..276a62f924f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.82.0", - "distro": "49cc0fbc0a8e222bcce2a7c3bf62e0d23f20d258", + "distro": "2100ad274ed566f978bb917f327b3d99f95d59f2", "author": { "name": "Microsoft Corporation" }, diff --git a/remote/.yarnrc b/remote/.yarnrc index c4421581246..26dc815d0f8 100644 --- a/remote/.yarnrc +++ b/remote/.yarnrc @@ -1,5 +1,5 @@ disturl "https://nodejs.org/dist" target "18.15.0" -ms_build_id "223745" +ms_build_id "229541" runtime "node" build_from_source "true" From 72d5c4d06c322e9d2602337cde5e7fea3eb2b90d Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Tue, 29 Aug 2023 08:20:30 -0700 Subject: [PATCH 058/198] quick search - file highlight decoration isn't showing up on search (#191544) Fixes #191539 --- .../quickTextSearch/textSearchQuickAccess.ts | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts index 6324613fbfd..14b1636c0b8 100644 --- a/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts +++ b/src/vs/workbench/contrib/search/browser/quickTextSearch/textSearchQuickAccess.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { CancellationToken } from 'vs/base/common/cancellation'; import { IMatch } from 'vs/base/common/filters'; -import { DisposableStore } from 'vs/base/common/lifecycle'; +import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle'; import { basenameOrAuthority, dirname } from 'vs/base/common/resources'; import { ThemeIcon } from 'vs/base/common/themables'; import { IRange, Range } from 'vs/editor/common/core/range'; @@ -15,8 +15,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ILabelService } from 'vs/platform/label/common/label'; import { WorkbenchCompressibleObjectTree, getSelectionKeyboardEvent } from 'vs/platform/list/browser/listService'; import { FastAndSlowPicks, IPickerQuickAccessItem, PickerQuickAccessProvider, Picks } from 'vs/platform/quickinput/browser/pickerQuickAccess'; -import { DefaultQuickAccessFilterValue } from 'vs/platform/quickinput/common/quickAccess'; -import { IKeyMods, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; +import { DefaultQuickAccessFilterValue, IQuickAccessProviderRunOptions } from 'vs/platform/quickinput/common/quickAccess'; +import { IKeyMods, IQuickPick, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IWorkbenchEditorConfiguration } from 'vs/workbench/common/editor'; import { IViewsService } from 'vs/workbench/common/views'; @@ -75,6 +75,19 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider, token: CancellationToken, runOptions?: IQuickAccessProviderRunOptions): IDisposable { + const disposables = new DisposableStore(); + disposables.add(super.provide(picker, token, runOptions)); + disposables.add(picker.onDidHide(() => this.searchModel.searchResult.toggleHighlights(false))); + disposables.add(picker.onDidAccept(() => this.searchModel.searchResult.toggleHighlights(false))); + return disposables; + } + private get configuration() { const editorConfig = this._configurationService.getValue().workbench?.editor; const searchConfig = this._configurationService.getValue().search; @@ -247,6 +260,9 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider 0) { + this.searchModel.searchResult.toggleHighlights(true); + } if (matches.length >= MAX_FILES_SHOWN) { return syncResult; @@ -254,9 +270,14 @@ export class TextSearchQuickAccess extends PickerQuickAccessProvider { - return this._getPicksFromMatches(asyncResults, MAX_FILES_SHOWN - matches.length); - }) + additionalPicks: allMatches.asyncResults + .then(asyncResults => this._getPicksFromMatches(asyncResults, MAX_FILES_SHOWN - matches.length)) + .then(picks => { + if (picks.length > 0) { + this.searchModel.searchResult.toggleHighlights(true); + } + return picks; + }) }; } From 4056fc822ab355a7d1603f4f5d701f8863be5cd6 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 29 Aug 2023 08:43:14 -0700 Subject: [PATCH 059/198] Dim settings and keybindings editors Fixes #191612 Fixes #191611 --- .../accessibility/browser/unfocusedViewDimmingContribution.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts index 1dc2b4b3605..5012089fda7 100644 --- a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts @@ -46,6 +46,10 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .monaco-editor { ${filterRule} }`); // Terminal editors rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .terminal-wrapper { ${filterRule} }`); + // Settings editor + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .settings-editor { ${filterRule} }`); + // Keybindings editor + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .keybindings-editor { ${filterRule} }`); cssTextContent = [...rules].join('\n'); } From a56713bb39e86aa4f0396dc892faecafaf7d4702 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 29 Aug 2023 08:43:17 -0700 Subject: [PATCH 060/198] add onDidRunText --- .../contrib/terminal/browser/terminal.ts | 1 + .../terminal/browser/terminalActions.ts | 11 +---------- .../terminal/browser/terminalInstance.ts | 3 +++ .../terminal.accessibility.contribution.ts | 18 +++++++++++++++--- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index bba8941c31b..c69c05e99d0 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -591,6 +591,7 @@ export interface ITerminalInstance { onDidBlur: Event; onDidInputData: Event; onDidChangeSelection: Event; + onDidRunText: Event; /** * An event that fires when a terminal is dropped on this instance via drag and drop. diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index 38423fb1e4c..2cc1e80827a 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -15,7 +15,7 @@ import { URI } from 'vs/base/common/uri'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EndOfLinePreference } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; -import { CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; import { Action2, registerAction2, IAction2Options } from 'vs/platform/actions/common/actions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -549,8 +549,6 @@ export function registerTerminalActions() { title: { value: localize('workbench.action.terminal.runSelectedText', "Run Selected Text In Active Terminal"), original: 'Run Selected Text In Active Terminal' }, run: async (c, accessor) => { const codeEditorService = accessor.get(ICodeEditorService); - const configurationService = accessor.get(IConfigurationService); - const accessibilityService = accessor.get(IAccessibilityService); const editor = codeEditorService.getActiveCodeEditor(); if (!editor || !editor.hasModel()) { return; @@ -566,13 +564,6 @@ export function registerTerminalActions() { } await instance.sendText(text, true, true); await c.service.revealActiveTerminal(); - const focusAfterRun = configurationService.getValue(TerminalSettingId.FocusAfterRun); - const focusTerminal = focusAfterRun === 'terminal' || (focusAfterRun === 'auto' && accessibilityService.isScreenReaderOptimized()); - if (focusTerminal) { - instance.focus(true); - } else if (focusAfterRun === 'accessible-buffer') { - instance.getContribution('terminal.accessible-buffer')?.requestFocus?.(); - } } }); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 3262f52d621..449e9fce543 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -322,6 +322,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { readonly onRequestAddInstanceToGroup = this._onRequestAddInstanceToGroup.event; private readonly _onDidChangeHasChildProcesses = this._register(new Emitter()); readonly onDidChangeHasChildProcesses = this._onDidChangeHasChildProcesses.event; + private readonly _onDidRunText = this._register(new Emitter()); + readonly onDidRunText = this._onDidRunText.event; constructor( private readonly _terminalShellTypeContextKey: IContextKey, @@ -1255,6 +1257,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { this._onDidInputData.fire(this); this.xterm?.suggestController?.handleNonXtermData(text); this.xterm?.scrollToBottom(); + this._onDidRunText.fire(); } async sendPath(originalPath: string | URI, addNewLine: boolean): Promise { diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 253c0837c09..0bdcf0a7803 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -6,12 +6,13 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { localize } from 'vs/nls'; -import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; +import { CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { IQuickPick, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; +import { TerminalSettingId, terminalTabFocusModeContextKey } from 'vs/platform/terminal/common/terminal'; import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions'; import { ITerminalContribution, ITerminalInstance, ITerminalService, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -59,9 +60,20 @@ class AccessibleBufferContribution extends DisposableStore implements ITerminalC private readonly _instance: ITerminalInstance, processManager: ITerminalProcessManager, widgetManager: TerminalWidgetManager, - @IInstantiationService private readonly _instantiationService: IInstantiationService + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @IConfigurationService configurationService: IConfigurationService, + @IAccessibilityService accessibilityService: IAccessibilityService ) { super(); + this.add(_instance.onDidRunText(() => { + const focusAfterRun = configurationService.getValue(TerminalSettingId.FocusAfterRun); + const focusTerminal = focusAfterRun === 'terminal' || (focusAfterRun === 'auto' && accessibilityService.isScreenReaderOptimized()); + if (focusTerminal) { + _instance.focus(true); + } else if (focusAfterRun === 'accessible-buffer') { + _instance.getContribution('terminal.accessible-buffer')?.requestFocus?.(); + } + })); } layout(xterm: IXtermTerminal & { raw: Terminal }): void { this._xterm = xterm; From 406091a9a2a4dd85f32f9dddc0aaa022e15d073c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 29 Aug 2023 08:47:09 -0700 Subject: [PATCH 061/198] Dim breadcrumbs Fixes #191608 --- .../accessibility/browser/unfocusedViewDimmingContribution.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts index 5012089fda7..f507e5b1d4c 100644 --- a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts @@ -44,6 +44,8 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor rules.add(`.monaco-workbench .pane-body.integrated-terminal .terminal-wrapper:not(:focus-within) { ${filterRule} }`); // Text editors rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .monaco-editor { ${filterRule} }`); + // Breadcrumbs + rules.add(`.monaco-workbench .editor-group-container:not(.active) .tabs-breadcrumbs { ${filterRule} }`); // Terminal editors rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .terminal-wrapper { ${filterRule} }`); // Settings editor From ea3214b632b2cefe27eb20b20b4996b2e1ba83e1 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 29 Aug 2023 08:47:42 -0700 Subject: [PATCH 062/198] revert some changes --- src/vs/workbench/contrib/terminal/browser/terminal.ts | 1 - src/vs/workbench/contrib/terminal/browser/terminalActions.ts | 4 +--- .../browser/terminal.accessibility.contribution.ts | 5 +---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index c69c05e99d0..4092072afd7 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -40,7 +40,6 @@ export const ITerminalInstanceService = createDecorator Date: Tue, 29 Aug 2023 08:50:47 -0700 Subject: [PATCH 063/198] Prefer .editor-group-container over .editor-instance --- .../browser/unfocusedViewDimmingContribution.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts index f507e5b1d4c..97e68034743 100644 --- a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts @@ -43,15 +43,15 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor // Terminals rules.add(`.monaco-workbench .pane-body.integrated-terminal .terminal-wrapper:not(:focus-within) { ${filterRule} }`); // Text editors - rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .monaco-editor { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-group-container:not(.active) .monaco-editor { ${filterRule} }`); // Breadcrumbs rules.add(`.monaco-workbench .editor-group-container:not(.active) .tabs-breadcrumbs { ${filterRule} }`); // Terminal editors - rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .terminal-wrapper { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-group-container:not(.active) .terminal-wrapper { ${filterRule} }`); // Settings editor - rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .settings-editor { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-group-container:not(.active) .settings-editor { ${filterRule} }`); // Keybindings editor - rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .keybindings-editor { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-group-container:not(.active) .keybindings-editor { ${filterRule} }`); cssTextContent = [...rules].join('\n'); } From caa82e0443e3267ba053139098fe527f2a840b75 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 29 Aug 2023 08:54:16 -0700 Subject: [PATCH 064/198] Dim editor placeholder Fixes #191614 --- .../accessibility/browser/unfocusedViewDimmingContribution.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts index 97e68034743..fade15e0f6e 100644 --- a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts @@ -36,6 +36,8 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor ); if (opacity !== 1) { + // These filter rules are more specific than may be expected as the `filter` + // rule can cause problems if it's used inside the element like on editor hovers const rules = new Set(); const filterRule = `filter: opacity(${opacity});`; // Terminal tabs @@ -52,6 +54,8 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor rules.add(`.monaco-workbench .editor-group-container:not(.active) .settings-editor { ${filterRule} }`); // Keybindings editor rules.add(`.monaco-workbench .editor-group-container:not(.active) .keybindings-editor { ${filterRule} }`); + // Editor placeholder (error case) + rules.add(`.monaco-workbench .editor-group-container:not(.active) .monaco-editor-pane-placeholder { ${filterRule} }`); cssTextContent = [...rules].join('\n'); } From b37772b7990e9cf699a1c29a1d543d5c86d55818 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 29 Aug 2023 08:55:40 -0700 Subject: [PATCH 065/198] Dim welcome editor Fixes #191613 --- .../accessibility/browser/unfocusedViewDimmingContribution.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts index fade15e0f6e..19712c0fa6e 100644 --- a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts @@ -56,6 +56,8 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor rules.add(`.monaco-workbench .editor-group-container:not(.active) .keybindings-editor { ${filterRule} }`); // Editor placeholder (error case) rules.add(`.monaco-workbench .editor-group-container:not(.active) .monaco-editor-pane-placeholder { ${filterRule} }`); + // Welcome editor + rules.add(`.monaco-workbench .editor-group-container:not(.active) .gettingStartedContainer { ${filterRule} }`); cssTextContent = [...rules].join('\n'); } From 64f1488b7e388e744cd80cd1bf5b238c9f193b0a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 29 Aug 2023 09:05:38 -0700 Subject: [PATCH 066/198] Dim unfocused setting feedback Fixes #191618 --- .../browser/accessibilityConfiguration.ts | 12 ++++++------ .../browser/unfocusedViewDimmingContribution.ts | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts index 2cd52bc8311..325a0afea94 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts @@ -21,8 +21,8 @@ export const accessibleViewCurrentProviderId = new RawContextKey('access * were better to live under workbench for discoverability. */ export const enum AccessibilityWorkbenchSettingId { - ViewDimUnfocusedEnabled = 'workbench.view.dimUnfocused.enabled', - ViewDimUnfocusedOpacity = 'workbench.view.dimUnfocused.opacity' + DimUnfocusedEnabled = 'accessibility.dimUnfocused.enabled', + DimUnfocusedOpacity = 'accessibility.dimUnfocused.opacity' } export const enum ViewDimUnfocusedOpacityProperties { @@ -120,15 +120,15 @@ export function registerAccessibilityConfiguration() { registry.registerConfiguration({ ...workbenchConfigurationNodeBase, properties: { - [AccessibilityWorkbenchSettingId.ViewDimUnfocusedEnabled]: { - description: localize('dimUnfocusedEnabled', 'Whether to dim unfocused editors and terminals, making the focused view more obvious.'), + [AccessibilityWorkbenchSettingId.DimUnfocusedEnabled]: { + description: localize('dimUnfocusedEnabled', 'Whether to dim unfocused editors and terminals, which makes it more clear where typed input will go to. This works with the majority of editors with the notable exceptions of those that utilize iframes like notebooks and extension webview editors.'), type: 'boolean', default: false, tags: ['accessibility'], scope: ConfigurationScope.APPLICATION, }, - [AccessibilityWorkbenchSettingId.ViewDimUnfocusedOpacity]: { - description: localize('dimUnfocusedOpacity', 'The opacity fraction (0.2 to 1.0) to use for unfocused editors and terminals. This will only take effect when {0} is enabled.', `\`#${AccessibilityWorkbenchSettingId.ViewDimUnfocusedEnabled}#\``), + [AccessibilityWorkbenchSettingId.DimUnfocusedOpacity]: { + description: localize('dimUnfocusedOpacity', 'The opacity fraction (0.2 to 1.0) to use for unfocused editors and terminals. This will only take effect when {0} is enabled.', `\`#${AccessibilityWorkbenchSettingId.DimUnfocusedEnabled}#\``), type: 'number', minimum: ViewDimUnfocusedOpacityProperties.Minimum, maximum: ViewDimUnfocusedOpacityProperties.Maximum, diff --git a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts index 19712c0fa6e..d4c7a06284c 100644 --- a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts @@ -21,16 +21,16 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor this._register(toDisposable(() => this._removeStyleElement())); this._register(Event.runAndSubscribe(configurationService.onDidChangeConfiguration, e => { - if (e && !e.affectsConfiguration(AccessibilityWorkbenchSettingId.ViewDimUnfocusedEnabled) && !e.affectsConfiguration(AccessibilityWorkbenchSettingId.ViewDimUnfocusedOpacity)) { + if (e && !e.affectsConfiguration(AccessibilityWorkbenchSettingId.DimUnfocusedEnabled) && !e.affectsConfiguration(AccessibilityWorkbenchSettingId.DimUnfocusedOpacity)) { return; } let cssTextContent = ''; - const enabled = ensureBoolean(configurationService.getValue(AccessibilityWorkbenchSettingId.ViewDimUnfocusedEnabled), false); + const enabled = ensureBoolean(configurationService.getValue(AccessibilityWorkbenchSettingId.DimUnfocusedEnabled), false); if (enabled) { const opacity = clamp( - ensureNumber(configurationService.getValue(AccessibilityWorkbenchSettingId.ViewDimUnfocusedOpacity), ViewDimUnfocusedOpacityProperties.Default), + ensureNumber(configurationService.getValue(AccessibilityWorkbenchSettingId.DimUnfocusedOpacity), ViewDimUnfocusedOpacityProperties.Default), ViewDimUnfocusedOpacityProperties.Minimum, ViewDimUnfocusedOpacityProperties.Maximum ); From 2af3045474f52bad8f14f01b09acfd5912e7fb5a Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 29 Aug 2023 10:28:37 -0700 Subject: [PATCH 067/198] tunnels: fix forwarding attempts wrong path to tunnel binary on linux (#191657) Fixes #191621 --- extensions/tunnel-forwarding/src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/tunnel-forwarding/src/extension.ts b/extensions/tunnel-forwarding/src/extension.ts index 3dd6fdfef19..83789934df5 100644 --- a/extensions/tunnel-forwarding/src/extension.ts +++ b/extensions/tunnel-forwarding/src/extension.ts @@ -25,7 +25,7 @@ const cliPath = process.env.VSCODE_FORWARDING_IS_DEV ? path.join(__dirname, '../../../cli/target/debug/code') : path.join( vscode.env.appRoot, - process.platform === 'win32' ? '../../bin' : 'bin', + process.platform === 'darwin' ? 'bin' : '../../bin', vscode.env.appQuality === 'stable' ? 'code-tunnel' : 'code-tunnel-insiders', ) + (process.platform === 'win32' ? '.exe' : ''); From a76ad82cad11dc5b0019585c61ae30ffa79d523b Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Tue, 29 Aug 2023 18:13:23 +0000 Subject: [PATCH 068/198] Amend --- src/vscode-dts/vscode.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 5a146bee7bb..4f5c61daaa7 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -11457,6 +11457,9 @@ declare module 'vscode' { clear(): void; } + /** + * A collection of mutations that an extension can apply to a process environment. Applies to all scopes. + */ export interface GlobalEnvironmentVariableCollection extends EnvironmentVariableCollection { /** * Gets scope-specific environment variable collection for the extension. This enables alterations to @@ -11471,6 +11474,8 @@ declare module 'vscode' { * If a scope parameter is omitted, collection applicable to all relevant scopes for that parameter is * returned. For instance, if the 'workspaceFolder' parameter is not specified, the collection that applies * across all workspace folders will be returned. + * + * @return Environment variable collection for the passed in scope. */ getScoped(scope: EnvironmentVariableScope): EnvironmentVariableCollection; } From 96ddbc4daad3129d444e9a0b49d5fa86177a8c3f Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 29 Aug 2023 21:13:55 +0200 Subject: [PATCH 069/198] Notification and notification buttons lack border radius (fix #191532) (#191557) --- .../browser/parts/notifications/notificationsViewer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts index 0be6eaf64c0..cb9d9b7ce0e 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsViewer.ts @@ -93,7 +93,7 @@ export class NotificationsListDelegate implements IListVirtualDelegate 1 */)}px`; // Render message into offset helper const renderedMessage = NotificationMessageRenderer.render(notification.message); From c63ccaba1c9f6659859645e134f67bc146e62781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Tue, 29 Aug 2023 21:32:59 +0200 Subject: [PATCH 070/198] add screencastMode.keyboardOptions.showKeybindings (#191686) fixes #179541 --- src/vs/workbench/browser/actions/developerActions.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/actions/developerActions.ts b/src/vs/workbench/browser/actions/developerActions.ts index 91297a82197..48c3f08a46e 100644 --- a/src/vs/workbench/browser/actions/developerActions.ts +++ b/src/vs/workbench/browser/actions/developerActions.ts @@ -94,6 +94,7 @@ class InspectContextKeysAction extends Action2 { interface IScreencastKeyboardOptions { readonly showKeys?: boolean; + readonly showKeybindings?: boolean; readonly showCommands?: boolean; readonly showCommandGroups?: boolean; readonly showSingleEditorCursorMoves?: boolean; @@ -315,7 +316,7 @@ class ToggleScreencastModeAction extends Action2 { append(keyboardMarker, $('span.title', {}, `${commandAndGroupLabel} `)); } - if (options.showKeys ?? true) { + if ((options.showKeys ?? true) || (command && (options.showKeybindings ?? true))) { // Fix label for arrow keys keyLabel = keyLabel?.replace('UpArrow', '↑') ?.replace('DownArrow', '↓') @@ -435,6 +436,11 @@ configurationRegistry.registerConfiguration({ default: true, description: localize('screencastMode.keyboardOptions.showKeys', "Show raw keys.") }, + 'showKeybindings': { + type: 'boolean', + default: true, + description: localize('screencastMode.keyboardOptions.showKeybindings', "Show keyboard shortcuts.") + }, 'showCommands': { type: 'boolean', default: true, @@ -453,6 +459,7 @@ configurationRegistry.registerConfiguration({ }, default: { 'showKeys': true, + 'showKeybindings': true, 'showCommands': true, 'showCommandGroups': false, 'showSingleEditorCursorMoves': true From 350bdb4b1be87cbe4ac2a612d9edcb70297a5a75 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 29 Aug 2023 12:50:28 -0700 Subject: [PATCH 071/198] Fix dim unfocused settings link Fixes #191643 --- .../contrib/accessibility/browser/accessibilityConfiguration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts index 325a0afea94..05812456635 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts @@ -128,7 +128,7 @@ export function registerAccessibilityConfiguration() { scope: ConfigurationScope.APPLICATION, }, [AccessibilityWorkbenchSettingId.DimUnfocusedOpacity]: { - description: localize('dimUnfocusedOpacity', 'The opacity fraction (0.2 to 1.0) to use for unfocused editors and terminals. This will only take effect when {0} is enabled.', `\`#${AccessibilityWorkbenchSettingId.DimUnfocusedEnabled}#\``), + markdownDescription: localize('dimUnfocusedOpacity', 'The opacity fraction (0.2 to 1.0) to use for unfocused editors and terminals. This will only take effect when {0} is enabled.', `\`#${AccessibilityWorkbenchSettingId.DimUnfocusedEnabled}#\``), type: 'number', minimum: ViewDimUnfocusedOpacityProperties.Minimum, maximum: ViewDimUnfocusedOpacityProperties.Maximum, From 1157f145b608edb87b90146536e64d68292990e3 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Tue, 29 Aug 2023 13:31:39 -0700 Subject: [PATCH 072/198] Use correct check for just focusing (#191696) fixes https://github.com/microsoft/vscode-internalbacklog/issues/4580 --- src/vs/workbench/contrib/chat/browser/chatQuick.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index 03420bc79b4..5545e1a5d03 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -59,8 +59,9 @@ export class QuickChatService extends Disposable implements IQuickChatService { this.open(providerId, query); } } + open(providerId?: string, query?: string | undefined): void { - if (this.focused) { + if (this._input) { return this.focus(); } From 9858757c41ab641b72b68845278b910c6fea8cdc Mon Sep 17 00:00:00 2001 From: Justin Chen <54879025+justschen@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:33:29 -0700 Subject: [PATCH 073/198] Action widget fuzzyMatch fix (#191687) fixes fuzzy matching confusion - makes sure only finds exact matching --- src/vs/base/browser/ui/list/listWidget.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index ee900068b4b..b077aa3ff69 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -532,13 +532,16 @@ class TypeNavigationController implements IDisposable { const prefix = matchesPrefix(word, labelStr); const fuzzy = matchesFuzzy2(word, labelStr); - // ensures that when fuzzy matching, it doesn't clash with prefix matching (1 input vs 1+ should be prefix and fuzzy respecitvely) - const fuzzyScore = fuzzy ? fuzzy[0].end - fuzzy[0].start : 0; - if (prefix || fuzzyScore > 1) { - this.previouslyFocused = start; - this.list.setFocus([index]); - this.list.reveal(index); - return; + if (fuzzy) { + const fuzzyScore = fuzzy[0].end - fuzzy[0].start; + + // ensures that when fuzzy matching, doesn't clash with prefix matching (1 input vs 1+ should be prefix and fuzzy respecitvely). Also makes sure that exact matches are prioritized. + if (prefix || (fuzzyScore > 1 && fuzzy.length === 1)) { + this.previouslyFocused = start; + this.list.setFocus([index]); + this.list.reveal(index); + return; + } } } } else { From 5413247e57fb7e3d29cd36f08266005fe72bbde4 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Tue, 29 Aug 2023 13:57:48 -0700 Subject: [PATCH 074/198] serve-web: delete socket file on server shutdown (#191692) Fixes #191691 --- cli/src/commands/serve_web.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/cli/src/commands/serve_web.rs b/cli/src/commands/serve_web.rs index 8d37427dd33..2181c6339a4 100644 --- a/cli/src/commands/serve_web.rs +++ b/cli/src/commands/serve_web.rs @@ -25,6 +25,7 @@ use crate::download_cache::DownloadCache; use crate::log; use crate::options::Quality; use crate::state::{LauncherPaths, PersistedState}; +use crate::tunnels::shutdown_signal::ShutdownRequest; use crate::update_service::{ unzip_downloaded_release, Platform, Release, TargetKind, UpdateService, }; @@ -98,12 +99,20 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result(service) } }; + let mut shutdown = ShutdownRequest::create_rx([ShutdownRequest::CtrlC]); let r = if let Some(s) = args.socket_path { - let socket = listen_socket_rw_stream(&PathBuf::from(&s)).await?; - ctx.log.result(format!("Web UI available on {}", s)); - Server::builder(socket.into_pollable()) + let s = PathBuf::from(&s); + let socket = listen_socket_rw_stream(&s).await?; + ctx.log + .result(format!("Web UI available on {}", s.display())); + let r = Server::builder(socket.into_pollable()) .serve(make_service_fn(|_| make_svc())) - .await + .with_graceful_shutdown(async { + let _ = shutdown.wait().await; + }) + .await; + let _ = std::fs::remove_file(&s); // cleanup + r } else { let addr: SocketAddr = match &args.host { Some(h) => { @@ -120,6 +129,9 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result Date: Tue, 29 Aug 2023 14:05:13 -0700 Subject: [PATCH 075/198] fix #191591 --- .../accessibility/browser/terminalAccessibilityHelp.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts index 206e04d47cc..9205be2e624 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts @@ -60,7 +60,14 @@ export class TerminalAccessibleContentProvider extends Disposable implements IAc const kb = this._keybindingService.lookupKeybindings(commandId); // Run recent command has multiple keybindings. lookupKeybinding just returns the first one regardless of the when context. // Thus, we have to check if accessibility mode is enabled to determine which keybinding to use. - return this._accessibilityService.isScreenReaderOptimized() ? format(msg, kb[1].getAriaLabel()) : format(msg, kb[0].getAriaLabel()); + const isScreenReaderOptimized = this._accessibilityService.isScreenReaderOptimized(); + if (isScreenReaderOptimized && kb[1]) { + format(msg, kb[1].getAriaLabel()); + } else if (kb[0]) { + format(msg, kb[0].getAriaLabel()); + } else { + return format(noKbMsg, commandId); + } } const kb = this._keybindingService.lookupKeybinding(commandId, this._contextKeyService)?.getAriaLabel(); return !kb ? format(noKbMsg, commandId) : format(msg, kb); From 16c0c5796ed44db224741b6899cd3e0b7c464d1e Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 29 Aug 2023 14:24:58 -0700 Subject: [PATCH 076/198] fix #191672 --- .../workbench/contrib/accessibility/browser/accessibleView.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 42e95d10c93..1f82f5c1e9b 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -506,9 +506,9 @@ class AccessibleView extends Disposable { let hint = ''; const disableKeybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.DisableVerbosityHint, this._contextKeyService)?.getAriaLabel(); if (disableKeybinding) { - hint = localize('acessibleViewDisableHint', "Disable the aria label hint to open this ({0}).\n", disableKeybinding); + hint = localize('acessibleViewDisableHint', "Disable accessibility verbosity for this feature ({0}). This will disable the hint to open the accessible view for example.\n", disableKeybinding); } else { - hint = localize('accessibleViewDisableHintNoKb', "Add a keybinding for the command Disable Accessible View Hint to disable this hint.\n"); + hint = localize('accessibleViewDisableHintNoKb', "Add a keybinding for the command Disable Accessible View Hint, which disables accessibility verbosity for this feature.\n"); } return hint; } From 3a597af3e6260df6dba8f47025b4c077eed4aa78 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 29 Aug 2023 14:33:50 -0700 Subject: [PATCH 077/198] fix #191684 --- .../accessibility/browser/accessibilityContributions.ts | 4 ++++ .../contrib/accessibility/browser/accessibleViewActions.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts index 720720b02df..90544aabea6 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityContributions.ts @@ -258,6 +258,10 @@ function getActionsFromNotification(notification: INotificationViewItem): IActio }; } } + const manageExtension = actions?.find(a => a.label.includes('Manage Extension')); + if (manageExtension) { + manageExtension.class = ThemeIcon.asClassName(Codicon.gear); + } if (actions) { actions.push({ id: 'clearNotification', label: localize('clearNotification', "Clear Notification"), tooltip: localize('clearNotification', "Clear Notification"), run: () => notification.close(), enabled: true, class: ThemeIcon.asClassName(Codicon.clearAll) }); } diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts index 21547678e51..0721b08a570 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleViewActions.ts @@ -160,7 +160,7 @@ class AccessibleViewDisableHintAction extends Action2 { primary: KeyMod.Alt | KeyCode.F6, weight: KeybindingWeight.WorkbenchContrib }, - icon: Codicon.treeFilterClear, + icon: Codicon.bellSlash, menu: [ commandPalette, { From 5c3a9678d8098374cf09bd184784f43b93817773 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Tue, 29 Aug 2023 14:46:55 -0700 Subject: [PATCH 078/198] fix #191722 --- .../accessibility/browser/accessibilityConfiguration.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts index 05812456635..384572c7402 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts @@ -42,7 +42,7 @@ export const enum AccessibilityVerbositySettingId { Editor = 'accessibility.verbosity.editor', Hover = 'accessibility.verbosity.hover', Notification = 'accessibility.verbosity.notification', - EditorUntitledHint = 'accessibility.verbosity.editor.untitledHint' + EditorUntitledHint = 'accessibility.verbosity.untitledHint' } export const enum AccessibleViewProviderId { @@ -107,7 +107,7 @@ const configuration: IConfigurationNode = { ...baseProperty }, [AccessibilityVerbositySettingId.EditorUntitledHint]: { - description: localize('verbosity.editor.untitledhint', 'Provide information about relevant actions in an untitled text editor.'), + description: localize('verbosity.untitledhint', 'Provide information about relevant actions in an untitled text editor.'), ...baseProperty } } From 86a82d46a838fc516cc19e3b4a69249232bf74c3 Mon Sep 17 00:00:00 2001 From: Michael Lively Date: Tue, 29 Aug 2023 15:42:20 -0700 Subject: [PATCH 079/198] Skip Nb Sticky Scroll testing on web platform. (#191716) * test change * skip notebook sticky scroll testing on web --- .../notebook/test/browser/notebookStickyScroll.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts b/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts index 708b8b7aea8..99cb8117b61 100644 --- a/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts +++ b/src/vs/workbench/contrib/notebook/test/browser/notebookStickyScroll.test.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; +import { isWeb } from 'vs/base/common/platform'; import { Event } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { mock } from 'vs/base/test/common/mock'; @@ -19,7 +20,7 @@ import { createNotebookCellList, setupInstantiationService, withTestNotebook } f import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline'; -suite('NotebookEditorStickyScroll', () => { +(isWeb ? suite.skip : suite)('NotebookEditorStickyScroll', () => { let disposables: DisposableStore; let instantiationService: TestInstantiationService; @@ -92,7 +93,6 @@ suite('NotebookEditorStickyScroll', () => { const notebookOutlineEntries = getOutline(editor).entries; const resultingMap = nbStickyTestHelper(domNode, editor, cellList, notebookOutlineEntries); - await assertSnapshot(resultingMap); }); }); From 4b82860e269125af32a53be167edf7f88c461845 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:45:50 -0700 Subject: [PATCH 080/198] Clicking into notebook markdown search result clears result (#191731) Fixes #191666 --- src/vs/workbench/contrib/search/browser/searchView.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/search/browser/searchView.ts b/src/vs/workbench/contrib/search/browser/searchView.ts index b87d1347816..dd150169376 100644 --- a/src/vs/workbench/contrib/search/browser/searchView.ts +++ b/src/vs/workbench/contrib/search/browser/searchView.ts @@ -1894,7 +1894,6 @@ export class SearchView extends ViewPane { pinned, selection, revealIfVisible: true, - indexedCellOptions: element instanceof MatchInNotebook ? { index: element.cellIndex, selection: element.range() } : undefined, }; try { From 20f00913476c551011c0ffc81f03493e8da72eb7 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 29 Aug 2023 17:46:46 -0700 Subject: [PATCH 081/198] Don't allow taking action on codeblocks in filtered responses (#191732) Fix microsoft/vscode-copilot#1148 --- .../browser/actions/chatCodeblockActions.ts | 24 +++++++++++++++++-- .../chat/browser/actions/chatTitleActions.ts | 4 ++-- .../contrib/chat/browser/chatListRenderer.ts | 13 ++++++++-- .../contrib/chat/common/chatContextKeys.ts | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts index 3761e137dc5..8439a5d14fd 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatCodeblockActions.ts @@ -11,8 +11,10 @@ import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { IBulkEditService, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { Range } from 'vs/editor/common/core/range'; +import { RelatedContextItem, WorkspaceEdit } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { ITextModel } from 'vs/editor/common/model'; +import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { CopyAction } from 'vs/editor/contrib/clipboard/browser/clipboard'; import { localize } from 'vs/nls'; import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; @@ -31,8 +33,6 @@ import { CellKind, NOTEBOOK_EDITOR_ID } from 'vs/workbench/contrib/notebook/comm import { ITerminalEditorService, ITerminalGroupService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; -import { WorkspaceEdit, RelatedContextItem } from 'vs/editor/common/languages'; export interface IChatCodeBlockActionContext { code: string; @@ -92,6 +92,11 @@ export function registerChatCodeBlockActions() { return; } + if (context.element.errorDetails?.responseIsFiltered) { + // When run from command palette + return; + } + const clipboardService = accessor.get(IClipboardService); clipboardService.writeText(context.code); @@ -183,6 +188,11 @@ export function registerChatCodeBlockActions() { const editorService = accessor.get(IEditorService); const textFileService = accessor.get(ITextFileService); + if (context.element.errorDetails?.responseIsFiltered) { + // When run from command palette + return; + } + if (editorService.activeEditorPane?.getId() === NOTEBOOK_EDITOR_ID) { return this.handleNotebookEditor(accessor, editorService.activeEditorPane.getControl() as INotebookEditor, context); } @@ -312,6 +322,11 @@ export function registerChatCodeBlockActions() { } override async runWithContext(accessor: ServicesAccessor, context: IChatCodeBlockActionContext) { + if (context.element.errorDetails?.responseIsFiltered) { + // When run from command palette + return; + } + const editorService = accessor.get(IEditorService); const chatService = accessor.get(IChatService); editorService.openEditor({ contents: context.code, languageId: context.languageId, resource: undefined }); @@ -358,6 +373,11 @@ export function registerChatCodeBlockActions() { } override async runWithContext(accessor: ServicesAccessor, context: IChatCodeBlockActionContext) { + if (context.element.errorDetails?.responseIsFiltered) { + // When run from command palette + return; + } + const chatService = accessor.get(IChatService); const terminalService = accessor.get(ITerminalService); const editorService = accessor.get(IEditorService); diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts index 19bd054e7b8..6d7a399b006 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.ts @@ -15,7 +15,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis import { ResourceNotebookCellEdit } from 'vs/workbench/contrib/bulkEdit/browser/bulkCellEdits'; import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions'; import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat'; -import { CONTEXT_IN_CHAT_INPUT, CONTEXT_IN_CHAT_SESSION, CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys'; +import { CONTEXT_IN_CHAT_INPUT, CONTEXT_IN_CHAT_SESSION, CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { IChatService, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService'; import { isRequestVM, isResponseVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser'; @@ -119,7 +119,7 @@ export function registerChatTitleActions() { id: MenuId.ChatMessageTitle, group: 'navigation', isHiddenByDefault: true, - when: ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR, CONTEXT_RESPONSE) + when: ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR, CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED.negate()) } }); } diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 1208e6134c3..06f2c24dfb6 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -61,7 +61,7 @@ import { IChatCodeBlockActionContext } from 'vs/workbench/contrib/chat/browser/a import { ChatTreeItem, IChatCodeBlockInfo, IChatFileTreeInfo } from 'vs/workbench/contrib/chat/browser/chat'; import { ChatFollowups } from 'vs/workbench/contrib/chat/browser/chatFollowups'; import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions'; -import { CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_HAS_PROVIDER_ID, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys'; +import { CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED, CONTEXT_RESPONSE_HAS_PROVIDER_ID, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys'; import { IChatReplyFollowup, IChatResponseProgressFileTreeData, IChatService, ISlashCommand, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService'; import { IChatResponseMarkdownRenderData, IChatResponseRenderData, IChatResponseViewModel, IChatWelcomeMessageViewModel, isRequestVM, isResponseVM, isWelcomeVM } from 'vs/workbench/contrib/chat/common/chatViewModel'; import { IWordCountResult, getNWords } from 'vs/workbench/contrib/chat/common/chatWordCounter'; @@ -268,10 +268,13 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer('chatSessionResponseHasProviderId', false, { type: 'boolean', description: localize('interactiveSessionResponseHasProviderId', "True when the provider has assigned an id to this response.") }); export const CONTEXT_RESPONSE_VOTE = new RawContextKey('chatSessionResponseVote', '', { type: 'string', description: localize('interactiveSessionResponseVote', "When the response has been voted up, is set to 'up'. When voted down, is set to 'down'. Otherwise an empty string.") }); +export const CONTEXT_RESPONSE_FILTERED = new RawContextKey('chatSessionResponseFiltered', false, { type: 'boolean', description: localize('chatResponseFiltered', "True when the chat response was filtered out by the server.") }); export const CONTEXT_CHAT_REQUEST_IN_PROGRESS = new RawContextKey('chatSessionRequestInProgress', false, { type: 'boolean', description: localize('interactiveSessionRequestInProgress', "True when the current request is still in progress.") }); export const CONTEXT_RESPONSE = new RawContextKey('chatResponse', false, { type: 'boolean', description: localize('chatResponse', "The chat item is a response.") }); From 046cfbf6d0b50a0cbd74d722451870bdcdacd30c Mon Sep 17 00:00:00 2001 From: Hans Date: Wed, 30 Aug 2023 09:04:15 +0800 Subject: [PATCH 082/198] add custom hover for quick open (#191416) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add custom hover for quick open * 💄 * 💄 * adjust delayer create logic --- .../platform/quickinput/browser/quickInput.ts | 2 +- .../browser/quickInputController.ts | 5 +- .../quickinput/browser/quickInputList.ts | 88 ++++++++++--------- .../quickinput/browser/quickInputService.ts | 6 -- 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/vs/platform/quickinput/browser/quickInput.ts b/src/vs/platform/quickinput/browser/quickInput.ts index 173bbc88096..4258cd0640a 100644 --- a/src/vs/platform/quickinput/browser/quickInput.ts +++ b/src/vs/platform/quickinput/browser/quickInput.ts @@ -47,7 +47,7 @@ export interface IQuickInputOptions { renderers: IListRenderer[], options: IListOptions, ): List; - hoverDelegate: IHoverDelegate; + hoverDelegate?: IHoverDelegate; styles: IQuickInputStyles; } diff --git a/src/vs/platform/quickinput/browser/quickInputController.ts b/src/vs/platform/quickinput/browser/quickInputController.ts index 85780828ce1..932eec180e1 100644 --- a/src/vs/platform/quickinput/browser/quickInputController.ts +++ b/src/vs/platform/quickinput/browser/quickInputController.ts @@ -83,12 +83,13 @@ export class QuickInputController extends Disposable { const titleBar = dom.append(container, $('.quick-input-titlebar')); - const leftActionBar = this._register(new ActionBar(titleBar)); + const actionBarOption = this.options.hoverDelegate ? { hoverDelegate: this.options.hoverDelegate } : undefined; + const leftActionBar = this._register(new ActionBar(titleBar, actionBarOption)); leftActionBar.domNode.classList.add('quick-input-left-action-bar'); const title = dom.append(titleBar, $('.quick-input-title')); - const rightActionBar = this._register(new ActionBar(titleBar)); + const rightActionBar = this._register(new ActionBar(titleBar, actionBarOption)); rightActionBar.domNode.classList.add('quick-input-right-action-bar'); const headerContainer = dom.append(container, $('.quick-input-header')); diff --git a/src/vs/platform/quickinput/browser/quickInputList.ts b/src/vs/platform/quickinput/browser/quickInputList.ts index e5914bfef84..bb8dc4c1429 100644 --- a/src/vs/platform/quickinput/browser/quickInputList.ts +++ b/src/vs/platform/quickinput/browser/quickInputList.ts @@ -541,46 +541,49 @@ export class QuickInputList { } })); - const delayer = new ThrottledDelayer(options.hoverDelegate.delay); - // onMouseOver triggers every time a new element has been moused over - // even if it's on the same list item. - this.disposables.push(this.list.onMouseOver(async e => { - // If we hover over an anchor element, we don't want to show the hover because - // the anchor may have a tooltip that we want to show instead. - if (e.browserEvent.target instanceof HTMLAnchorElement) { - delayer.cancel(); - return; - } - if ( - // anchors are an exception as called out above so we skip them here - !(e.browserEvent.relatedTarget instanceof HTMLAnchorElement) && - // check if the mouse is still over the same element - dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node) - ) { - return; - } - try { - await delayer.trigger(async () => { - if (e.element) { - this.showHover(e.element); - } - }); - } catch (e) { - // Ignore cancellation errors due to mouse out - if (!isCancellationError(e)) { - throw e; + if (options.hoverDelegate) { + const delayer = new ThrottledDelayer(options.hoverDelegate.delay); + // onMouseOver triggers every time a new element has been moused over + // even if it's on the same list item. + this.disposables.push(this.list.onMouseOver(async e => { + // If we hover over an anchor element, we don't want to show the hover because + // the anchor may have a tooltip that we want to show instead. + if (e.browserEvent.target instanceof HTMLAnchorElement) { + delayer.cancel(); + return; } - } - })); - this.disposables.push(this.list.onMouseOut(e => { - // onMouseOut triggers every time a new element has been moused over - // even if it's on the same list item. We only want one event, so we - // check if the mouse is still over the same element. - if (dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node)) { - return; - } - delayer.cancel(); - })); + if ( + // anchors are an exception as called out above so we skip them here + !(e.browserEvent.relatedTarget instanceof HTMLAnchorElement) && + // check if the mouse is still over the same element + dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node) + ) { + return; + } + try { + await delayer.trigger(async () => { + if (e.element) { + this.showHover(e.element); + } + }); + } catch (e) { + // Ignore cancellation errors due to mouse out + if (!isCancellationError(e)) { + throw e; + } + } + })); + this.disposables.push(this.list.onMouseOut(e => { + // onMouseOut triggers every time a new element has been moused over + // even if it's on the same list item. We only want one event, so we + // check if the mouse is still over the same element. + if (dom.isAncestor(e.browserEvent.relatedTarget as Node, e.element?.element as Node)) { + return; + } + delayer.cancel(); + })); + this.disposables.push(delayer); + } this.disposables.push(this._listElementChecked.event(_ => this.fireCheckedEvents())); this.disposables.push( this._onChangedAllVisibleChecked, @@ -590,8 +593,7 @@ export class QuickInputList { this._onButtonTriggered, this._onSeparatorButtonTriggered, this._onLeave, - this._onKeyDown, - delayer + this._onKeyDown ); } @@ -839,10 +841,14 @@ export class QuickInputList { * @param element The element to show the hover for */ private showHover(element: IListElement): void { + if (this.options.hoverDelegate === undefined) { + return; + } if (this._lastHover && !this._lastHover.isDisposed) { this.options.hoverDelegate.onDidHideHover?.(); this._lastHover?.dispose(); } + if (!element.element || !element.saneTooltip) { return; } diff --git a/src/vs/platform/quickinput/browser/quickInputService.ts b/src/vs/platform/quickinput/browser/quickInputService.ts index c4d20832264..924e6b83ef6 100644 --- a/src/vs/platform/quickinput/browser/quickInputService.ts +++ b/src/vs/platform/quickinput/browser/quickInputService.ts @@ -86,12 +86,6 @@ export class QuickInputService extends Themable implements IQuickInputService { renderers: IListRenderer[], options: IWorkbenchListOptions ) => this.instantiationService.createInstance(WorkbenchList, user, container, delegate, renderers, options) as List, - hoverDelegate: { - showHover(options, focus) { - return undefined; - }, - delay: 200 - }, styles: this.computeStyles() }; From ed40013ae9fc09ae0ed47fbc46115701c3323813 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Tue, 29 Aug 2023 20:28:51 -0700 Subject: [PATCH 083/198] Only decorate complete @ variables (#191733) --- .../browser/contrib/chatInputEditorContrib.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts index 8be40c833c1..d4ff01aec83 100644 --- a/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts +++ b/src/vs/workbench/contrib/chat/browser/contrib/chatInputEditorContrib.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { CancellationToken } from 'vs/base/common/cancellation'; +import { Iterable } from 'vs/base/common/iterator'; import { Disposable } from 'vs/base/common/lifecycle'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { Position } from 'vs/editor/common/core/position'; @@ -44,6 +45,7 @@ class InputEditorDecorations extends Disposable { @ICodeEditorService private readonly codeEditorService: ICodeEditorService, @IThemeService private readonly themeService: IThemeService, @IChatService private readonly chatService: IChatService, + @IChatVariablesService private readonly chatVariablesService: IChatVariablesService, ) { super(); @@ -175,21 +177,22 @@ class InputEditorDecorations extends Disposable { this.widget.inputEditor.setDecorationsByType(decorationDescription, slashCommandTextDecorationType, []); } - // const variables = this.chatVariablesService.getVariables(); + const variables = this.chatVariablesService.getVariables(); const variableReg = /(^|\s)@(\w+)(:\d+)?(?=(\s|$))/ig; let match: RegExpMatchArray | null; const varDecorations: IDecorationOptions[] = []; while (match = variableReg.exec(inputValue)) { - // const candidate = match[2]; - // if (Iterable.find(variables, v => v.name === candidate)) - varDecorations.push({ - range: { - startLineNumber: 1, - endLineNumber: 1, - startColumn: match.index! + match[1].length + 1, - endColumn: match.index! + match[0].length + 1 - } - }); + const varName = match[2]; + if (Iterable.find(variables, v => v.name === varName)) { + varDecorations.push({ + range: { + startLineNumber: 1, + endLineNumber: 1, + startColumn: match.index! + match[1].length + 1, + endColumn: match.index! + match[0].length + 1 + } + }); + } } this.widget.inputEditor.setDecorationsByType(decorationDescription, variableTextDecorationType, varDecorations); From 35be9bf683eace09796e59d54f1f225bbc3a7866 Mon Sep 17 00:00:00 2001 From: Robo Date: Wed, 30 Aug 2023 13:03:40 +0900 Subject: [PATCH 084/198] chore: update electron@25.7.0 (#191282) * chore: update electron@25.7.0 * chore: update internal build id * chore: bump distro --- .yarnrc | 4 +- build/checksums/electron.txt | 54 +++++++++---------- cgmanifest.json | 4 +- package.json | 4 +- .../api/node/extensionHostProcess.ts | 10 ---- yarn.lock | 8 +-- 6 files changed, 37 insertions(+), 47 deletions(-) diff --git a/.yarnrc b/.yarnrc index 8f658afd4a9..7b3fff4b526 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,5 +1,5 @@ disturl "https://electronjs.org/headers" -target "25.5.0" -ms_build_id "23084831" +target "25.7.0" +ms_build_id "23434598" runtime "electron" build_from_source "true" diff --git a/build/checksums/electron.txt b/build/checksums/electron.txt index f5c22bc1c23..a19497f08e8 100644 --- a/build/checksums/electron.txt +++ b/build/checksums/electron.txt @@ -1,27 +1,27 @@ -c3fb8cb4804143eb25fce55a179a6f2df8c215ed709104ec235c96e357b20f42 *electron-v25.5.0-darwin-arm64-symbols.zip -e6d2a09348d4fe7c9fbd92bf796489a95e625642f0f1ce96169212554cfa6841 *electron-v25.5.0-darwin-arm64.zip -15c28e613dfee0f7e46a296bb4aed64e17f9644d7ef19129aeb6480b8da230ab *electron-v25.5.0-darwin-x64-symbols.zip -a5c5c0b621daf8242258c89edb2387fbdf1c69125c984f8564d89b87927373e3 *electron-v25.5.0-darwin-x64.zip -69d60a69b7f692b9069cdf9e518bcbaca9cec561f40199cc87196929936a34ce *electron-v25.5.0-linux-arm64-symbols.zip -adec2ba09faf5f8d8af8997c8bed43c7712eba5546db1e7d06f8357bf4613921 *electron-v25.5.0-linux-arm64.zip -0fe7a5d152c9c401671e02ebcd9da34ab9bb0c28598ede3657077a79f8b3e70a *electron-v25.5.0-linux-armv7l-symbols.zip -eccb66e4a308a0bd2d90474894370e3d687e32f78672e6b5077c1822c7bc526b *electron-v25.5.0-linux-armv7l.zip -82bd9bc9e66f8ae802fe48a51b8d7e2fb599403e9715fa4b859190200a7376b1 *electron-v25.5.0-linux-x64-symbols.zip -485cbeb206fccfb4ed42f694100eebb80c9db6639b3537a95823c4fcb7f210cd *electron-v25.5.0-linux-x64.zip -ed2c2a7da571b53bcb336b9a2a024753a272df82ece45df83df888df51bf1912 *electron-v25.5.0-win32-arm64-pdb.zip -c316f6364e9b4cd61e19d4763c96abda7247a2c31ae7d30e81219c9a7754f11a *electron-v25.5.0-win32-arm64-symbols.zip -582ccbfc5a85a093f5639ee476bb5fef18c2d25dab4a60e5f5cb47e64c99f7fb *electron-v25.5.0-win32-arm64.zip -5776e650c23e3847b0c52d850f61c57a84a4fa30943c3cc82197250112911b5b *electron-v25.5.0-win32-ia32-pdb.zip -730b429ad2c4cae0fe3ba9600a6ee86c79dada77976bac1c75ca2404993495bc *electron-v25.5.0-win32-ia32-symbols.zip -7e6e68aa33a89c0d647575b06daf415a2401feb170ebb9cd795e221af321f751 *electron-v25.5.0-win32-ia32.zip -0792665fda9255b340a829cdd24601887a2ca8f04cc49f9a6d4557db0c0cd2f2 *electron-v25.5.0-win32-x64-pdb.zip -dc2459546951f8418e866857e9111dd83a0789d401906b2200c2f8dd59d9146b *electron-v25.5.0-win32-x64-symbols.zip -9bf7980fbc024ba77ea8ab3e2d32088a5f69bf32506a7d2db72ede17028abdf4 *electron-v25.5.0-win32-x64.zip -5b1ea601b737842eacf88d7456c4d14e697822753e9a08ede889cce9e20bafb2 *ffmpeg-v25.5.0-darwin-arm64.zip -37bf5c75edefc0b6735b44d0b5b06fdd427179a8501f6e93df9840283cdb4a95 *ffmpeg-v25.5.0-darwin-x64.zip -bd52d57ff97fb56ac01a3482af905d04f0d4e9c13c53858c6d9f99957eca82da *ffmpeg-v25.5.0-linux-arm64.zip -9b3d09177fa1e63e2a6beecfa70aeec30aeb5c1873ff21128a68051c4e23f95d *ffmpeg-v25.5.0-linux-armv7l.zip -edc7b1c9f1a0733f109a2c0375a4e40c5bfe0bf28b7f06dcc76e1ada0aa2f125 *ffmpeg-v25.5.0-linux-x64.zip -2e28767b3570ea247869a20988cddd23af710eb994d6099404f123390cedeba6 *ffmpeg-v25.5.0-win32-arm64.zip -715568eefd7267573a30186ade3de901587baeb1f013200d8ae50b35941b613f *ffmpeg-v25.5.0-win32-ia32.zip -29876504452aaa505f696642178968e24b8dc8cc4b055071e6f0f3f073088acc *ffmpeg-v25.5.0-win32-x64.zip +efbcf77eb1a0783766f9579ffb9f9b68f04fea8cb091eab7ab8484ba0cd13fbf *electron-v25.7.0-darwin-arm64-symbols.zip +76a415165d212a345a5689de83078adc715fc10562bfaa35d7323094780ba683 *electron-v25.7.0-darwin-arm64.zip +07b9049848e877019d1dce71e06713125b605dda8ac5d0b8ab3aa899cf40551d *electron-v25.7.0-darwin-x64-symbols.zip +dea726ae9adc1c36206ce8d20ce32f630bcd684b869e0cb302f97c8bd26616d6 *electron-v25.7.0-darwin-x64.zip +b6c8ba123353984b2d3ffd6ccd52aec2d3238f71611c4c94bab75aa92804eebf *electron-v25.7.0-linux-arm64-symbols.zip +19e1e2c7ea1ab024f069e3dad6a26605e14b2c605e134484196343118fccf925 *electron-v25.7.0-linux-arm64.zip +ba0bbe84ea626c8064809c66487a3b77ad39bcf8b1daa0d9421428f78ad4d665 *electron-v25.7.0-linux-armv7l-symbols.zip +832a68cddb20eb847aca982b89f89e145f50dd483c71c8a705bbb9248fb7c665 *electron-v25.7.0-linux-armv7l.zip +2e616b446112533d3aa69ed1074ab1e0be5400996129aa636273d01462dc9506 *electron-v25.7.0-linux-x64-symbols.zip +002641e8103b77060e23b9c77c51ffb942372d01306210cdc3d32fc6ae5d112b *electron-v25.7.0-linux-x64.zip +162e0f7ca9fc1c17b8d84e9b9eccc65bb0f527a67f6339a19292d798085848e4 *electron-v25.7.0-win32-arm64-pdb.zip +7d98734ffcf10e1d002c30a212dd1f203b1418a295da67410490f83e9ced388c *electron-v25.7.0-win32-arm64-symbols.zip +9777d47f74d129f7c68ebffad640a6a527b83895c173c7d344f80fc9588bad85 *electron-v25.7.0-win32-arm64.zip +c805c6356378dccb21b5725004934534e187bdaf8149a6a457fdd60d243b41e4 *electron-v25.7.0-win32-ia32-pdb.zip +5f1a3b09153cf934f24f3b1853ad1788e7c27c6ddceb80e52fe07e2e69b6bb2b *electron-v25.7.0-win32-ia32-symbols.zip +fdf8e100c3d3cdb75b54ced1ecae96d6206eca08ebb07c5d8f08740e5e703509 *electron-v25.7.0-win32-ia32.zip +aa56314a675351e9457355f2cb0660c62a3be62cc340dad76fd216741064824d *electron-v25.7.0-win32-x64-pdb.zip +25d664dfe0823e1a12269feb6eb3886dba44b2d130b8787c4d58d3d0cbcf1c22 *electron-v25.7.0-win32-x64-symbols.zip +7ddb0b38207fd837cdf4e2b2778c365751315e321b09d346c8bb8476300d0ec0 *electron-v25.7.0-win32-x64.zip +02619733aadb13b6bf21df966e04775506d0d7595a0795003fed45631c4a0af6 *ffmpeg-v25.7.0-darwin-arm64.zip +69a8e2021e48f504021913c15633cbef2b4a7b28656c51cd238acdbf7c94e358 *ffmpeg-v25.7.0-darwin-x64.zip +bd52d57ff97fb56ac01a3482af905d04f0d4e9c13c53858c6d9f99957eca82da *ffmpeg-v25.7.0-linux-arm64.zip +9b3d09177fa1e63e2a6beecfa70aeec30aeb5c1873ff21128a68051c4e23f95d *ffmpeg-v25.7.0-linux-armv7l.zip +edc7b1c9f1a0733f109a2c0375a4e40c5bfe0bf28b7f06dcc76e1ada0aa2f125 *ffmpeg-v25.7.0-linux-x64.zip +7076d4593f2e2e2abf0dc9ad8f6490d72b2fa89710def822f39da4363e49e504 *ffmpeg-v25.7.0-win32-arm64.zip +bd07183c1b6a93586d73c4106ceef0faae77f46763d15d6901d5954c2c5bba1b *ffmpeg-v25.7.0-win32-ia32.zip +b056e71a7c59441c551d5bbc1a8d99f2464a5809a3ba17d41540dc7174cab7b7 *ffmpeg-v25.7.0-win32-x64.zip diff --git a/cgmanifest.json b/cgmanifest.json index 574ec75d24d..df2f75f3209 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -528,12 +528,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "34be316c404e84cdd967fa0e10fceeb6424eed90" + "commitHash": "f818ec3295c9688585e3cfea532ccc5b705746bb" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "25.5.0" + "version": "25.7.0" }, { "component": { diff --git a/package.json b/package.json index 276a62f924f..0af191524ed 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.82.0", - "distro": "2100ad274ed566f978bb917f327b3d99f95d59f2", + "distro": "c7d53f94cfb25168c3c3ae9a6f4902d32643a0ee", "author": { "name": "Microsoft Corporation" }, @@ -150,7 +150,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.8.0", - "electron": "25.5.0", + "electron": "25.7.0", "eslint": "8.36.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", diff --git a/src/vs/workbench/api/node/extensionHostProcess.ts b/src/vs/workbench/api/node/extensionHostProcess.ts index 860800e3f84..bb3cbfbca7b 100644 --- a/src/vs/workbench/api/node/extensionHostProcess.ts +++ b/src/vs/workbench/api/node/extensionHostProcess.ts @@ -6,7 +6,6 @@ import * as nativeWatchdog from 'native-watchdog'; import * as net from 'net'; import * as minimist from 'minimist'; -import * as dns from 'dns'; import * as performance from 'vs/base/common/performance'; import type { MessagePortMain } from 'vs/base/parts/sandbox/node/electronTypes'; import { isCancellationError, isSigPipeError, onUnexpectedError } from 'vs/base/common/errors'; @@ -47,15 +46,6 @@ interface ParsedExtHostArgs { } })(); -// TODO(deepak1556): Remove this once -// https://github.com/electron/electron/pull/39376 -// is available. The following API call is needed to get our -// remote integration tests to pass. -(function configureDnsResultOrder() { - // Refs https://github.com/microsoft/vscode/issues/189805 - dns.setDefaultResultOrder('ipv4first'); -})(); - const args = minimist(process.argv.slice(2), { boolean: [ 'transformURIs', diff --git a/yarn.lock b/yarn.lock index 582d6e845a1..e171d0e0f55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3587,10 +3587,10 @@ electron-to-chromium@^1.4.202: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.207.tgz#9c3310ebace2952903d05dcaba8abe3a4ed44c01" integrity sha512-piH7MJDJp4rJCduWbVvmUd59AUne1AFBJ8JaRQvk0KzNTSUnZrVXHCZc+eg+CGE4OujkcLJznhGKD6tuAshj5Q== -electron@25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/electron/-/electron-25.5.0.tgz#6465d49c0731424e3e48776628c35771697caf11" - integrity sha512-w1DNj1LuAk0Vaas1rQ0pAkTe2gZ5YG75J27mC2m88y0G6Do5b5YoFDaF84fOGQHeQ4j8tC5LngSgWhbwmqDlrw== +electron@25.7.0: + version "25.7.0" + resolved "https://registry.yarnpkg.com/electron/-/electron-25.7.0.tgz#0076c2e6acfe363f666a7b77d826a6f8a3028bcd" + integrity sha512-P82EzYZ8k9J21x5syhXV7EkezDmEXwycReXnagfzS0kwepnrlWzq1aDIUWdNvzTdHobky4m/nYcL98qd73mEVA== dependencies: "@electron/get" "^2.0.0" "@types/node" "^18.11.18" From 82348c380c484b77a3ad03566534a4735fa391c6 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 30 Aug 2023 11:19:11 +0200 Subject: [PATCH 085/198] fix #191734 (#191756) --- .../node/extensionManagementService.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index 677149f937b..9b8ba9a1b42 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -152,12 +152,13 @@ export class ExtensionManagementService extends AbstractExtensionManagementServi throw new Error(nls.localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extensionId, this.productService.version)); } - const result = await this.installExtensions([{ manifest, extension: location, options }]); - if (result[0]?.local) { - return result[0]?.local; + const results = await this.installExtensions([{ manifest, extension: location, options }]); + const result = results.find(({ identifier }) => areSameExtensions(identifier, { id: extensionId })); + if (result?.local) { + return result.local; } - if (result[0]?.error) { - throw result[0].error; + if (result?.error) { + throw result.error; } throw toExtensionManagementError(new Error(`Unknown error while installing extension ${extensionId}`)); } finally { From ebfe7fabfb11c763896c20c09ea6b386fbf021e3 Mon Sep 17 00:00:00 2001 From: Johannes Date: Wed, 30 Aug 2023 11:37:44 +0200 Subject: [PATCH 086/198] wip - define jsdoc lint rules for vscode.d.ts --- .eslintrc.json | 41 +++++++++++++++++++++++++++ package.json | 2 +- yarn.lock | 76 +++++++++++++++++++++++++++++--------------------- 3 files changed, 86 insertions(+), 33 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 0644079623d..b2c303da84a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -196,6 +196,47 @@ ] } }, + { + "files": [ + "**/vscode.d.ts" + ], + "rules": { + "extends": [ + "plugin:jsdoc/recommended-typescript" + ], + "jsdoc/tag-lines": "off", + "jsdoc/valid-types": "off", + "jsdoc/no-multi-asterisks": [ + "warn", + { + "allowWhitespace": true + } + ], + "jsdoc/require-jsdoc": [ + "warn", + { + "enableFixer": false, + "contexts": [ + "TSInterfaceDeclaration", + "TSPropertySignature", + "TSMethodSignature", + "ClassDeclaration", + "MethodDefinition", + "PropertyDeclaration", + "TSEnumDeclaration", + "TSEnumMember", + "ExportNamedDeclaration" + ] + } + ], + "jsdoc/check-param-names": [ + "warn", + { + "enableFixer": false + } + ] + } + }, { "files": [ "src/**/{common,browser}/**/*.ts" diff --git a/package.json b/package.json index 4dbaa275413..99b6034460c 100644 --- a/package.json +++ b/package.json @@ -153,7 +153,7 @@ "electron": "25.5.0", "eslint": "8.36.0", "eslint-plugin-header": "3.1.1", - "eslint-plugin-jsdoc": "^39.3.2", + "eslint-plugin-jsdoc": "^46.5.0", "eslint-plugin-local": "^1.0.0", "event-stream": "3.3.4", "fancy-log": "^1.3.3", diff --git a/yarn.lock b/yarn.lock index 582d6e845a1..e651e4a891d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -325,14 +325,14 @@ optionalDependencies: global-agent "^3.0.0" -"@es-joy/jsdoccomment@~0.31.0": - version "0.31.0" - resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz#dbc342cc38eb6878c12727985e693eaef34302bc" - integrity sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ== +"@es-joy/jsdoccomment@~0.40.1": + version "0.40.1" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz#13acd77fb372ed1c83b7355edd865a3b370c9ec4" + integrity sha512-YORCdZSusAlBrFpZ77pJjc5r1bQs5caPWtAu+WWmiSo+8XaUzseapVrfAtiRFbQWnrBxxLLEwF6f6ZG/UgCQCg== dependencies: - comment-parser "1.3.1" - esquery "^1.4.0" - jsdoc-type-pratt-parser "~3.1.0" + comment-parser "1.4.0" + esquery "^1.5.0" + jsdoc-type-pratt-parser "~4.0.0" "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" @@ -1841,6 +1841,11 @@ archy@^1.0.0: resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= +are-docs-informative@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/are-docs-informative/-/are-docs-informative-0.0.2.tgz#387f0e93f5d45280373d387a59d34c96db321963" + integrity sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig== + are-we-there-yet@~1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" @@ -2289,6 +2294,11 @@ buffer@^5.2.1, buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + bytes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -2797,10 +2807,10 @@ commandpost@^1.0.0: resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.2.1.tgz#2e9c4c7508b9dc704afefaa91cab92ee6054cc68" integrity sha512-V1wzc+DTFsO96te2W/U+fKNRSOWtOwXhkkZH2WRLLbucrY+YrDNsRr4vtfSf83MUZVF3E6B4nwT30fqaTpzipQ== -comment-parser@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b" - integrity sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA== +comment-parser@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.0.tgz#0f8c560f59698193854f12884c20c0e39a26d32c" + integrity sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw== component-emitter@^1.2.1: version "1.3.0" @@ -3822,17 +3832,19 @@ eslint-plugin-header@3.1.1: resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6" integrity sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg== -eslint-plugin-jsdoc@^39.3.2: - version "39.3.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.2.tgz#b9c3becdbd860a75b8bd07bd04a0eaaad7c79403" - integrity sha512-RSGN94RYzIJS/WfW3l6cXzRLfJWxvJgNQZ4w0WCaxJWDJMigtwTsILEAfKqmmPkT2rwMH/s3C7G5ChDE6cwPJg== +eslint-plugin-jsdoc@^46.5.0: + version "46.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.5.0.tgz#02e7945701a01fab76e7ced850d4d1eea63c23c0" + integrity sha512-aulXdA4I1dyWpzyS1Nh/GNoS6PavzeucxEapnMR4JUERowWvaEk2Y4A5irpHAcdXtBBHLVe8WIhdXNjoAlGQgA== dependencies: - "@es-joy/jsdoccomment" "~0.31.0" - comment-parser "1.3.1" + "@es-joy/jsdoccomment" "~0.40.1" + are-docs-informative "^0.0.2" + comment-parser "1.4.0" debug "^4.3.4" escape-string-regexp "^4.0.0" - esquery "^1.4.0" - semver "^7.3.7" + esquery "^1.5.0" + is-builtin-module "^3.2.1" + semver "^7.5.4" spdx-expression-parse "^3.0.1" eslint-plugin-local@^1.0.0: @@ -3999,14 +4011,7 @@ esquery@^1.0.1: dependencies: estraverse "^5.1.0" -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esquery@^1.4.2: +esquery@^1.4.2, esquery@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== @@ -5683,6 +5688,13 @@ is-buffer@^1.1.5, is-buffer@~1.1.1: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-builtin-module@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + is-callable@^1.1.4, is-callable@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" @@ -6143,10 +6155,10 @@ jschardet@3.0.0: resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-3.0.0.tgz#898d2332e45ebabbdb6bf2feece9feea9a99e882" integrity sha512-lJH6tJ77V8Nzd5QWRkFYCLc13a3vADkh3r/Fi8HupZGWk2OVVDfnZP8V/VgQgZ+lzW0kG2UGb5hFgt3V3ndotQ== -jsdoc-type-pratt-parser@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz#a4a56bdc6e82e5865ffd9febc5b1a227ff28e67e" - integrity sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw== +jsdoc-type-pratt-parser@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz#136f0571a99c184d84ec84662c45c29ceff71114" + integrity sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ== jsesc@^2.5.1: version "2.5.2" @@ -8895,7 +8907,7 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: +semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== From 4a0169c45c6614c59ffa81daf2c9bf963a007957 Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 30 Aug 2023 11:50:58 +0200 Subject: [PATCH 087/198] fix #191022 (#191760) --- .../common/extensionManagementChannelClient.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts b/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts index 305332829c9..c0815fcd50f 100644 --- a/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts +++ b/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ILocalExtension, IGalleryExtension, InstallOptions, InstallVSIXOptions, UninstallOptions, Metadata, DidUninstallExtensionEvent, InstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ILocalExtension, IGalleryExtension, InstallOptions, InstallVSIXOptions, UninstallOptions, Metadata, DidUninstallExtensionEvent, InstallExtensionEvent, InstallExtensionResult, UninstallExtensionEvent, InstallExtensionInfo } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; import { ExtensionIdentifier, ExtensionType, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; import { ExtensionManagementChannelClient as BaseExtensionManagementChannelClient, ExtensionEventResult } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; @@ -76,6 +76,14 @@ export abstract class ProfileAwareExtensionManagementChannelClient extends BaseE return super.installFromGallery(extension, installOptions); } + override async installGalleryExtensions(extensions: InstallExtensionInfo[]): Promise { + const infos: InstallExtensionInfo[] = []; + for (const extension of extensions) { + infos.push({ ...extension, options: { ...extension.options, profileLocation: extension.options?.profileLocation ? (await this.getProfileLocation(extension.options?.profileLocation)) : undefined } }); + } + return super.installGalleryExtensions(infos); + } + override async uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise { options = { ...options, profileLocation: await this.getProfileLocation(options?.profileLocation) }; return super.uninstall(extension, options); From 32d0dbf4d08633d305bd0a893eeebd9100a69cd5 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 11:42:58 +0200 Subject: [PATCH 088/198] Fixes #191664 --- .../browser/widget/diffEditorWidget2/unchangedRanges.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index 5b5c4ecc2a9..73d56045a0e 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -94,7 +94,7 @@ export class UnchangedRangesFeature extends Disposable { const d = derived(reader => /** @description hiddenOriginalRangeStart */ r.getHiddenOriginalRange(reader).startLineNumber - 1); const origVz = new PlaceholderViewZone(d, 24); origViewZones.push(origVz); - store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, r.originalRange, !sideBySide, modifiedOutlineSource, l => this._diffModel.get()!.ensureOriginalLineIsVisible(l, undefined), this._options)); + store.add(new CollapsedCodeOverlayWidget(this._editors.original, origVz, r, r.originalRange, !sideBySide, modifiedOutlineSource, l => this._diffModel.get()!.ensureModifiedLineIsVisible(l, undefined), this._options)); } { const d = derived(reader => /** @description hiddenModifiedRangeStart */ r.getHiddenModifiedRange(reader).startLineNumber - 1); @@ -265,7 +265,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { private readonly _unchangedRegionRange: LineRange, private readonly hide: boolean, private readonly _modifiedOutlineSource: OutlineSource, - private readonly _revealHiddenLine: (lineNumber: number) => void, + private readonly _revealModifiedHiddenLine: (lineNumber: number) => void, private readonly _options: DiffEditorOptions, ) { const root = h('div.diff-hidden-lines-widget'); @@ -396,7 +396,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { ]).root; children.push(divItem); divItem.onclick = () => { - this._revealHiddenLine(item.startLineNumber); + this._revealModifiedHiddenLine(item.startLineNumber); }; } } From e77c84f0a744563a1753f6243898eafcbf3301f3 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 30 Aug 2023 12:07:53 +0200 Subject: [PATCH 089/198] Configure Tunnel Name leads to empty settings page for WSL (#191761) --- .../electron-sandbox/remoteTunnel.contribution.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts b/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts index c71388d51fb..145c7c81a1e 100644 --- a/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts +++ b/src/vs/workbench/contrib/remoteTunnel/electron-sandbox/remoteTunnel.contribution.ts @@ -789,7 +789,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis [CONFIGURATION_KEY_HOST_NAME]: { description: localize('remoteTunnelAccess.machineName', "The name under which the remote tunnel access is registered. If not set, the host name is used."), type: 'string', - scope: ConfigurationScope.MACHINE, + scope: ConfigurationScope.APPLICATION, pattern: '^(\\w[\\w-]*)?$', patternErrorMessage: localize('remoteTunnelAccess.machineNameRegex', "The name must only consist of letters, numbers, underscore and dash. It must not start with a dash."), maxLength: 20, @@ -798,7 +798,7 @@ Registry.as(ConfigurationExtensions.Configuration).regis [CONFIGURATION_KEY_PREVENT_SLEEP]: { description: localize('remoteTunnelAccess.preventSleep', "Prevent the computer from sleeping when remote tunnel access is turned on."), type: 'boolean', - scope: ConfigurationScope.MACHINE, + scope: ConfigurationScope.APPLICATION, default: false, } } From 662ce156c09b569a24c1de6141c5ef2b9c66dc4f Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 12:03:55 +0200 Subject: [PATCH 090/198] Fixes #191637 --- .../editor/browser/widget/diffEditorWidget2/unchangedRanges.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index 73d56045a0e..bd1af6d94f9 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -250,7 +250,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { private readonly _nodes = h('div.diff-hidden-lines', [ h('div.top@top', { title: localize('diff.hiddenLines.top', 'Click or drag to show more above') }), h('div.center@content', { style: { display: 'flex' } }, [ - h('div@first', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' } }, + h('div@first', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center', flexShrink: '0' } }, [$('a', { title: localize('showAll', 'Show all'), role: 'button', onclick: () => { this.showAll(); } }, ...renderLabelWithIcons('$(unfold)'))] ), h('div@others', { style: { display: 'flex', justifyContent: 'center', alignItems: 'center' } }), From c39b2fffa65713e69c56f77a64bd0bc76483b6d6 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 12:05:18 +0200 Subject: [PATCH 091/198] Fixes #191600 --- .../editor/browser/widget/diffEditorWidget2/unchangedRanges.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts index bd1af6d94f9..a61dc81803b 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/unchangedRanges.ts @@ -365,7 +365,7 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget { const children: HTMLElement[] = []; if (!this.hide) { const lineCount = _unchangedRegion.getHiddenModifiedRange(reader).length; - const linesHiddenText = localize('hiddenLines', '{0} Hidden Lines', lineCount); + const linesHiddenText = localize('hiddenLines', '{0} hidden lines', lineCount); const span = $('span', { title: localize('diff.hiddenLines.expandAll', 'Double click to unfold') }, linesHiddenText); span.addEventListener('dblclick', e => { if (e.button !== 0) { return; } From 19c238294cb6793aa4d34c8fcdd7746e237cb101 Mon Sep 17 00:00:00 2001 From: troy351 <914053923@qq.com> Date: Wed, 30 Aug 2023 18:24:37 +0800 Subject: [PATCH 092/198] listWidget: remove redundant logic (#191054) --- src/vs/base/browser/ui/list/listWidget.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index b077aa3ff69..262d3ca9e2e 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -732,10 +732,6 @@ export class MouseController implements IDisposable { return; } - if (this.isSelectionRangeChangeEvent(e)) { - return this.changeSelection(e); - } - if (this.isSelectionChangeEvent(e)) { return this.changeSelection(e); } From 4bd1ea339fa9c1e0d5c6a8f39c5b351ae167a4c5 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 12:19:07 +0200 Subject: [PATCH 093/198] Fixes #191603 --- .../editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts index 27a9f8f46fb..8a3ac863ddc 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts @@ -324,7 +324,7 @@ class MovedBlockOverlayWidget extends ViewZoneOverlayWidget { true, () => { this._editor.focus(); - this._diffModel.movedTextToCompare.set(this._diffModel.movedTextToCompare.get() ? undefined : this._move, undefined); + this._diffModel.movedTextToCompare.set(this._diffModel.movedTextToCompare.get() === _move ? undefined : this._move, undefined); }, ); this._register(autorun(reader => { From adf839e3564d0a3522249c4f94df518b8ed49067 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 30 Aug 2023 12:42:51 +0200 Subject: [PATCH 094/198] changing the setting text --- src/vs/editor/common/config/editorOptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index f338f7b0817..35979acc29f 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -2799,7 +2799,7 @@ class EditorStickyScroll extends BaseEditorOption Date: Wed, 30 Aug 2023 14:42:02 +0200 Subject: [PATCH 095/198] voice - fix issues around stopping transcription (#191774) --- src/vs/base/common/event.ts | 18 ++ src/vs/base/test/common/event.test.ts | 44 ++- .../actions/voiceChatActions.ts | 257 +++++++++++------- .../browser/inlineChatController.ts | 1 + 4 files changed, 218 insertions(+), 102 deletions(-) diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 52a4b2d20f6..c26c0271f39 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -557,6 +557,24 @@ export namespace Event { return new Promise(resolve => once(event)(resolve)); } + /** + * Creates an event out of a promise that fires once when the promise is + * resolved with the result of the promise or `undefined`. + */ + export function fromPromise(promise: Promise): Event { + const result = new Emitter(); + + promise.then(res => { + result.fire(res); + }, () => { + result.fire(undefined); + }).finally(() => { + result.dispose(); + }); + + return result.event; + } + /** * Adds a listener to an event and calls the listener immediately with undefined as the event object. * diff --git a/src/vs/base/test/common/event.test.ts b/src/vs/base/test/common/event.test.ts index 8f14d7d47cd..30320370f2a 100644 --- a/src/vs/base/test/common/event.test.ts +++ b/src/vs/base/test/common/event.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { stub } from 'sinon'; -import { timeout } from 'vs/base/common/async'; +import { DeferredPromise, timeout } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { errorHandler, setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { AsyncEmitter, DebounceEmitter, DynamicListEventMultiplexer, Emitter, Event, EventBufferer, EventMultiplexer, IWaitUntil, MicrotaskEmitter, PauseableEmitter, Relay, createEventDeliveryQueue } from 'vs/base/common/event'; @@ -1158,6 +1158,48 @@ suite('Event utils', () => { listener.dispose(); // should not crash }); + suite('fromPromise', () => { + + test('not yet resolved', async function () { + return new Promise(resolve => { + let promise = new DeferredPromise(); + + Event.fromPromise(promise.p)(e => { + assert.strictEqual(e, 1); + + promise = new DeferredPromise(); + + Event.fromPromise(promise.p)(() => { + resolve(); + }); + + promise.error(undefined); + }); + + promise.complete(1); + }); + }); + + test('already resolved', async function () { + return new Promise(resolve => { + let promise = new DeferredPromise(); + promise.complete(1); + + Event.fromPromise(promise.p)(e => { + assert.strictEqual(e, 1); + + promise = new DeferredPromise(); + promise.error(undefined); + + Event.fromPromise(promise.p)(() => { + resolve(); + }); + }); + + }); + }); + }); + suite('Relay', () => { test('should input work', () => { const e1 = new Emitter(); diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts index 8773eff46d5..467a7c20d8a 100644 --- a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts @@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/event'; import { firstOrDefault } from 'vs/base/common/arrays'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Codicon } from 'vs/base/common/codicons'; -import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; @@ -24,11 +24,14 @@ import { CONTEXT_PROVIDER_EXISTS } from 'vs/workbench/contrib/chat/common/chatCo import { InlineChatController } from 'vs/workbench/contrib/inlineChat/browser/inlineChatController'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { getCodeEditor } from 'vs/editor/browser/editorBrowser'; -import { isExecuteActionContext } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; import product from 'vs/platform/product/common/product'; import { ActiveEditorContext } from 'vs/workbench/common/contextkeys'; +import { IViewsService } from 'vs/workbench/common/views'; +import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService'; +import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; +import { KeyCode } from 'vs/base/common/keyCodes'; const CONTEXT_VOICE_CHAT_GETTING_READY = new RawContextKey('voiceChatGettingReady', false, { type: 'boolean', description: localize('voiceChatGettingReady', "True when getting ready for receiving voice input from the microphone.") }); const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey('voiceChatInProgress', false, { type: 'boolean', description: localize('voiceChatInProgress', "True when voice recording from microphone is in progress.") }); @@ -36,29 +39,123 @@ const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey('voiceChatInPr interface IVoiceChatSessionController { readonly onDidAcceptInput: Event; + readonly onDidCancelInput: Event; focusInput(): void; acceptInput(): void; updateInput(text: string): void; } -function getController(controller: InlineChatController): IVoiceChatSessionController; -function getController(context: unknown): IVoiceChatSessionController | undefined; -function getController(context: unknown): IVoiceChatSessionController | undefined { - if (context instanceof InlineChatController) { - return { - onDidAcceptInput: context.onDidAcceptInput, - focusInput: () => context.focus(), - acceptInput: () => context.acceptInput(), - updateInput: text => context.updateInput(text) - }; - } +class VoiceChatSessionControllerFactory { - if (isExecuteActionContext(context)) { - return context.widget; - } + static create(accessor: ServicesAccessor, context: 'inline'): Promise; + static create(accessor: ServicesAccessor, context: 'quick'): Promise; + static create(accessor: ServicesAccessor, context: 'view'): Promise; + static create(accessor: ServicesAccessor, context: 'focussed'): Promise; + static async create(accessor: ServicesAccessor, context: 'inline' | 'quick' | 'view' | 'focussed'): Promise { + const chatWidgetService = accessor.get(IChatWidgetService); + const chatService = accessor.get(IChatService); + const viewsService = accessor.get(IViewsService); + const chatContributionService = accessor.get(IChatContributionService); + const editorService = accessor.get(IEditorService); + const quickChatService = accessor.get(IQuickChatService); - return undefined; + // Currently Focussed Context + if (context === 'focussed') { + + // Try with the chat widget service, which currently + // only supports the chat view and quick chat + // https://github.com/microsoft/vscode/issues/191191 + const chatInput = chatWidgetService.lastFocusedWidget; + if (chatInput?.hasInputFocus()) { + return { + onDidAcceptInput: chatInput.onDidAcceptInput, + onDidCancelInput: Event.any( + // Since we do not know if the view or the quick chat + // is container of the chat input, we need to listen + // to both events here... + Event.filter(viewsService.onDidChangeViewVisibility, e => e.id === chatContributionService.getViewIdForProvider(chatInput.providerId)), + quickChatService.onDidClose + ), + focusInput: () => chatInput.focusInput(), + acceptInput: () => chatInput.acceptInput(), + updateInput: text => chatInput.updateInput(text) + }; + } + + // Try with the inline chat + const activeCodeEditor = getCodeEditor(editorService.activeTextEditorControl); + if (activeCodeEditor) { + const inlineChat = InlineChatController.get(activeCodeEditor); + if (inlineChat?.hasFocus()) { + return { + onDidAcceptInput: inlineChat.onDidAcceptInput, + onDidCancelInput: inlineChat.onDidCancelInput, + focusInput: () => inlineChat.focus(), + acceptInput: () => inlineChat.acceptInput(), + updateInput: text => inlineChat.updateInput(text) + }; + } + } + } + + // View Chat + if (context === 'view') { + const provider = firstOrDefault(chatService.getProviderInfos()); + if (provider) { + const chatView = await chatWidgetService.revealViewForProvider(provider.id); + if (chatView) { + return { + onDidAcceptInput: chatView.onDidAcceptInput, + onDidCancelInput: Event.filter(viewsService.onDidChangeViewVisibility, e => e.id === chatContributionService.getViewIdForProvider(provider.id)), + focusInput: () => chatView.focusInput(), + acceptInput: () => chatView.acceptInput(), + updateInput: text => chatView.updateInput(text) + }; + } + } + } + + // Inline Chat + if (context === 'inline') { + const activeCodeEditor = getCodeEditor(editorService.activeTextEditorControl); + if (activeCodeEditor) { + const inlineChat = InlineChatController.get(activeCodeEditor); + if (inlineChat) { + const inlineChatSession = inlineChat.run(); + + return { + onDidAcceptInput: inlineChat.onDidAcceptInput, + onDidCancelInput: Event.any( + inlineChat.onDidCancelInput, + Event.fromPromise(inlineChatSession) + ), + focusInput: () => inlineChat.focus(), + acceptInput: () => inlineChat.acceptInput(), + updateInput: text => inlineChat.updateInput(text) + }; + } + } + } + + // Quick Chat + if (context === 'quick') { + quickChatService.open(); + + const quickChat = chatWidgetService.lastFocusedWidget; + if (quickChat) { + return { + onDidAcceptInput: quickChat.onDidAcceptInput, + onDidCancelInput: quickChatService.onDidClose, + focusInput: () => quickChat.focusInput(), + acceptInput: () => quickChat.acceptInput(), + updateInput: text => quickChat.updateInput(text) + }; + } + } + + return undefined; + } } class VoiceChatSession { @@ -83,33 +180,41 @@ class VoiceChatSession { @IWorkbenchVoiceRecognitionService private readonly voiceRecognitionService: IWorkbenchVoiceRecognitionService ) { } - async start(context: IVoiceChatSessionController): Promise { + async start(controller: IVoiceChatSessionController): Promise { this.stop(); - this.voiceChatGettingReadyKey.set(true); + const voiceChatSessionId = ++this.voiceChatSessionIds; this.currentVoiceChatSession = new DisposableStore(); const cts = new CancellationTokenSource(); this.currentVoiceChatSession.add(toDisposable(() => cts.dispose(true))); - context.focusInput(); + this.currentVoiceChatSession.add(controller.onDidAcceptInput(() => this.stop(voiceChatSessionId))); + this.currentVoiceChatSession.add(controller.onDidCancelInput(() => this.stop(voiceChatSessionId))); + + controller.focusInput(); + + this.voiceChatGettingReadyKey.set(true); const onDidTranscribe = await this.voiceRecognitionService.transcribe(cts.token, { onDidCancel: () => this.stop(voiceChatSessionId) }); - if (cts.token.isCancellationRequested) { - return Disposable.None; - } - const voiceChatSessionId = ++this.voiceChatSessionIds; + if (cts.token.isCancellationRequested) { + return; + } this.voiceChatGettingReadyKey.set(false); this.voiceChatInProgressKey.set(true); + this.registerTranscriptionListener(controller, onDidTranscribe, this.currentVoiceChatSession); + } + + private registerTranscriptionListener(controller: IVoiceChatSessionController, onDidTranscribe: Event, disposables: DisposableStore) { let lastText: string | undefined = undefined; let lastTextSimilarCount = 0; - this.currentVoiceChatSession.add(onDidTranscribe(text => { + disposables.add(onDidTranscribe(text => { if (!text && lastText) { text = lastText; } @@ -123,17 +228,13 @@ class VoiceChatSession { } if (lastTextSimilarCount >= 2) { - context.acceptInput(); + controller.acceptInput(); } else { - context.updateInput(text); + controller.updateInput(text); } } })); - - this.currentVoiceChatSession.add(context.onDidAcceptInput(() => this.stop(voiceChatSessionId))); - - return toDisposable(() => this.stop(voiceChatSessionId)); } private isSimilarTranscription(textA: string, textB: string): boolean { @@ -151,11 +252,10 @@ class VoiceChatSession { } stop(voiceChatSessionId = this.voiceChatSessionIds): void { - if (!this.currentVoiceChatSession) { - return; - } - - if (this.voiceChatSessionIds !== voiceChatSessionId) { + if ( + !this.currentVoiceChatSession || + this.voiceChatSessionIds !== voiceChatSessionId + ) { return; } @@ -185,16 +285,11 @@ class VoiceChatInChatViewAction extends Action2 { } async run(accessor: ServicesAccessor): Promise { - const chatWidgetService = accessor.get(IChatWidgetService); - const chatService = accessor.get(IChatService); const instantiationService = accessor.get(IInstantiationService); - const provider = firstOrDefault(chatService.getProviderInfos()); - if (provider) { - const controller = await chatWidgetService.revealViewForProvider(provider.id); - if (controller) { - VoiceChatSession.getInstance(instantiationService).start(controller); - } + const controller = await VoiceChatSessionControllerFactory.create(accessor, 'view'); + if (controller) { + VoiceChatSession.getInstance(instantiationService).start(controller); } } } @@ -217,23 +312,12 @@ class InlineVoiceChatAction extends Action2 { } async run(accessor: ServicesAccessor): Promise { - const editorService = accessor.get(IEditorService); const instantiationService = accessor.get(IInstantiationService); - const activeCodeEditor = getCodeEditor(editorService.activeTextEditorControl); - if (!activeCodeEditor) { - return; + const controller = await VoiceChatSessionControllerFactory.create(accessor, 'inline'); + if (controller) { + VoiceChatSession.getInstance(instantiationService).start(controller); } - - const controller = InlineChatController.get(activeCodeEditor); - if (!controller) { - return; - } - - const inlineChatSession = controller.run(); - - const disposable = await VoiceChatSession.getInstance(instantiationService).start(getController(controller)); - inlineChatSession.finally(() => disposable.dispose()); } } @@ -255,16 +339,11 @@ class QuickVoiceChatAction extends Action2 { } async run(accessor: ServicesAccessor): Promise { - const quickChatService = accessor.get(IQuickChatService); - const chatWidgetService = accessor.get(IChatWidgetService); const instantiationService = accessor.get(IInstantiationService); - quickChatService.open(); - - const controller = chatWidgetService.lastFocusedWidget; + const controller = await VoiceChatSessionControllerFactory.create(accessor, 'quick'); if (controller) { - const disposable = await VoiceChatSession.getInstance(instantiationService).start(controller); - Event.once(quickChatService.onDidClose)(() => disposable.dispose()); + VoiceChatSession.getInstance(instantiationService).start(controller); } } } @@ -296,46 +375,17 @@ class StartVoiceChatAction extends Action2 { }); } - async run(accessor: ServicesAccessor, context: unknown): Promise { - const editorService = accessor.get(IEditorService); - const chatWidgetService = accessor.get(IChatWidgetService); + async run(accessor: ServicesAccessor): Promise { const instantiationService = accessor.get(IInstantiationService); const commandService = accessor.get(ICommandService); - let controller = getController(context); - if (!controller) { - - // Without a controller, this action potentially executed from - // a global keybinding, and thus we have to find the chat - // input that is currently focussed, or have a fallback - - // 1.) a chat input widget has focus - if (chatWidgetService.lastFocusedWidget?.hasInputFocus()) { - controller = chatWidgetService.lastFocusedWidget; - } - - // 2.) a inline chat input widget has focus - if (!controller) { - const activeCodeEditor = getCodeEditor(editorService.activeTextEditorControl); - if (activeCodeEditor) { - const chatInput = InlineChatController.get(activeCodeEditor); - if (chatInput?.hasFocus()) { - controller = getController(chatInput); - } - } - } - - // 3.) open a quick chat view - if (!controller) { - return commandService.executeCommand(QuickVoiceChatAction.ID); - } + const controller = await VoiceChatSessionControllerFactory.create(accessor, 'focussed'); + if (controller) { + VoiceChatSession.getInstance(instantiationService).start(controller); + } else { + // fallback to Quick Voice Chat command + commandService.executeCommand(QuickVoiceChatAction.ID); } - - if (!controller) { - return; - } - - VoiceChatSession.getInstance(instantiationService).start(controller); } } @@ -352,6 +402,11 @@ class StopVoiceChatAction extends Action2 { }, category: CHAT_CATEGORY, f1: true, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib + 100, + when: CONTEXT_VOICE_CHAT_IN_PROGRESS, + primary: KeyCode.Escape + }, precondition: CONTEXT_VOICE_CHAT_IN_PROGRESS, icon: spinningLoading, menu: [{ diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts index 023fee9cfd2..1d8cacb2985 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts @@ -101,6 +101,7 @@ export class InlineChatController implements IEditorContribution { private _messages = this._store.add(new Emitter()); readonly onDidAcceptInput = Event.filter(this._messages.event, m => m === Message.ACCEPT_INPUT, this._store); + readonly onDidCancelInput = Event.filter(this._messages.event, m => m === Message.CANCEL_INPUT || m === Message.CANCEL_SESSION, this._store); private readonly _sessionStore: DisposableStore = this._store.add(new DisposableStore()); private readonly _stashedSession: MutableDisposable = this._store.add(new MutableDisposable()); From eef56ce7d3aefa1aadec4ec46f411d9e815abe3f Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 30 Aug 2023 05:44:32 -0700 Subject: [PATCH 096/198] Fix another `var()` fallback case (#191721) One more case of #190968 --- .../workbench/contrib/interactive/browser/interactiveEditor.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.css b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.css index 491aa3e8c17..d43c6a6e98b 100644 --- a/src/vs/workbench/contrib/interactive/browser/interactiveEditor.css +++ b/src/vs/workbench/contrib/interactive/browser/interactiveEditor.css @@ -17,5 +17,5 @@ .interactive-editor .input-cell-container .monaco-editor-background, .interactive-editor .input-cell-container .margin-view-overlays { - background-color: var(--vscode-notebook-cellEditorBackground, --vscode-editor-background); + background-color: var(--vscode-notebook-cellEditorBackground, var(--vscode-editor-background)); } From bee68cee69f701e3fdcea4190ef6d14aab00fa48 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 30 Aug 2023 15:24:37 +0200 Subject: [PATCH 097/198] allow workspace edit to "create" untitled files (#191779) https://github.com/microsoft/vscode-copilot/issues/1261 --- .../src/singlefolder-tests/workspace.test.ts | 16 ++++++++++++++++ .../contrib/bulkEdit/browser/bulkFileEdits.ts | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts index 6e0c8e59404..e69eecff5d1 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/workspace.test.ts @@ -977,6 +977,22 @@ suite('vscode API - workspace', () => { assert.strictEqual(document.getText(), expected); }); + + test('[Bug] Failed to create new test file when in an untitled file #1261', async function () { + const uri = vscode.Uri.parse('untitled:Untitled-5.test'); + const contents = `Hello Test File ${uri.toString()}`; + const we = new vscode.WorkspaceEdit(); + we.createFile(uri, { ignoreIfExists: true }); + we.replace(uri, new vscode.Range(0, 0, 0, 0), contents); + + const success = await vscode.workspace.applyEdit(we); + + assert.ok(success); + + const doc = await vscode.workspace.openTextDocument(uri); + assert.strictEqual(doc.getText(), contents); + }); + test('Should send a single FileWillRenameEvent instead of separate events when moving multiple files at once#111867, 1/3', async function () { const file1 = await createRandomFile(); diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts index c21f9e7f6c6..9f895d8b8a7 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkFileEdits.ts @@ -18,6 +18,7 @@ import { ResourceFileEdit } from 'vs/editor/browser/services/bulkEditService'; import { CancellationToken } from 'vs/base/common/cancellation'; import { tail } from 'vs/base/common/arrays'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; +import { Schemas } from 'vs/base/common/network'; interface IFileOperation { uris: URI[]; @@ -173,6 +174,9 @@ class CreateOperation implements IFileOperation { const undoes: DeleteEdit[] = []; for (const edit of this._edits) { + if (edit.newUri.scheme === Schemas.untitled) { + continue; // ignore, will be handled by a later edit + } if (edit.options.overwrite === undefined && edit.options.ignoreIfExists && await this._fileService.exists(edit.newUri)) { continue; // not overwriting, but ignoring, and the target file exists } From 0e3926c62a5c779c0d1ac8e267dce6bbc82624c4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 30 Aug 2023 15:34:27 +0200 Subject: [PATCH 098/198] voice - fix bad controller when using toolbar actions (#191780) --- .../chat/electron-sandbox/actions/voiceChatActions.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts index 467a7c20d8a..97a1c2efcbd 100644 --- a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts @@ -32,6 +32,7 @@ import { IViewsService } from 'vs/workbench/common/views'; import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode } from 'vs/base/common/keyCodes'; +import { isExecuteActionContext } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions'; const CONTEXT_VOICE_CHAT_GETTING_READY = new RawContextKey('voiceChatGettingReady', false, { type: 'boolean', description: localize('voiceChatGettingReady', "True when getting ready for receiving voice input from the microphone.") }); const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey('voiceChatInProgress', false, { type: 'boolean', description: localize('voiceChatInProgress', "True when voice recording from microphone is in progress.") }); @@ -375,10 +376,18 @@ class StartVoiceChatAction extends Action2 { }); } - async run(accessor: ServicesAccessor): Promise { + async run(accessor: ServicesAccessor, context: unknown): Promise { const instantiationService = accessor.get(IInstantiationService); const commandService = accessor.get(ICommandService); + if (isExecuteActionContext(context)) { + // if we already get a context when the action is executed + // from a toolbar within the chat widget, then make sure + // to move focus into the input field so that the controller + // is properly retrieved + context.widget.focusInput(); + } + const controller = await VoiceChatSessionControllerFactory.create(accessor, 'focussed'); if (controller) { VoiceChatSession.getInstance(instantiationService).start(controller); From fdcc959e0a6dfc365d9a6a8a595ac76457db2f65 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:43:56 +0200 Subject: [PATCH 099/198] Git - update Explorer welcome view context key (#191788) --- extensions/git/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 105491916ca..37212410bfe 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -2950,13 +2950,13 @@ { "view": "scm", "contents": "%view.workbench.scm.folder%", - "when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == folder && scmRepositoryCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'", + "when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == folder && scm.providerCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'", "group": "5_scm@1" }, { "view": "scm", "contents": "%view.workbench.scm.workspace%", - "when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == workspace && workspaceFolderCount != 0 && scmRepositoryCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'", + "when": "config.git.enabled && !git.missing && git.state == initialized && workbenchState == workspace && workspaceFolderCount != 0 && scm.providerCount == 0 && git.parentRepositoryCount == 0 && git.unsafeRepositoryCount == 0 && git.closedRepositoryCount == 0 && remoteName != 'codespaces'", "group": "5_scm@1" }, { @@ -2992,13 +2992,13 @@ { "view": "explorer", "contents": "%view.workbench.cloneRepository%", - "when": "config.git.enabled && git.state == initialized && scmRepositoryCount == 0", + "when": "config.git.enabled && git.state == initialized && scm.providerCount == 0", "group": "5_scm@1" }, { "view": "explorer", "contents": "%view.workbench.learnMore%", - "when": "config.git.enabled && git.state == initialized && scmRepositoryCount == 0", + "when": "config.git.enabled && git.state == initialized && scm.providerCount == 0", "group": "5_scm@10" } ] From 4538c811ebacf7eee5defab22d560dd57fdcd785 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 15:39:01 +0200 Subject: [PATCH 100/198] Fixes #191323 --- src/vs/base/common/arrays.ts | 4 + .../common/diff/advancedLinesDiffComputer.ts | 93 +++++++++++++++++-- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 22c2859f5e9..94966dc1b6f 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -666,6 +666,10 @@ export namespace CompareResult { return result < 0; } + export function isLessThanOrEqual(result: CompareResult): boolean { + return result <= 0; + } + export function isGreaterThan(result: CompareResult): boolean { return result > 0; } diff --git a/src/vs/editor/common/diff/advancedLinesDiffComputer.ts b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts index a7d9605d78c..55166f1ad82 100644 --- a/src/vs/editor/common/diff/advancedLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts @@ -3,10 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { compareBy, equals, findLastIndex, numberComparator, reverseOrder } from 'vs/base/common/arrays'; +import { Comparator, CompareResult, compareBy, equals, findLastIndex, numberComparator, reverseOrder } from 'vs/base/common/arrays'; import { assertFn, checkAdjacentItems } from 'vs/base/common/assert'; import { CharCode } from 'vs/base/common/charCode'; import { SetMap } from 'vs/base/common/collections'; +import { BugIndicatingError } from 'vs/base/common/errors'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Position } from 'vs/editor/common/core/position'; @@ -302,7 +303,7 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { if (moves.length === 0) { return []; } - const joinedMoves = [moves[0]]; + let joinedMoves = [moves[0]]; for (let i = 1; i < moves.length; i++) { const last = joinedMoves[joinedMoves.length - 1]; const current = moves[i]; @@ -324,6 +325,19 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { joinedMoves.push(current); } + // Ignore non moves + const originalChanges = MonotonousFinder.createOfSorted(changes, c => c.originalRange.endLineNumberExclusive, numberComparator); + joinedMoves = joinedMoves.filter(m => { + const diffBeforeOriginalMove = originalChanges.findLastItemBeforeOrEqual(m.original.startLineNumber) + || new LineRangeMapping(new LineRange(1, 1), new LineRange(1, 1), []); + + const modifiedDistToPrevDiff = m.modified.startLineNumber - diffBeforeOriginalMove.modifiedRange.endLineNumberExclusive; + const originalDistToPrevDiff = m.original.startLineNumber - diffBeforeOriginalMove.originalRange.endLineNumberExclusive; + + const differentDistances = modifiedDistToPrevDiff !== originalDistToPrevDiff; + return differentDistances; + }); + const fullMoves = joinedMoves.map(m => { const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( m.original.toOffsetRange(), @@ -366,6 +380,60 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { } } +class MonotonousFinder { + public static create( + items: TItem[], + itemToDomain: (item: TItem) => TDomain, + domainComparator: Comparator, + ): MonotonousFinder { + items.sort((a, b) => domainComparator(itemToDomain(a), itemToDomain(b))); + return new MonotonousFinder(items, itemToDomain, domainComparator); + } + + public static createOfSorted( + items: TItem[], + itemToDomain: (item: TItem) => TDomain, + domainComparator: Comparator, + ): MonotonousFinder { + return new MonotonousFinder(items, itemToDomain, domainComparator); + } + + private _currentIdx = 0; // All values with index lower than this are smaller than or equal to _lastValue and vice versa. + private _lastValue: TDomain | undefined = undefined; // Represents a smallest value. + private _hasLastValue = false; + + private constructor( + private readonly _items: TItem[], + private readonly _itemToDomain: (item: TItem) => TDomain, + private readonly _domainComparator: Comparator, + ) { + } + + /** + * Assumes the values are monotonously increasing. + */ + findLastItemBeforeOrEqual(value: TDomain): TItem | undefined { + if (this._hasLastValue && CompareResult.isLessThan(this._domainComparator(value, this._lastValue!))) { + // Values must be monotonously increasing + throw new BugIndicatingError(); + } + this._lastValue = value; + this._hasLastValue = true; + + while ( + this._currentIdx < this._items.length + && CompareResult.isLessThanOrEqual(this._domainComparator( + this._itemToDomain(this._items[this._currentIdx]), + value + )) + ) { + this._currentIdx++; + } + + return this._currentIdx === 0 ? undefined : this._items[this._currentIdx - 1]; + } +} + function intersectRanges(ranges1: LineRange[], ranges2: LineRange[]): LineRange[] { const result: LineRange[] = []; @@ -839,16 +907,15 @@ export class LinesSliceCharSequence implements ISequence { } public extendToFullLines(range: OffsetRange): OffsetRange { - const firstIdx = findLastIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => x <= range.start); - const lastIdx = findFirstIdxMonotonous(this.firstCharOffsetByLineMinusOne, x => range.endExclusive <= x); - - const start = firstIdx === -1 ? 0 : this.firstCharOffsetByLineMinusOne[firstIdx]; - const end = lastIdx === this.firstCharOffsetByLineMinusOne.length ? this.elements.length : this.firstCharOffsetByLineMinusOne[lastIdx]; + const start = findLastMonotonous(this.firstCharOffsetByLineMinusOne, x => x <= range.start) ?? 0; + const end = findFirstMonotonous(this.firstCharOffsetByLineMinusOne, x => range.endExclusive <= x) ?? this.elements.length; return new OffsetRange(start, end); } } /** + * `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`! + * * @returns -1 if predicate is false for all items */ function findLastIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { @@ -865,7 +932,14 @@ function findLastIdxMonotonous(arr: T[], predicate: (item: T) => boolean): nu return i - 1; } +export function findLastMonotonous(arr: T[], predicate: (item: T) => boolean): T | undefined { + const idx = findLastIdxMonotonous(arr, predicate); + return idx === -1 ? undefined : arr[idx]; +} + /** + * `arr.map(predicate)` must be like `[false, ..., false, true, ..., true]`! + * * @returns arr.length if predicate is false for all items */ function findFirstIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { @@ -882,6 +956,11 @@ function findFirstIdxMonotonous(arr: T[], predicate: (item: T) => boolean): n return i; } +export function findFirstMonotonous(arr: T[], predicate: (item: T) => boolean): T | undefined { + const idx = findFirstIdxMonotonous(arr, predicate); + return idx === arr.length ? undefined : arr[idx]; +} + function isWordChar(charCode: number): boolean { return charCode >= CharCode.a && charCode <= CharCode.z || charCode >= CharCode.A && charCode <= CharCode.Z From ec9aa5cfdf18ac4f5d3fb2b384869dca46f6451f Mon Sep 17 00:00:00 2001 From: Sandeep Somavarapu Date: Wed, 30 Aug 2023 16:50:40 +0200 Subject: [PATCH 101/198] Revert "fix #190228 (#191207)" (#191789) This reverts commit cafcb59c16b5fcb2ae2db76cea0ba2596df8b7db. --- .../workbench/contrib/extensions/browser/extensionEditor.ts | 6 ++++-- .../contrib/extensions/browser/media/extensionEditor.css | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 0cb4cdeab43..16a37dc27c9 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -855,10 +855,12 @@ export class ExtensionEditor extends EditorPane { extensionPackReadme.style.maxWidth = '882px'; const extensionPack = append(extensionPackReadme, $('div', { class: 'extension-pack' })); - if (manifest.extensionPack!.length < 3) { + if (manifest.extensionPack!.length <= 3) { extensionPackReadme.classList.add('one-row'); - } else if (manifest.extensionPack!.length < 5) { + } else if (manifest.extensionPack!.length <= 6) { extensionPackReadme.classList.add('two-rows'); + } else if (manifest.extensionPack!.length <= 9) { + extensionPackReadme.classList.add('three-rows'); } else { extensionPackReadme.classList.add('more-rows'); } diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css index 575e6870b54..174b332538b 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css @@ -517,6 +517,10 @@ height: 224px; } +.extension-editor > .body > .content > .details > .readme-container > .extension-pack-readme.three-rows > .extension-pack { + height: 306px; +} + .extension-editor > .body > .content > .details > .readme-container > .extension-pack-readme.more-rows > .extension-pack { height: 326px; } From 6b9018f059cbe1d8a9ea75c3b026d0a85e27eb5b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 08:06:33 -0700 Subject: [PATCH 102/198] Workaround slow update webgl issue on Windows Fixes #190195 --- .../terminal/browser/xterm/xtermTerminal.ts | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index fcf7a078831..7d968e8818f 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -43,6 +43,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { debounce } from 'vs/base/common/decorators'; import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent'; +import { isWindows } from 'vs/base/common/platform'; const enum RenderConstants { /** @@ -120,6 +121,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, ID readonly raw: RawXtermTerminal; private _core: IXtermCore; private static _suggestedRendererType: 'canvas' | 'dom' | undefined = undefined; + private static _checkedWebglCompatible = false; private _attached?: { container: HTMLElement; options: IXtermAttachToElementOptions }; private _isPhysicalMouseWheel = MouseWheelClassifier.INSTANCE.isPhysicalMouseWheel(); @@ -677,6 +679,25 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, ID if (!this.raw.element || this._webglAddon) { return; } + + // Check if the the WebGL renderer is compatible with xterm.js: + // - https://github.com/microsoft/vscode/issues/190195 + // - https://github.com/xtermjs/xterm.js/issues/4665 + // - https://bugs.chromium.org/p/chromium/issues/detail?id=1476475 + if (!XtermTerminal._checkedWebglCompatible && isWindows) { + XtermTerminal._checkedWebglCompatible = true; + const checkCanvas = document.createElement('canvas'); + const checkGl = checkCanvas.getContext('webgl2'); + const debugInfo = checkGl?.getExtension('WEBGL_debug_renderer_info'); + if (checkGl && debugInfo) { + const renderer = checkGl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); + if (renderer.startsWith('ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero)')) { + this._disableWebglForThisSession(); + return; + } + } + } + const Addon = await this._getWebglAddonConstructor(); this._webglAddon = new Addon(); this._disposeOfCanvasRenderer(); @@ -701,12 +722,16 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, ID if (!neverMeasureRenderTime && this._configHelper.config.gpuAcceleration !== 'off') { this._measureRenderTime(); } - XtermTerminal._suggestedRendererType = 'canvas'; - this._disposeOfWebglRenderer(); - this._enableCanvasRenderer(); + this._disableWebglForThisSession(); } } + private _disableWebglForThisSession() { + XtermTerminal._suggestedRendererType = 'canvas'; + this._disposeOfWebglRenderer(); + this._enableCanvasRenderer(); + } + private async _enableCanvasRenderer(): Promise { if (!this.raw.element || this._canvasAddon) { return; From 5cc83f79943d1de0abefa00d650a2533e30be99a Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 30 Aug 2023 08:20:08 -0700 Subject: [PATCH 103/198] cli: verify vscode server integrity before committing to cache (#191792) Fixes #191469 --- cli/src/tunnels/code_server.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/cli/src/tunnels/code_server.rs b/cli/src/tunnels/code_server.rs index 5bc5e39514a..16655533754 100644 --- a/cli/src/tunnels/code_server.rs +++ b/cli/src/tunnels/code_server.rs @@ -14,7 +14,7 @@ use crate::tunnels::paths::{get_server_folder_name, SERVER_FOLDER_NAME}; use crate::update_service::{ unzip_downloaded_release, Platform, Release, TargetKind, UpdateService, }; -use crate::util::command::{capture_command, kill_tree}; +use crate::util::command::{capture_command, capture_command_and_check_status, kill_tree}; use crate::util::errors::{wrap, AnyError, CodeError, ExtensionInstallFailed, WrappedError}; use crate::util::http::{self, BoxedHttp}; use crate::util::io::SilentCopyProgress; @@ -416,11 +416,23 @@ impl<'a> ServerBuilder<'a> { ) .await?; - unzip_downloaded_release( - &archive_path, - &target_dir.join(SERVER_FOLDER_NAME), - SilentCopyProgress(), - )?; + let server_dir = target_dir.join(SERVER_FOLDER_NAME); + unzip_downloaded_release(&archive_path, &server_dir, SilentCopyProgress())?; + + let output = capture_command_and_check_status( + server_dir + .join("bin") + .join(self.server_params.release.quality.server_entrypoint()), + &["--version"], + ) + .await + .map_err(|e| wrap(e, "error checking server integrity"))?; + + trace!( + self.logger, + "Server integrity verified, version: {}", + String::from_utf8_lossy(&output.stdout).replace('\n', " / ") + ); Ok(()) }) From d46d86dd75cd99f652a183e02a091dbae31d5164 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 30 Aug 2023 17:36:04 +0200 Subject: [PATCH 104/198] voice - replace codicon when hovering over stop button (#191777) --- .../actions/media/voiceChatActions.css | 14 ++++++++++++++ .../electron-sandbox/actions/voiceChatActions.ts | 1 + 2 files changed, 15 insertions(+) create mode 100644 src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css b/src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css new file mode 100644 index 00000000000..53e4022e443 --- /dev/null +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css @@ -0,0 +1,14 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +.monaco-workbench .interactive-input-part .monaco-action-bar .action-label.codicon-loading.codicon-modifier-spin:not(.disabled):hover, +.monaco-workbench .inline-chat .monaco-action-bar .action-label.codicon-loading.codicon-modifier-spin:not(.disabled):hover { + animation: none; /* stop the running voice recording animation for showing another codicon to stop */ +} + +.monaco-workbench .interactive-input-part .monaco-action-bar .action-label.codicon-loading.codicon-modifier-spin:not(.disabled):hover::before, +.monaco-workbench .inline-chat .monaco-action-bar .action-label.codicon-loading.codicon-modifier-spin:not(.disabled):hover::before { + content: "\eba5"; /* use `stop-circle` icon unicode for hovering over running voice recording */ +} diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts index 97a1c2efcbd..792071aab04 100644 --- a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import 'vs/css!./media/voiceChatActions'; import { Event } from 'vs/base/common/event'; import { firstOrDefault } from 'vs/base/common/arrays'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; From 8813aca70522f4e5e4b3996db46dac2cb921564b Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 30 Aug 2023 08:37:00 -0700 Subject: [PATCH 105/198] cli: recycle all tunnels the cli creates for all scenarios (#191800) Fixes #191749 --- cli/src/tunnels/dev_tunnels.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cli/src/tunnels/dev_tunnels.rs b/cli/src/tunnels/dev_tunnels.rs index b77f6da5f2e..e7b84ed4112 100644 --- a/cli/src/tunnels/dev_tunnels.rs +++ b/cli/src/tunnels/dev_tunnels.rs @@ -212,6 +212,7 @@ impl ActiveTunnel { const VSCODE_CLI_TUNNEL_TAG: &str = "vscode-server-launcher"; const VSCODE_CLI_FORWARDING_TAG: &str = "vscode-port-forward"; +const OWNED_TUNNEL_TAGS: &[&str] = &[VSCODE_CLI_TUNNEL_TAG, VSCODE_CLI_FORWARDING_TAG]; const MAX_TUNNEL_NAME_LENGTH: usize = 20; fn get_host_token_from_tunnel(tunnel: &Tunnel) -> String { @@ -635,7 +636,7 @@ impl DevTunnels { "Tunnel limit hit, trying to recycle an old tunnel" ); - let existing_tunnels = self.list_all_server_tunnels().await?; + let existing_tunnels = self.list_tunnels_with_tag(OWNED_TUNNEL_TAGS).await?; let recyclable = existing_tunnels .iter() @@ -667,13 +668,15 @@ impl DevTunnels { } } - async fn list_all_server_tunnels(&mut self) -> Result, AnyError> { + async fn list_tunnels_with_tag( + &mut self, + tags: &[&'static str], + ) -> Result, AnyError> { let tunnels = spanf!( self.log, self.log.span("dev-tunnel.listall"), self.client.list_all_tunnels(&TunnelRequestOptions { - tags: vec![self.tag.to_string()], - require_all_tags: true, + tags: tags.iter().map(|t| t.to_string()).collect(), ..Default::default() }) ) @@ -711,7 +714,7 @@ impl DevTunnels { preferred_name: Option<&str>, mut use_random_name: bool, ) -> Result { - let existing_tunnels = self.list_all_server_tunnels().await?; + let existing_tunnels = self.list_tunnels_with_tag(&[self.tag]).await?; let is_name_free = |n: &str| { !existing_tunnels.iter().any(|v| { v.status From afa0d9fd750cdeaf6c03504fb84e8603eea0cc2e Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 30 Aug 2023 17:47:42 +0200 Subject: [PATCH 106/198] voice - make stop icon more explicit --- .../chat/electron-sandbox/actions/media/voiceChatActions.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css b/src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css index 53e4022e443..b081c2c8d2f 100644 --- a/src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/media/voiceChatActions.css @@ -10,5 +10,5 @@ .monaco-workbench .interactive-input-part .monaco-action-bar .action-label.codicon-loading.codicon-modifier-spin:not(.disabled):hover::before, .monaco-workbench .inline-chat .monaco-action-bar .action-label.codicon-loading.codicon-modifier-spin:not(.disabled):hover::before { - content: "\eba5"; /* use `stop-circle` icon unicode for hovering over running voice recording */ + content: "\ead7"; /* use `debug-stop` icon unicode for hovering over running voice recording */ } From 1e4020e70c32d3f836f44ce816bbca6f761743be Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 30 Aug 2023 08:50:59 -0700 Subject: [PATCH 107/198] set default focusAfterRun to none --- .../contrib/terminal/common/terminalConfiguration.ts | 5 ++--- .../browser/terminal.accessibility.contribution.ts | 8 +++----- .../accessibility/browser/terminalAccessibilityHelp.ts | 3 ++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts index 1f8820b634f..dde5c45fd5c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts @@ -611,11 +611,10 @@ const terminalConfiguration: IConfigurationNode = { }, [TerminalSettingId.FocusAfterRun]: { markdownDescription: localize('terminal.integrated.focusAfterRun', "Controls whether the terminal, accessible buffer, or neither will be focused after `Terminal: Run Selected Text In Active Terminal` has been run."), - enum: ['auto', 'terminal', 'accessible-buffer', 'none'], - default: 'auto', + enum: ['terminal', 'accessible-buffer', 'none'], + default: 'none', tags: ['accessibility'], markdownEnumDescriptions: [ - localize('terminal.integrated.focusAfterRun.auto', "Set to `terminal` when in screen reader optimized mode and `none` otherwise."), localize('terminal.integrated.focusAfterRun.terminal', "Always focus the terminal."), localize('terminal.integrated.focusAfterRun.accessible-buffer', "Always focus the accessible buffer."), localize('terminal.integrated.focusAfterRun.none', "Do nothing."), diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts index 8c3ef5b48eb..682d14ccde1 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminal.accessibility.contribution.ts @@ -6,7 +6,7 @@ import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { localize } from 'vs/nls'; -import { CONTEXT_ACCESSIBILITY_MODE_ENABLED, IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -61,14 +61,12 @@ class AccessibleBufferContribution extends DisposableStore implements ITerminalC processManager: ITerminalProcessManager, widgetManager: TerminalWidgetManager, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IConfigurationService configurationService: IConfigurationService, - @IAccessibilityService accessibilityService: IAccessibilityService + @IConfigurationService configurationService: IConfigurationService ) { super(); this.add(_instance.onDidRunText(() => { const focusAfterRun = configurationService.getValue(TerminalSettingId.FocusAfterRun); - const focusTerminal = focusAfterRun === 'terminal' || (focusAfterRun === 'auto' && accessibilityService.isScreenReaderOptimized()); - if (focusTerminal) { + if (focusAfterRun === 'terminal') { _instance.focus(true); } else if (focusAfterRun === 'accessible-buffer') { this.show(); diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts index 9205be2e624..340427fd528 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibilityHelp.ts @@ -11,7 +11,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { ShellIntegrationStatus, WindowsShellType } from 'vs/platform/terminal/common/terminal'; +import { ShellIntegrationStatus, TerminalSettingId, WindowsShellType } from 'vs/platform/terminal/common/terminal'; import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; import { AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions } from 'vs/workbench/contrib/accessibility/browser/accessibleView'; import { ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; @@ -93,6 +93,7 @@ export class TerminalAccessibleContentProvider extends Disposable implements IAc } content.push(this._descriptionForCommand(TerminalCommandId.OpenDetectedLink, localize('openDetectedLink', 'The Open Detected Link ({0}) command enables screen readers to easily open links found in the terminal.'), localize('openDetectedLinkNoKb', 'The Open Detected Link command enables screen readers to easily open links found in the terminal and is currently not triggerable by a keybinding.'))); content.push(this._descriptionForCommand(TerminalCommandId.NewWithProfile, localize('newWithProfile', 'The Create New Terminal (With Profile) ({0}) command allows for easy terminal creation using a specific profile.'), localize('newWithProfileNoKb', 'The Create New Terminal (With Profile) command allows for easy terminal creation using a specific profile and is currently not triggerable by a keybinding.'))); + content.push(localize('focusAfterRun', 'Configure what gets focused after running selected text in the terminal with `{0}`.', TerminalSettingId.FocusAfterRun)); content.push(localize('accessibilitySettings', 'Access accessibility settings such as `terminal.integrated.tabFocusMode` via the Preferences: Open Accessibility Settings command.')); return content.join('\n\n'); } From 65dd28d745a5369653196d67b83b0390cd2a82bf Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Wed, 30 Aug 2023 17:53:35 +0200 Subject: [PATCH 108/198] voice - add a new action to stop and accept voice input (#191802) --- .../actions/voiceChatActions.ts | 87 ++++++++++++++----- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts index 792071aab04..05e454d36a2 100644 --- a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts @@ -160,21 +160,26 @@ class VoiceChatSessionControllerFactory { } } -class VoiceChatSession { +interface ActiveVoiceChatSession { + readonly controller: IVoiceChatSessionController; + readonly disposables: DisposableStore; +} - private static instance: VoiceChatSession | undefined = undefined; - static getInstance(instantiationService: IInstantiationService): VoiceChatSession { - if (!VoiceChatSession.instance) { - VoiceChatSession.instance = instantiationService.createInstance(VoiceChatSession); +class VoiceChatSessions { + + private static instance: VoiceChatSessions | undefined = undefined; + static getInstance(instantiationService: IInstantiationService): VoiceChatSessions { + if (!VoiceChatSessions.instance) { + VoiceChatSessions.instance = instantiationService.createInstance(VoiceChatSessions); } - return VoiceChatSession.instance; + return VoiceChatSessions.instance; } private voiceChatInProgressKey = CONTEXT_VOICE_CHAT_IN_PROGRESS.bindTo(this.contextKeyService); private voiceChatGettingReadyKey = CONTEXT_VOICE_CHAT_GETTING_READY.bindTo(this.contextKeyService); - private currentVoiceChatSession: DisposableStore | undefined = undefined; + private currentVoiceChatSession: ActiveVoiceChatSession | undefined = undefined; private voiceChatSessionIds = 0; constructor( @@ -186,14 +191,18 @@ class VoiceChatSession { this.stop(); const voiceChatSessionId = ++this.voiceChatSessionIds; - this.currentVoiceChatSession = new DisposableStore(); + this.currentVoiceChatSession = { + controller, + disposables: new DisposableStore() + }; const cts = new CancellationTokenSource(); - this.currentVoiceChatSession.add(toDisposable(() => cts.dispose(true))); + this.currentVoiceChatSession.disposables.add(toDisposable(() => cts.dispose(true))); - this.currentVoiceChatSession.add(controller.onDidAcceptInput(() => this.stop(voiceChatSessionId))); - this.currentVoiceChatSession.add(controller.onDidCancelInput(() => this.stop(voiceChatSessionId))); + this.currentVoiceChatSession.disposables.add(controller.onDidAcceptInput(() => this.stop(voiceChatSessionId))); + this.currentVoiceChatSession.disposables.add(controller.onDidCancelInput(() => this.stop(voiceChatSessionId))); + controller.updateInput(''); controller.focusInput(); this.voiceChatGettingReadyKey.set(true); @@ -209,14 +218,14 @@ class VoiceChatSession { this.voiceChatGettingReadyKey.set(false); this.voiceChatInProgressKey.set(true); - this.registerTranscriptionListener(controller, onDidTranscribe, this.currentVoiceChatSession); + this.registerTranscriptionListener(this.currentVoiceChatSession, onDidTranscribe); } - private registerTranscriptionListener(controller: IVoiceChatSessionController, onDidTranscribe: Event, disposables: DisposableStore) { + private registerTranscriptionListener(session: ActiveVoiceChatSession, onDidTranscribe: Event) { let lastText: string | undefined = undefined; let lastTextSimilarCount = 0; - disposables.add(onDidTranscribe(text => { + session.disposables.add(onDidTranscribe(text => { if (!text && lastText) { text = lastText; } @@ -230,9 +239,9 @@ class VoiceChatSession { } if (lastTextSimilarCount >= 2) { - controller.acceptInput(); + session.controller.acceptInput(); } else { - controller.updateInput(text); + session.controller.updateInput(text); } } @@ -261,12 +270,23 @@ class VoiceChatSession { return; } - this.currentVoiceChatSession.dispose(); + this.currentVoiceChatSession.disposables.dispose(); this.currentVoiceChatSession = undefined; this.voiceChatGettingReadyKey.set(false); this.voiceChatInProgressKey.set(false); } + + accept(voiceChatSessionId = this.voiceChatSessionIds): void { + if ( + !this.currentVoiceChatSession || + this.voiceChatSessionIds !== voiceChatSessionId + ) { + return; + } + + this.currentVoiceChatSession.controller.acceptInput(); + } } class VoiceChatInChatViewAction extends Action2 { @@ -291,7 +311,7 @@ class VoiceChatInChatViewAction extends Action2 { const controller = await VoiceChatSessionControllerFactory.create(accessor, 'view'); if (controller) { - VoiceChatSession.getInstance(instantiationService).start(controller); + VoiceChatSessions.getInstance(instantiationService).start(controller); } } } @@ -318,7 +338,7 @@ class InlineVoiceChatAction extends Action2 { const controller = await VoiceChatSessionControllerFactory.create(accessor, 'inline'); if (controller) { - VoiceChatSession.getInstance(instantiationService).start(controller); + VoiceChatSessions.getInstance(instantiationService).start(controller); } } } @@ -345,7 +365,7 @@ class QuickVoiceChatAction extends Action2 { const controller = await VoiceChatSessionControllerFactory.create(accessor, 'quick'); if (controller) { - VoiceChatSession.getInstance(instantiationService).start(controller); + VoiceChatSessions.getInstance(instantiationService).start(controller); } } } @@ -391,7 +411,7 @@ class StartVoiceChatAction extends Action2 { const controller = await VoiceChatSessionControllerFactory.create(accessor, 'focussed'); if (controller) { - VoiceChatSession.getInstance(instantiationService).start(controller); + VoiceChatSessions.getInstance(instantiationService).start(controller); } else { // fallback to Quick Voice Chat command commandService.executeCommand(QuickVoiceChatAction.ID); @@ -434,7 +454,29 @@ class StopVoiceChatAction extends Action2 { } run(accessor: ServicesAccessor): void { - VoiceChatSession.getInstance(accessor.get(IInstantiationService)).stop(); + VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).stop(); + } +} + +class StopVoiceChatAndSubmitAction extends Action2 { + + static readonly ID = 'workbench.action.chat.stopVoiceChatAndSubmit'; + + constructor() { + super({ + id: StopVoiceChatAndSubmitAction.ID, + title: { + value: localize('workbench.action.chat.stopAndAcceptVoiceChat.label', "Stop Voice Chat and Submit"), + original: 'Stop Voice Chat and Submit' + }, + category: CHAT_CATEGORY, + f1: true, + precondition: CONTEXT_VOICE_CHAT_IN_PROGRESS + }); + } + + run(accessor: ServicesAccessor): void { + VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).accept(); } } @@ -446,5 +488,6 @@ export function registerVoiceChatActions() { registerAction2(StartVoiceChatAction); registerAction2(StopVoiceChatAction); + registerAction2(StopVoiceChatAndSubmitAction); } } From 3ea4d66a5b943aafd6585fc546c2899958093f29 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 30 Aug 2023 18:04:52 +0200 Subject: [PATCH 109/198] changing to use code action instead of setting --- .../client/src/jsonClient.ts | 32 +++++++------------ .../json-language-features/package.json | 6 ---- .../json-language-features/package.nls.json | 1 - 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonClient.ts b/extensions/json-language-features/client/src/jsonClient.ts index 23410ebb814..a801245a46d 100644 --- a/extensions/json-language-features/client/src/jsonClient.ts +++ b/extensions/json-language-features/client/src/jsonClient.ts @@ -8,7 +8,7 @@ export type JSONLanguageStatus = { schemas: string[] }; import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange, - ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, TextEditorOptions + ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, CodeActionKind, CodeAction } from 'vscode'; import { LanguageClientOptions, RequestType, NotificationType, FormattingOptions as LSPFormattingOptions, @@ -102,7 +102,6 @@ export type JSONSchemaSettings = { export namespace SettingIds { export const enableFormatter = 'json.format.enable'; export const enableKeepLines = 'json.format.keepLines'; - export const enableSortOnSave = 'json.sortOnSave.enable'; export const enableValidation = 'json.validate.enable'; export const enableSchemaDownload = 'json.schemaDownload.enable'; export const maxItemsComputed = 'json.maxItemsComputed'; @@ -171,15 +170,6 @@ export async function startClient(context: ExtensionContext, newLanguageClient: window.showInformationMessage(l10n.t('JSON schema cache cleared.')); })); - toDispose.push(workspace.onWillSaveTextDocument(event => { - const sortOnSave = workspace.getConfiguration().get(SettingIds.enableSortOnSave); - const document = event.document; - if (sortOnSave && (document.languageId === 'json' || document.languageId === 'jsonc')) { - const documentOptions = getOptionsForDocument(document); - const textEditsPromise = getSortTextEdits(document, documentOptions?.tabSize, documentOptions?.insertSpaces); - event.waitUntil(textEditsPromise); - } - })); toDispose.push(commands.registerCommand('json.sort', async () => { @@ -312,6 +302,17 @@ export async function startClient(context: ExtensionContext, newLanguageClient: return r.then(checkLimit); } return checkLimit(r); + }, + provideCodeActions(doc) { + console.log('doc : ', doc); + console.log('inside of provideCodeActions'); + const codeActions: CodeAction[] = []; + const sortCodeAction = new CodeAction('Sort JSON', CodeActionKind.Source); + sortCodeAction.command = { + command: 'json.sort', + title: 'Sort JSON' + }; + return codeActions; } } }; @@ -643,12 +644,3 @@ function updateMarkdownString(h: MarkdownString): MarkdownString { function isSchemaResolveError(d: Diagnostic) { return d.code === /* SchemaResolveError */ 0x300; } - -function getOptionsForDocument(document: TextDocument): TextEditorOptions | undefined { - for (const editor of window.visibleTextEditors) { - if (editor.document.uri.toString() === document.uri.toString()) { - return editor.options; - } - } - return; -} diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index cd9e69d69b4..f804c30da79 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -91,12 +91,6 @@ "default": false, "description": "%json.format.keepLines.desc%" }, - "json.sortOnSave.enable": { - "type": "boolean", - "scope": "window", - "default": false, - "description": "%json.sortOnSave.enable.desc%" - }, "json.trace.server": { "type": "string", "scope": "window", diff --git a/extensions/json-language-features/package.nls.json b/extensions/json-language-features/package.nls.json index df68b3f8eac..2586bc6ab0a 100644 --- a/extensions/json-language-features/package.nls.json +++ b/extensions/json-language-features/package.nls.json @@ -8,7 +8,6 @@ "json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.", "json.format.enable.desc": "Enable/disable default JSON formatter", "json.format.keepLines.desc" : "Keep all existing new lines when formatting.", - "json.sortOnSave.enable.desc": "Enable/disable default sorting on save", "json.validate.enable.desc": "Enable/disable JSON validation.", "json.tracing.desc": "Traces the communication between VS Code and the JSON language server.", "json.colorDecorators.enable.desc": "Enables or disables color decorators", From 49581af0aa7abbad69699899dadb972488998c32 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:17:45 -0700 Subject: [PATCH 110/198] Disable renderer unit test on Windows --- .../terminal/test/browser/xterm/xtermTerminal.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index ab689e76e87..578d5b7fbf5 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -33,6 +33,7 @@ import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKe import { Color, RGBA } from 'vs/base/common/color'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; +import { isWindows } from 'vs/base/common/platform'; class TestWebglAddon implements WebglAddon { static shouldThrow = false; @@ -256,7 +257,9 @@ suite('XtermTerminal', () => { }); suite('renderers', () => { - test('should re-evaluate gpu acceleration auto when the setting is changed', async () => { + // This is skipped on Windows because the result depends on the webgl + // renderer in the browsing context + (isWindows ? test.skip : test)('should re-evaluate gpu acceleration auto when the setting is changed', async () => { // Check initial state strictEqual(TestWebglAddon.isEnabled, false); From e2d858ecb03625377d4ddfaf9b7d65061745a0c9 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 30 Aug 2023 09:32:45 -0700 Subject: [PATCH 111/198] changed command title and name --- extensions/ipynb/package.json | 6 +++--- extensions/ipynb/package.nls.json | 2 +- .../notebook/browser/controller/cellOutputActions.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/ipynb/package.json b/extensions/ipynb/package.json index f5e25ac3695..25d08040183 100644 --- a/extensions/ipynb/package.json +++ b/extensions/ipynb/package.json @@ -58,8 +58,8 @@ "title": "%cleanInvalidImageAttachment.title%" }, { - "command": "notebook.cellOutput.copyToClipboard", - "title": "%copyOutputToClipboard.title%" + "command": "notebook.cellOutput.copy", + "title": "%copyCellOutput.title%" } ], "notebooks": [ @@ -106,7 +106,7 @@ ], "webview/context": [ { - "command": "notebook.cellOutput.copyToClipboard", + "command": "notebook.cellOutput.copy", "when": "webviewId == 'notebook.output' && webviewSection == 'image'" } ] diff --git a/extensions/ipynb/package.nls.json b/extensions/ipynb/package.nls.json index 45aa2aa03e8..1f281c32dd3 100644 --- a/extensions/ipynb/package.nls.json +++ b/extensions/ipynb/package.nls.json @@ -6,7 +6,7 @@ "newUntitledIpynb.shortTitle": "Jupyter Notebook", "openIpynbInNotebookEditor.title": "Open IPYNB File In Notebook Editor", "cleanInvalidImageAttachment.title": "Clean Invalid Image Attachment Reference", - "copyOutputToClipboard.title": "Copy Output to Clipboard", + "copyCellOutput.title": "Copy Output", "markdownAttachmentRenderer.displayName": { "message": "Markdown-It ipynb Cell Attachment renderer", "comment": [ diff --git a/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts index 956222d7a36..529fb143978 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts @@ -17,13 +17,13 @@ import { ICellOutputViewModel, ICellViewModel, INotebookEditor, getNotebookEdito import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon'; import { CodeCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/codeCellViewModel'; -export const COPY_OUTPUT_COMMAND_ID = 'notebook.cellOutput.copyToClipboard'; +export const COPY_OUTPUT_COMMAND_ID = 'notebook.cellOutput.copy'; registerAction2(class CopyCellOutputAction extends Action2 { constructor() { super({ id: COPY_OUTPUT_COMMAND_ID, - title: localize('notebookActions.copyOutput', "Copy Output to Clipboard"), + title: localize('notebookActions.copyOutput', "Copy Output"), menu: { id: MenuId.NotebookOutputToolbar, when: NOTEBOOK_CELL_HAS_OUTPUTS From de94adc47511b51dd239381e4c34e16dfa870d9e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:33:14 -0700 Subject: [PATCH 112/198] Update distro Fixes #191605 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0af191524ed..1a58592be0a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.82.0", - "distro": "c7d53f94cfb25168c3c3ae9a6f4902d32643a0ee", + "distro": "021e674d5265eb9125cfc0282c3a9a6091f4982d", "author": { "name": "Microsoft Corporation" }, From 29137c69f1243d31302e57e26c2ea169b1c6254e Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 30 Aug 2023 18:46:39 +0200 Subject: [PATCH 113/198] make sure codeEditor is set when bulk editing via diff editor (#191810) re https://github.com/microsoft/vscode/issues/188385 --- src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts b/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts index 1258f618970..888c67f46a9 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/bulkEditService.ts @@ -8,7 +8,7 @@ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; import { ResourceMap, ResourceSet } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; -import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IBulkEditOptions, IBulkEditPreviewHandler, IBulkEditResult, IBulkEditService, ResourceEdit, ResourceFileEdit, ResourceTextEdit } from 'vs/editor/browser/services/bulkEditService'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { WorkspaceEdit } from 'vs/editor/common/languages'; @@ -197,6 +197,8 @@ export class BulkEditService implements IBulkEditService { const candidate = this._editorService.activeTextEditorControl; if (isCodeEditor(candidate)) { codeEditor = candidate; + } else if (isDiffEditor(candidate)) { + codeEditor = candidate.getModifiedEditor(); } } From cc5e466c96635ef3e0d18896b6054eb51fe5969a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:47:27 -0700 Subject: [PATCH 114/198] Remove windows check --- .../workbench/contrib/terminal/browser/xterm/xtermTerminal.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index 7d968e8818f..12aaa0b0bb6 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -43,7 +43,6 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService import { debounce } from 'vs/base/common/decorators'; import { MouseWheelClassifier } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent'; -import { isWindows } from 'vs/base/common/platform'; const enum RenderConstants { /** @@ -684,7 +683,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, ID // - https://github.com/microsoft/vscode/issues/190195 // - https://github.com/xtermjs/xterm.js/issues/4665 // - https://bugs.chromium.org/p/chromium/issues/detail?id=1476475 - if (!XtermTerminal._checkedWebglCompatible && isWindows) { + if (!XtermTerminal._checkedWebglCompatible) { XtermTerminal._checkedWebglCompatible = true; const checkCanvas = document.createElement('canvas'); const checkGl = checkCanvas.getContext('webgl2'); From ed06154e36dba10a6625f33c4c2c6626df54d57a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:49:19 -0700 Subject: [PATCH 115/198] Disable test --- .../terminal/test/browser/xterm/xtermTerminal.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index 578d5b7fbf5..f4c0afd0259 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -257,9 +257,9 @@ suite('XtermTerminal', () => { }); suite('renderers', () => { - // This is skipped on Windows because the result depends on the webgl - // renderer in the browsing context - (isWindows ? test.skip : test)('should re-evaluate gpu acceleration auto when the setting is changed', async () => { + // This is skipped until the webgl renderer bug is fixed in Chromium + // https://bugs.chromium.org/p/chromium/issues/detail?id=1476475 + test.skip('should re-evaluate gpu acceleration auto when the setting is changed', async () => { // Check initial state strictEqual(TestWebglAddon.isEnabled, false); From cd7388f4dad4c7102713db8ebb16488f070433ea Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 30 Aug 2023 09:50:50 -0700 Subject: [PATCH 116/198] forwarding: fix formatting issues in the log (#191814) Fixes #191759 --- extensions/tunnel-forwarding/src/split.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/tunnel-forwarding/src/split.ts b/extensions/tunnel-forwarding/src/split.ts index 6e9d7474604..33ad055ac67 100644 --- a/extensions/tunnel-forwarding/src/split.ts +++ b/extensions/tunnel-forwarding/src/split.ts @@ -9,6 +9,8 @@ export const splitNewLines = () => new StreamSplitter('\n'.charCodeAt(0)); /** * Copied and simplified from src\vs\base\node\nodeStreams.ts + * + * Exception: does not include the split character in the output. */ export class StreamSplitter extends Transform { private buffer: Buffer | undefined; @@ -31,7 +33,7 @@ export class StreamSplitter extends Transform { break; } - this.push(this.buffer.subarray(offset, index + 1)); + this.push(this.buffer.subarray(offset, index)); offset = index + 1; } From d3c20779626942e64713fefeb1f84b363946dd94 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 09:51:35 -0700 Subject: [PATCH 117/198] Fix import --- .../contrib/terminal/test/browser/xterm/xtermTerminal.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index f4c0afd0259..204505dd1e6 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -33,7 +33,6 @@ import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKe import { Color, RGBA } from 'vs/base/common/color'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; -import { isWindows } from 'vs/base/common/platform'; class TestWebglAddon implements WebglAddon { static shouldThrow = false; From 4dc543d246c6cb2987904444863ea0a51102a95a Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 30 Aug 2023 09:55:19 -0700 Subject: [PATCH 118/198] fix #188329 --- .../workbench/contrib/terminal/browser/terminalInstance.ts | 5 +++++ .../accessibility/browser/terminalAccessibleWidget.ts | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 449e9fce543..64bd477b0e8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -976,6 +976,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return false; } + if (event.key === 'Tab' && event.shiftKey) { + event.preventDefault(); + return true; + } + // Always have alt+F4 skip the terminal on Windows and allow it to be handled by the // system if (isWindows && event.altKey && event.key === 'F4' && !event.ctrlKey) { diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index 6b43d58d553..5190803c2d0 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -118,11 +118,6 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { // On escape, hide the accessible buffer and force focus onto the terminal this.hide(true); break; - case KeyCode.Tab: - // On tab or shift+tab, hide the accessible buffer and perform the default tab - // behavior - this.hide(); - break; } })); this.add(this._editorWidget.onDidFocusEditorText(async () => { From c394fb8959fcaf1f6e9831a0b2b19da7cd4e1286 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 30 Aug 2023 10:02:48 -0700 Subject: [PATCH 119/198] cli: polish serve-web help (#191817) Fixes #191601 --- cli/src/commands/args.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index bfa1c6f2da4..cbc33fcb071 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -52,6 +52,7 @@ const VERSION: &str = concatcp!(NUMBER_IN_VERSION, " (commit ", COMMIT_IN_VERSIO #[clap( help_template = INTEGRATED_TEMPLATE, long_about = None, + name = constants::APPLICATION_NAME, version = VERSION, )] pub struct IntegratedCli { @@ -84,6 +85,7 @@ pub struct CliCore { help_template = STANDALONE_TEMPLATE, long_about = None, version = VERSION, + name = constants::APPLICATION_NAME, )] pub struct StandaloneCli { #[clap(flatten)] @@ -173,6 +175,7 @@ pub enum Commands { Version(VersionArgs), /// Runs a local web version of VS Code. + #[clap(about = concatcp!("Runs a local web version of ", constants::PRODUCT_NAME_LONG))] ServeWeb(ServeWebArgs), /// Runs the control server on process stdin/stdout From c69c9082378f6b18bb237f8cc04da64f62e5370f Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 10:04:34 -0700 Subject: [PATCH 120/198] Fix error in zsh si script Fixes #188875 --- .../contrib/terminal/browser/media/shellIntegration-rc.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh index 09718cfbab2..cc2cb83e0d2 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration-rc.zsh @@ -51,7 +51,7 @@ if [ -n "${VSCODE_ENV_PREPEND:-}" ]; then IFS=':' read -rA ADDR <<< "$VSCODE_ENV_PREPEND" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo ${ITEM%%=*})" - export $VARNAME="$(echo -e {ITEM#*=})${(P)VARNAME}" + export $VARNAME="$(echo -e ${ITEM#*=})${(P)VARNAME}" done unset VSCODE_ENV_PREPEND fi @@ -59,7 +59,7 @@ if [ -n "${VSCODE_ENV_APPEND:-}" ]; then IFS=':' read -rA ADDR <<< "$VSCODE_ENV_APPEND" for ITEM in "${ADDR[@]}"; do VARNAME="$(echo ${ITEM%%=*})" - export $VARNAME="${(P)VARNAME}$(echo -e {ITEM#*=})" + export $VARNAME="${(P)VARNAME}$(echo -e ${ITEM#*=})" done unset VSCODE_ENV_APPEND fi From 146a7d807040153ed6ecdc937185db651393b229 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 30 Aug 2023 10:14:14 -0700 Subject: [PATCH 121/198] Update src/vs/workbench/contrib/terminal/browser/terminalInstance.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 64bd477b0e8..645bcb88540 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -976,6 +976,8 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { return false; } + // Prevent default when shift+tab is being sent to the terminal to avoid it bubbling up + // and changing focus https://github.com/microsoft/vscode/issues/188329 if (event.key === 'Tab' && event.shiftKey) { event.preventDefault(); return true; From 3ff7e76b48dcc4a2ec5421239175432d1d47f2d3 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 30 Aug 2023 10:19:08 -0700 Subject: [PATCH 122/198] on blur, hide --- .../accessibility/browser/terminalAccessibleWidget.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts index 5190803c2d0..448cd3da0e4 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/terminalAccessibleWidget.ts @@ -124,6 +124,7 @@ export abstract class TerminalAccessibleWidget extends DisposableStore { this._terminalService.setActiveInstance(this._instance as ITerminalInstance); this._xtermElement.classList.add(ClassName.Hide); })); + this.add(this._editorWidget.onDidBlurEditorText(async () => this.hide())); } registerListeners(): void { From 8a69a8f266d812d093be0e9c2fd8d41c397e6f75 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 30 Aug 2023 10:41:17 -0700 Subject: [PATCH 123/198] debug: bump js-debug to 1.82 (#191827) --- product.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/product.json b/product.json index 2ae3ee8f0f8..acb24971c39 100644 --- a/product.json +++ b/product.json @@ -52,8 +52,8 @@ }, { "name": "ms-vscode.js-debug", - "version": "1.81.0", - "sha256": "6d1c7ee89881afd65e8fee47445b6a1c5fb345bf30e2bdf70cd2fdd8d1ff6dec", + "version": "1.82.0", + "sha256": "4fba41b4b764c3f5a6591d6d9a5bdc59b417f2d799071c889c2b54163f256282", "repo": "https://github.com/microsoft/vscode-js-debug", "metadata": { "id": "25629058-ddac-4e17-abba-74678e126c5d", From 6e058e590332c2f85a2097a642a1efc10d2a2fec Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 30 Aug 2023 10:46:39 -0700 Subject: [PATCH 124/198] allow more output mime types to be copied --- .../notebook/browser/contrib/clipboard/cellOutputClipboard.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/cellOutputClipboard.ts b/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/cellOutputClipboard.ts index 576ded3d1f6..a544461cc28 100644 --- a/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/cellOutputClipboard.ts +++ b/src/vs/workbench/contrib/notebook/browser/contrib/clipboard/cellOutputClipboard.ts @@ -61,5 +61,7 @@ export const TEXT_BASED_MIMETYPES = [ 'application/x.notebook.stream', 'application/vnd.code.notebook.stderr', 'application/x.notebook.stderr', - 'text/plain' + 'text/plain', + 'text/markdown', + 'application/json' ]; From faa42cbdd2276d3815ae3485e64067ba28b791da Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 30 Aug 2023 10:52:35 -0700 Subject: [PATCH 125/198] Fix file tree not being transferred to panel chat (#191826) --- src/vs/workbench/contrib/chat/common/chatModel.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/workbench/contrib/chat/common/chatModel.ts b/src/vs/workbench/contrib/chat/common/chatModel.ts index 23fec163a79..5f51abedb9a 100644 --- a/src/vs/workbench/contrib/chat/common/chatModel.ts +++ b/src/vs/workbench/contrib/chat/common/chatModel.ts @@ -160,6 +160,7 @@ export class Response implements IResponse { }); } else if (isCompleteInteractiveProgressTreeData(responsePart)) { this._responseParts.push(responsePart); + this._updateRepr(quiet); } } From da5492061c96005ca7592623f523c3323983fb09 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 30 Aug 2023 11:13:13 -0700 Subject: [PATCH 126/198] Fix rendering when chat is hidden (#191830) Fixes https://github.com/microsoft/vscode/issues/191704 --- .../contrib/chat/browser/chatQuick.ts | 11 +++++++++++ .../contrib/chat/browser/chatWidget.ts | 19 +++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index 5545e1a5d03..cc32d7adbd3 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -92,10 +92,13 @@ export class QuickChatService extends Disposable implements IQuickChatService { // show needs to come after the quickpick is shown this._currentChat.render(this._container); + } else { + this._currentChat.show(); } disposableStore.add(this._input.onDidHide(() => { disposableStore.dispose(); + this._currentChat!.hide(); this._input = undefined; this._onDidClose.fire(); })); @@ -163,6 +166,14 @@ class QuickChat extends Disposable { } } + hide(): void { + this.widget.setVisible(false); + } + + show(): void { + this.widget.setVisible(true); + } + render(parent: HTMLElement): void { if (this.widget) { throw new Error('Cannot render quick chat twice'); diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 7e65ed72d20..b37163a9990 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -213,7 +213,7 @@ export class ChatWidget extends Disposable implements IChatWidget { this._onDidClear.fire(); } - private onDidChangeItems() { + private onDidChangeItems(skipDynamicLayout?: boolean) { if (this.tree && this.visible) { const treeItems = (this.viewModel?.getItems() ?? []) .map(item => { @@ -239,7 +239,7 @@ export class ChatWidget extends Disposable implements IChatWidget { } }); - if (this._dynamicMessageLayoutData) { + if (!skipDynamicLayout && this._dynamicMessageLayoutData) { this.layoutDynamicChatTreeItemMode(); } @@ -270,7 +270,7 @@ export class ChatWidget extends Disposable implements IChatWidget { // Progressive rendering paused while hidden, so start it up again. // Do it after a timeout because the container is not visible yet (it should be but offsetHeight returns 0 here) if (this.visible) { - this.onDidChangeItems(); + this.onDidChangeItems(true); } }, 0)); } @@ -540,6 +540,11 @@ export class ChatWidget extends Disposable implements IChatWidget { const mutableDisposable = this._register(new MutableDisposable()); this._register(this.tree.onDidScroll((e) => { + // TODO@TylerLeonhardt this should probably just be disposed when this is disabled + // and then set up again when it is enabled again + if (!this._dynamicMessageLayoutData?.enabled) { + return; + } mutableDisposable.value = dom.scheduleAtNextAnimationFrame(() => { if (!e.scrollTopChanged || e.heightChanged || e.scrollHeightChanged) { return; @@ -593,7 +598,9 @@ export class ChatWidget extends Disposable implements IChatWidget { if (!this.viewModel || !this._dynamicMessageLayoutData?.enabled) { return; } - const inputHeight = this.inputPart.layout(this._dynamicMessageLayoutData!.maxHeight, this.container.offsetWidth); + + const width = this.bodyDimension?.width ?? this.container.offsetWidth; + const inputHeight = this.inputPart.layout(this._dynamicMessageLayoutData!.maxHeight, width); const totalMessages = this.viewModel.getItems(); // grab the last N messages @@ -610,10 +617,10 @@ export class ChatWidget extends Disposable implements IChatWidget { inputHeight + listHeight + (totalMessages.length > 2 ? 18 : 0), this._dynamicMessageLayoutData!.maxHeight ), - this.container.offsetWidth + width ); - if (needsRerender) { + if (needsRerender || !listHeight) { // TODO: figure out a better place to reveal the last element revealLastElement(this.tree); } From 8470c9b0e32bc4da53d74c89ad3909da18ff1991 Mon Sep 17 00:00:00 2001 From: Andrea Mah <31675041+andreamah@users.noreply.github.com> Date: Wed, 30 Aug 2023 11:17:10 -0700 Subject: [PATCH 127/198] adjust endgame query (#191806) --- .vscode/notebooks/my-endgame.github-issues | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index 96c780e5a6f..6978af0b6f0 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -177,7 +177,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE -$MINE is:issue label:bug label:verification-steps-needed" + "value": "$REPOS $MILESTONE -$MINE is:issue label:bug label:verification-steps-needed -label:verified" }, { "kind": 1, From 272fdf6abf6d3ddedc4197b21585fa615ef313c0 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 16:19:30 +0200 Subject: [PATCH 128/198] Diff Editor: Disables optimistic diff updates. Fixes #190748, Fixes #190232 --- .../diffEditorWidget2/diffEditorViewModel.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index aff79983e40..91839a8d461 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -4,22 +4,21 @@ *--------------------------------------------------------------------------------------------*/ import { RunOnceScheduler } from 'vs/base/common/async'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IObservable, IReader, ISettableObservable, ITransaction, autorunWithStore, derived, observableSignal, observableSignalFromEvent, observableValue, transaction, waitForState } from 'vs/base/common/observable'; -import { isDefined } from 'vs/base/common/types'; +import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { ISerializedLineRange, LineRange } from 'vs/editor/common/core/lineRange'; import { Range } from 'vs/editor/common/core/range'; -import { IDocumentDiff, IDocumentDiffProvider } from 'vs/editor/common/diff/documentDiffProvider'; -import { LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { AdvancedLinesDiffComputer, lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/advancedLinesDiffComputer'; +import { IDocumentDiff, IDocumentDiffProvider } from 'vs/editor/common/diff/documentDiffProvider'; +import { LineRangeMapping, MovedText, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; import { IDiffEditorModel, IDiffEditorViewModel } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { TextEditInfo } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper'; import { combineTextEditInfos } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos'; import { lengthAdd, lengthDiffNonNegative, lengthGetLineCount, lengthOfRange, lengthToPosition, lengthZero, positionToLength } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length'; import { DiffEditorOptions } from './diffEditorOptions'; -import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; -import { CancellationTokenSource } from 'vs/base/common/cancellation'; export class DiffEditorViewModel extends Disposable implements IDiffEditorViewModel { private readonly _isDiffUpToDate = observableValue('isDiffUpToDate', false); @@ -469,6 +468,9 @@ export class UnchangedRegion { } function applyOriginalEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], originalTextModel: ITextModel, modifiedTextModel: ITextModel): IDocumentDiff | undefined { + return undefined; + /* + TODO@hediet if (textEdits.length === 0) { return diff; } @@ -478,7 +480,7 @@ function applyOriginalEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], orig if (!diff3) { return undefined; } - return flip(diff3); + return flip(diff3);*/ } function flip(diff: IDocumentDiff): IDocumentDiff { @@ -491,6 +493,9 @@ function flip(diff: IDocumentDiff): IDocumentDiff { } function applyModifiedEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], originalTextModel: ITextModel, modifiedTextModel: ITextModel): IDocumentDiff | undefined { + return undefined; + /* + TODO@hediet if (textEdits.length === 0) { return diff; } @@ -514,7 +519,7 @@ function applyModifiedEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], orig quitEarly: false, changes, moves, - }; + };*/ } function applyEditToLineRange(range: LineRange, textEdits: TextEditInfo[]): LineRange | undefined { From 425413a5092365a790cdd0c7006a687513e4572f Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 16:45:22 +0200 Subject: [PATCH 129/198] Uncomment unused symbols. --- .../widget/diffEditorWidget2/diffEditorViewModel.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 91839a8d461..729b3d61260 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -482,7 +482,7 @@ function applyOriginalEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], orig } return flip(diff3);*/ } - +/* function flip(diff: IDocumentDiff): IDocumentDiff { return { changes: diff.changes.map(c => c.flip()), @@ -491,7 +491,7 @@ function flip(diff: IDocumentDiff): IDocumentDiff { quitEarly: diff.quitEarly, }; } - +*/ function applyModifiedEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], originalTextModel: ITextModel, modifiedTextModel: ITextModel): IDocumentDiff | undefined { return undefined; /* @@ -521,7 +521,7 @@ function applyModifiedEdits(diff: IDocumentDiff, textEdits: TextEditInfo[], orig moves, };*/ } - +/* function applyEditToLineRange(range: LineRange, textEdits: TextEditInfo[]): LineRange | undefined { let rangeStartLineNumber = range.startLineNumber; let rangeEndLineNumberEx = range.endLineNumberExclusive; @@ -588,3 +588,4 @@ function applyModifiedEditsToLineRangeMappings(changes: readonly LineRangeMappin ); return newChanges; } +*/ From 8e242d5bd40435dee74cfb003af4e931767f55bd Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Wed, 30 Aug 2023 20:03:24 +0200 Subject: [PATCH 130/198] Fixes CI --- .../browser/widget/diffEditorWidget2/diffEditorViewModel.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 729b3d61260..860afa96659 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -9,15 +9,13 @@ import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IObservable, IReader, ISettableObservable, ITransaction, autorunWithStore, derived, observableSignal, observableSignalFromEvent, observableValue, transaction, waitForState } from 'vs/base/common/observable'; import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidget2/utils'; import { ISerializedLineRange, LineRange } from 'vs/editor/common/core/lineRange'; -import { Range } from 'vs/editor/common/core/range'; -import { AdvancedLinesDiffComputer, lineRangeMappingFromRangeMappings } from 'vs/editor/common/diff/advancedLinesDiffComputer'; +import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; import { IDocumentDiff, IDocumentDiffProvider } from 'vs/editor/common/diff/documentDiffProvider'; -import { LineRangeMapping, MovedText, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { LineRangeMapping, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; import { IDiffEditorModel, IDiffEditorViewModel } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { TextEditInfo } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper'; import { combineTextEditInfos } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/combineTextEditInfos'; -import { lengthAdd, lengthDiffNonNegative, lengthGetLineCount, lengthOfRange, lengthToPosition, lengthZero, positionToLength } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/length'; import { DiffEditorOptions } from './diffEditorOptions'; export class DiffEditorViewModel extends Disposable implements IDiffEditorViewModel { From 078a686c8254dd37ff652ea87df7e0ed53e95615 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 30 Aug 2023 20:47:31 +0200 Subject: [PATCH 131/198] Fix screen reader for comment editor (#191828) * Try forwarding the accessibility support setting to the comment editor * Add isAccessible to comment view Fixes #146994 --- .../contrib/comments/browser/commentThreadZoneWidget.ts | 2 +- .../workbench/contrib/comments/browser/simpleCommentEditor.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadZoneWidget.ts b/src/vs/workbench/contrib/comments/browser/commentThreadZoneWidget.ts index 1f00b285fa2..74590df5c4c 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadZoneWidget.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadZoneWidget.ts @@ -129,7 +129,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget @IContextKeyService contextKeyService: IContextKeyService, @IConfigurationService private readonly configurationService: IConfigurationService ) { - super(editor, { keepEditorSelection: true }); + super(editor, { keepEditorSelection: true, isAccessible: true }); this._contextKeyService = contextKeyService.createScoped(this.domNode); this._scopedInstantiationService = instantiationService.createChild(new ServiceCollection( diff --git a/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts b/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts index c8ec74a476f..f087642f26b 100644 --- a/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts +++ b/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts @@ -104,7 +104,8 @@ export class SimpleCommentEditor extends CodeEditorWidget { enabled: false }, autoClosingBrackets: configurationService.getValue('editor.autoClosingBrackets'), - quickSuggestions: false + quickSuggestions: false, + accessibilitySupport: configurationService.getValue<'auto' | 'off' | 'on'>('editor.accessibilitySupport'), }; } } From 0d71f3559452de1026dc6475b5a94ceb0f42d300 Mon Sep 17 00:00:00 2001 From: David Dossett Date: Wed, 30 Aug 2023 11:59:17 -0700 Subject: [PATCH 132/198] Update codicons (#191835) --- .../browser/ui/codicons/codicon/codicon.ttf | Bin 73436 -> 73624 bytes src/vs/base/common/codicons.ts | 1 + 2 files changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf index b5623b0a55c7200b6be0079458f48accd5e9eb17..91105610d11595b1232b6618c80bedaf568e09f5 100644 GIT binary patch delta 3559 zcmXBW2~bt%6$kM1hbN2d`z8p2sKjX9h{~pbfGkf`1O#Lec&ra`i)aWB1#yj0u6vXi zqnK#YF_MmrC2CS@G-Df^rm5r5)=sU>@TkqSX{yF*&&e76-T(dW`|f?`<9^?Lcj#l& z;VY)S(Y9nF>?WehYHL+%Oi7Iok;`GC;E}rKjTU#0Z99o#hKT-BUte2QQ+(*eQto?? z#mfPQQird3e~`u0Ti3PyJMsAse7zAOr}vsyRado4I=zx8s+-8M*jm-r>TnC2`SW1z zAK6l6tu?+6{V1E@l+FhqwXRyb&bc)17{MixD5!MbV6?|M0{3Nye|_`RzL9A-XGGuw z_zv8Lr<2iV@;COdXXrKdyZFtz^J8yv{E{4h+?&ifn#gpAOpg709dG{UNHn~Cc=zyU z!#C}&cJqj@G2}9*dIo+%XAy-B@WvAQ0Y#LJ6Ue|Km}v*iL@0I8ReDG%SWjyy5Pf7& zCtidr2*7r_M1AyAY{5$E!djG~5%nlT6V|{A3!O(5Rt>bdy218@p3?v589j$1OmKz^ z+~5vh1R@B*2tgReARG}Gi%5(|EGA$gCLso!Eul zcn$ktU_TDvFpl6Tj^Q}o!b!Z1Q#g%xahC4W-{|l34V6$SHPUQqqH?UJ2C`BeEu&bP zK>ww!w39BPm+wOmRnVU?8i`nk3V(VZ3y}p+lpp}nRDd@ql^#(KU7&x$2{AMYe(<1K z6i*p=83(Z!d+<8-BLPVmMHckq9h^ZsUPT9N=)`8cLOx`M7ahQx#yz+2ImvX4Dk*>l z=tKC>Sc;^7kRJ}gf&N5a&~5rX{f@q(KhPbzOGETW`jUQ&HoAgwM!frYuXM^nCYI7C z^q6O!ld;gCQ8i2VI!%g4_dn>?bcX7FUHRy=`dxJJ=g&RT^iPK&|@&N>Be z&U(dDj)of)@d6rdR46i@c?69=!7Zyo24{=HBFohk`4oP06Yn?o{B$@MeYWhOgIDk1gElQCMl1y@G6Oxy6qHfl|(03Q{RQJ_KYm zuPc;s?p0{w+^4XHvsXdJWGG%FG`wHYdCmh0Rh$R;aUvUDL&IK~PP~T59;J9Sk$s%v zbw&1Q#Vd^LF^ZmZj#uF2Z;w?laZXTh=A5YD!Z}I7jWbSxXMp_$BAaaB%Zt@ z76{^;qU1SepQ;eT$x}oijB}d87|!Vm;ha3B1R^+RDvafvr4UIrvd43SK}PkGf{bdm zf{bd8f{bdef{ZFbK}N;TSpgo9JxM_Z#XkxHGLRGn8OS`rQwUQ1d@J z!7d;LFHn$zGZduYOa&=8OF;@=s2~MoD@Xyh9NsWU0l5lNK%RmWU{;VX%~z0%ELM!<=mjM>u6f3`aR-L=49`Ur{*D*{<*w=c@`QIXe{I=9Gal zoZ{?MI8792-^>k$cR9BxoHZ_oc44)V8rH>cBiF+cY@_*;J_TN6_BRz|Y$p`_Ii&1O{0XQUZe~Czl{l!r8A7zvk!WO&2q9g{iDiCgCt z|JsuM14WZKFDUqN4k&mSqr<1l-`xIlg@c?QDeUFEq_Btc7m9ze$v&t^iu_n1f%CFL z66Y1gzwBhcs>s6miGrN_DUn4s-~rixsUV}hrXV--R|;}7uPeyS{7gY^<_(2T&YMc! zN9~_0ykbN|M2C2B>oOjYEd5f*Q9i!5x#?hvN-vh1Ts0j6~B1Uh>zk|5E}7S^mt%h)PG=mkl>w=o6wzb zE#XmOTw-xzZ{qpH?~=wOolF`^E=)d=(w#Dx@^D_kytaAQ=TDs9IsbZUXlifjgS6Rc z=CqEqYiUo@{nHcE%hCtazg@6t!JUk`8O<4k8Q)}@GdnU*Wj@Uc&Wg>tw=iR2g`Y=27jK+N|2j+6xww<)mfEGGcjJ=Uz9auDx!s?rD8S{qFjw z4Y3XD8lE&BY`oqS+?3ta(=^l^(cIX)v-!T&WKFfUSZ`P#w47ZPx@xd>W@}sPhXc1_ z;?~>fJAUnVrx1R@CBJb_;qVWf9-oAnu|b{~7t1@z2n!2cti{7jB6p*|j-zMdXFp)QUlKexcJh_FC}L~}_i Zql3eH7oUtqn!Cx-+E9HlDG0}%{}0c4tqK4D delta 3355 zcmXZe3s4p36$kM12SijrPy|I03}}#;2tJ4k0)hhamY2K*fySR)<)5)aHG;N)GsqHweV=&d8ljAVI{qNpgzWvVb_w8=? zHHYti_Qr@D2de8zODZocV_D~~t~4JW3&Ef< z7Z>0@au=?S#z6-+=3zWTm(lGsefhm#jwbuNWdFMYrD0> z`jz#TZIUfz%-y)}w6b&w7Ska7ume-EfyR+d2{?syNI^2~qh**yyXZPSq)0T7g;6%?s*h`;LFAZTgN~i@5$io&?ARm?3ifWY8Fp5z-vUAcDSbn0X^fUdBp1}_G zaKuDR#uT_?20Y<~nefJJ%z+Q)!WRLUj|F%cfmnzjyn9AQM^Gh#VB45JlL8%_z-78B8#v3N@%h6W+ugw4fF5q7CiX zhy6H!4s@am29Dr3y74|fzzOu>L!8DL^kV=Y(U0^u`UgFrJj$m^T0vD*gnFZR$_&e4 zzV2SMiT;8~2*Wl^r;ibjIJh7e9(ai|(L>SngxcsL{R(&a|9DDHhvt6o>F0 z4$?WSLO2}AgtIu0b9fs&@eX#uf@Zu$?vw&oI*MK@qc7+i`aRvDWJ;pM1>`|r(pfrB z8MGOz=>!$i3>u+N;YPmXNB^YhI0hKr&a)@HLDw+PSmiw5C5GY=i*))ek2J?KTb(hD z$BHu}4<}jj&x1y@i@(bf9y_H9i;ZCyFN+^B#7$a+y zq6E%rg;Sh03hOv)6;e3s6pu=>))N`Au0EJ$l(~kX(dcva$4O(<)jwnr@7<+%gp$>w z=s9Pzl4)h#t+3aaId!o`w%QbrW3uj5)WX@W(7?H0A&>Kbg4D;8SU|49A%%R-P6es^ zu)`Nay1fr1R?)q%#Q$(iux4FBqgZNea>#o*M$v8J;r&(t$JuX>fyrG?=a+?PVxP zdzlKUoLLIeMz*p*4&JCB2j?ir!MO^upC^id?B@v~P{8>D3VHnn6!H2C*u?8EU^B1t z91tkwERp-qvlL~#Av+mNoU)U_%qjaAsyNFPYB=RM27a2@DioSH<$oC7k3* zP>}w9sUUTXD#&g6or2t^8wzrpzEY6ebW=fY(=7$LO}7<)E|BeO#UBo2yTjKcbgug> zS6=@{k<|4EgsKGYWjeT#oS`tKx5me&6%6WXS!bNGcmw{5?_T_t&K{ zL}T2#AijfRQx#%4-4uUq&=~hd$alv`>%9NMa&^^{u;8%zu>P=n;SS*u;RWG+;Wt;O ztZt96i%5zLjxyV& z>3Y%wOR{rvaB^C5WAfdU$tejb^(p-+KcohxwxwQ9y_YsEt#^adhCLf@r$?nXrC-c& z&PdPrJhL_PbmsM}p{)B^kF)1wo3h)oFK7R}v18-V#s@ipIY~K9IXyXdb4|HDxi|8h z^G5R?=GW#A7I+kd7wjk)D-0~GE*vVf76ljWEc&jf{K=;1O@A(4vUy4AgEEh@6=nTp zH_QH0?p$6}K5R-cwVS$41E$NSn-zf-=8A!eN9Gmg0rR(8{I;B{jIL~`9Ibp@wWO-O z>UOnfb!c^G^>FpW8t Date: Wed, 30 Aug 2023 20:54:49 +0200 Subject: [PATCH 133/198] Fixes #191617 --- .../diffEditorWidget2/movedBlocksLines.ts | 55 +++++++++++++++---- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts index 8a3ac863ddc..8a618685996 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/movedBlocksLines.ts @@ -9,7 +9,7 @@ import { Action } from 'vs/base/common/actions'; import { booleanComparator, compareBy, findMaxIdxBy, numberComparator, tieBreakComparators } from 'vs/base/common/arrays'; import { Codicon } from 'vs/base/common/codicons'; import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IObservable, autorun, autorunWithStore, constObservable, derived, derivedWithStore, keepAlive, observableFromEvent, observableSignalFromEvent, observableValue } from 'vs/base/common/observable'; +import { IObservable, autorun, autorunHandleChanges, autorunWithStore, constObservable, derived, derivedWithStore, keepAlive, observableFromEvent, observableSignalFromEvent, observableValue } from 'vs/base/common/observable'; import { ThemeIcon } from 'vs/base/common/themables'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { DiffEditorEditors } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorEditors'; @@ -82,19 +82,50 @@ export class MovedBlocksLinesPart extends Disposable { } })); - this._register(this._editors.original.onDidChangeCursorPosition(e => { - const m = this._diffModel.get(); - if (!m) { return; } - const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.original.contains(e.position.lineNumber)); - if (movedText !== m.movedTextToCompare.get()) { - m.movedTextToCompare.set(undefined, undefined); + const originalCursorPosition = observableFromEvent(this._editors.original.onDidChangeCursorPosition, () => this._editors.original.getPosition()); + const modifiedCursorPosition = observableFromEvent(this._editors.modified.onDidChangeCursorPosition, () => this._editors.modified.getPosition()); + const originalHasFocus = observableSignalFromEvent( + 'original.onDidFocusEditorWidget', + e => this._editors.original.onDidFocusEditorWidget(() => setTimeout(() => e(undefined), 0)) + ); + const modifiedHasFocus = observableSignalFromEvent( + 'modified.onDidFocusEditorWidget', + e => this._editors.modified.onDidFocusEditorWidget(() => setTimeout(() => e(undefined), 0)) + ); + + let lastChangedEditor: 'original' | 'modified' = 'modified'; + + this._register(autorunHandleChanges({ + createEmptyChangeSummary: () => undefined, + handleChange: (ctx, summary) => { + if (ctx.didChange(originalHasFocus)) { lastChangedEditor = 'original'; } + if (ctx.didChange(modifiedHasFocus)) { lastChangedEditor = 'modified'; } + return true; } - m.setActiveMovedText(movedText); - })); - this._register(this._editors.modified.onDidChangeCursorPosition(e => { - const m = this._diffModel.get(); + }, reader => { + originalHasFocus.read(reader); + modifiedHasFocus.read(reader); + + const m = this._diffModel.read(reader); if (!m) { return; } - const movedText = m.diff.get()!.movedTexts.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber)); + const diff = m.diff.read(reader); + + let movedText: MovedText | undefined = undefined; + + if (diff && lastChangedEditor === 'original') { + const originalPos = originalCursorPosition.read(reader); + if (originalPos) { + movedText = diff.movedTexts.find(m => m.lineRangeMapping.original.contains(originalPos.lineNumber)); + } + } + + if (diff && lastChangedEditor === 'modified') { + const modifiedPos = modifiedCursorPosition.read(reader); + if (modifiedPos) { + movedText = diff.movedTexts.find(m => m.lineRangeMapping.modified.contains(modifiedPos.lineNumber)); + } + } + if (movedText !== m.movedTextToCompare.get()) { m.movedTextToCompare.set(undefined, undefined); } From 08631fab3a63e8439bec69dce08aa5cf95360d48 Mon Sep 17 00:00:00 2001 From: songlinn <17741492+songlinn@users.noreply.github.com> Date: Thu, 31 Aug 2023 03:57:58 +0800 Subject: [PATCH 134/198] fix: prevent history show prev/next in composing event (#184014) --- src/vs/platform/history/browser/contextScopedHistoryWidget.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vs/platform/history/browser/contextScopedHistoryWidget.ts b/src/vs/platform/history/browser/contextScopedHistoryWidget.ts index 0278e0c0112..53b9397651d 100644 --- a/src/vs/platform/history/browser/contextScopedHistoryWidget.ts +++ b/src/vs/platform/history/browser/contextScopedHistoryWidget.ts @@ -113,6 +113,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ when: ContextKeyExpr.and( ContextKeyExpr.has(HistoryNavigationWidgetFocusContext), ContextKeyExpr.equals(HistoryNavigationBackwardsEnablementContext, true), + ContextKeyExpr.not('isComposing'), historyNavigationVisible.isEqualTo(false), ), primary: KeyCode.UpArrow, @@ -128,6 +129,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({ when: ContextKeyExpr.and( ContextKeyExpr.has(HistoryNavigationWidgetFocusContext), ContextKeyExpr.equals(HistoryNavigationForwardsEnablementContext, true), + ContextKeyExpr.not('isComposing'), historyNavigationVisible.isEqualTo(false), ), primary: KeyCode.DownArrow, From e5851bc5f53b2229d34402fb6c816e82124b00a7 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 30 Aug 2023 14:34:42 -0700 Subject: [PATCH 135/198] look for re-used output id containing the image --- .../browser/controller/cellOutputActions.ts | 2 +- .../contrib/notebook/browser/notebookBrowser.ts | 1 + .../notebook/browser/notebookEditorWidget.ts | 2 +- .../browser/view/renderers/backLayerWebView.ts | 6 ++++-- .../browser/view/renderers/webviewMessages.ts | 2 ++ .../browser/view/renderers/webviewPreloads.ts | 15 ++++++++------- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts b/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts index 956222d7a36..fa43716b286 100644 --- a/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts +++ b/src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts @@ -55,7 +55,7 @@ registerAction2(class CopyCellOutputAction extends Action2 { const mimeType = outputViewModel.pickedMimeType?.mimeType; if (mimeType?.startsWith('image/')) { - const focusOptions = { skipReveal: true, outputId: outputViewModel.model.outputId }; + const focusOptions = { skipReveal: true, outputId: outputViewModel.model.outputId, altOutputId: outputViewModel.model.alternativeOutputId }; await notebookEditor.focusNotebookCell(outputViewModel.cellViewModel as ICellViewModel, 'output', focusOptions); notebookEditor.copyOutputImage(outputViewModel); } else { diff --git a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts index 4f1d98b86bb..158b98692fe 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts @@ -152,6 +152,7 @@ export interface IFocusNotebookCellOptions { readonly focusEditorLine?: number; readonly minimalScrolling?: boolean; readonly outputId?: string; + readonly altOutputId?: string; } //#endregion diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index ba8ae7da1db..3830664287b 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -2350,7 +2350,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } const focusElementId = options?.outputId ?? cell.id; - this._webview.focusOutput(focusElementId, this._webviewFocused); + this._webview.focusOutput(focusElementId, options?.altOutputId, this._webviewFocused); cell.updateEditState(CellEditState.Preview, 'focusNotebookCell'); cell.focusMode = CellFocusMode.Output; diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index b2359655e6d..aaed4af8425 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1548,7 +1548,8 @@ export class BackLayerWebView extends Themable { async copyImage(output: ICellOutputViewModel): Promise { this._sendMessageToWebview({ type: 'copyImage', - outputId: output.model.outputId + outputId: output.model.outputId, + altOutputId: output.model.alternativeOutputId }); } @@ -1608,7 +1609,7 @@ export class BackLayerWebView extends Themable { this.webview?.focus(); } - focusOutput(cellOrOutputId: string, viewFocused: boolean) { + focusOutput(cellOrOutputId: string, backupId: string | undefined, viewFocused: boolean) { if (this._disposed) { return; } @@ -1620,6 +1621,7 @@ export class BackLayerWebView extends Themable { this._sendMessageToWebview({ type: 'focus-output', cellOrOutputId: cellOrOutputId, + backupId: backupId }); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts index e74e173ae33..f16d781611a 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -269,11 +269,13 @@ export interface IShowOutputMessage { export interface ICopyImageMessage { readonly type: 'copyImage'; readonly outputId: string; + readonly altOutputId: string; } export interface IFocusOutputMessage { readonly type: 'focus-output'; readonly cellOrOutputId: string; + readonly backupId?: string; } export interface IAckOutputHeight { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 4715e64aa08..cadaa48312f 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -474,8 +474,9 @@ async function webviewPreloads(ctx: PreloadContext) { }); }; - function focusFirstFocusableOrContainerInOutput(cellOrOutputId: string) { - const cellOutputContainer = document.getElementById(cellOrOutputId); + function focusFirstFocusableOrContainerInOutput(cellOrOutputId: string, backupId?: string) { + const cellOutputContainer = document.getElementById(cellOrOutputId) ?? + backupId ? document.getElementById(backupId!) : undefined; if (cellOutputContainer) { if (cellOutputContainer.contains(document.activeElement)) { return; @@ -1362,17 +1363,17 @@ async function webviewPreloads(ctx: PreloadContext) { }); }; - const copyOutputImage = async (outputId: string, retries = 5) => { + const copyOutputImage = async (outputId: string, altOutputId: string, retries = 5) => { if (!document.hasFocus() && retries > 0) { // copyImage can be called from outside of the webview, which means this function may be running whilst the webview is gaining focus. // Since navigator.clipboard.write requires the document to be focused, we need to wait for focus. // We cannot use a listener, as there is a high chance the focus is gained during the setup of the listener resulting in us missing it. - setTimeout(() => { copyOutputImage(outputId, retries - 1); }, 20); + setTimeout(() => { copyOutputImage(outputId, altOutputId, retries - 1); }, 20); return; } try { - const image = document.getElementById(outputId)?.querySelector('img'); + const image = document.getElementById(outputId)?.querySelector('img') || document.getElementById(altOutputId)?.querySelector('img'); if (image) { await navigator.clipboard.write([new ClipboardItem({ 'image/png': new Promise((resolve) => { @@ -1501,7 +1502,7 @@ async function webviewPreloads(ctx: PreloadContext) { } case 'copyImage': { - await copyOutputImage(event.data.outputId); + await copyOutputImage(event.data.outputId, event.data.altOutputId); break; } @@ -1524,7 +1525,7 @@ async function webviewPreloads(ctx: PreloadContext) { break; } case 'focus-output': - focusFirstFocusableOrContainerInOutput(event.data.cellOrOutputId); + focusFirstFocusableOrContainerInOutput(event.data.cellOrOutputId, event.data.backupId); break; case 'decorations': { let outputContainer = document.getElementById(event.data.cellId); From 2e4187c15f7fe9b32445f64ccdb800af3bb8f531 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 30 Aug 2023 14:39:22 -0700 Subject: [PATCH 136/198] normalize option name --- .../notebook/browser/view/renderers/backLayerWebView.ts | 4 ++-- .../notebook/browser/view/renderers/webviewMessages.ts | 2 +- .../notebook/browser/view/renderers/webviewPreloads.ts | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts index aaed4af8425..b89185074f7 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/backLayerWebView.ts @@ -1609,7 +1609,7 @@ export class BackLayerWebView extends Themable { this.webview?.focus(); } - focusOutput(cellOrOutputId: string, backupId: string | undefined, viewFocused: boolean) { + focusOutput(cellOrOutputId: string, alternateId: string | undefined, viewFocused: boolean) { if (this._disposed) { return; } @@ -1621,7 +1621,7 @@ export class BackLayerWebView extends Themable { this._sendMessageToWebview({ type: 'focus-output', cellOrOutputId: cellOrOutputId, - backupId: backupId + alternateId: alternateId }); } diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts index f16d781611a..b46964be307 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages.ts @@ -275,7 +275,7 @@ export interface ICopyImageMessage { export interface IFocusOutputMessage { readonly type: 'focus-output'; readonly cellOrOutputId: string; - readonly backupId?: string; + readonly alternateId?: string; } export interface IAckOutputHeight { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index cadaa48312f..ef41ec0d8b4 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -474,9 +474,9 @@ async function webviewPreloads(ctx: PreloadContext) { }); }; - function focusFirstFocusableOrContainerInOutput(cellOrOutputId: string, backupId?: string) { + function focusFirstFocusableOrContainerInOutput(cellOrOutputId: string, alternateId?: string) { const cellOutputContainer = document.getElementById(cellOrOutputId) ?? - backupId ? document.getElementById(backupId!) : undefined; + alternateId ? document.getElementById(alternateId!) : undefined; if (cellOutputContainer) { if (cellOutputContainer.contains(document.activeElement)) { return; @@ -1525,7 +1525,7 @@ async function webviewPreloads(ctx: PreloadContext) { break; } case 'focus-output': - focusFirstFocusableOrContainerInOutput(event.data.cellOrOutputId, event.data.backupId); + focusFirstFocusableOrContainerInOutput(event.data.cellOrOutputId, event.data.alternateId); break; case 'decorations': { let outputContainer = document.getElementById(event.data.cellId); From 9fbe99c616a42350af45dbb72b6c6bcaadad8a21 Mon Sep 17 00:00:00 2001 From: Aaron Munger Date: Wed, 30 Aug 2023 14:41:03 -0700 Subject: [PATCH 137/198] cleanup --- .../notebook/browser/view/renderers/webviewPreloads.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index ef41ec0d8b4..5197ae5372d 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -1373,7 +1373,8 @@ async function webviewPreloads(ctx: PreloadContext) { } try { - const image = document.getElementById(outputId)?.querySelector('img') || document.getElementById(altOutputId)?.querySelector('img'); + const image = document.getElementById(outputId)?.querySelector('img') + ?? document.getElementById(altOutputId)?.querySelector('img'); if (image) { await navigator.clipboard.write([new ClipboardItem({ 'image/png': new Promise((resolve) => { @@ -1501,9 +1502,7 @@ async function webviewPreloads(ctx: PreloadContext) { break; } case 'copyImage': { - await copyOutputImage(event.data.outputId, event.data.altOutputId); - break; } case 'ack-dimension': { From 3217686db153a4bf9ff11a74beb5288c102c41e4 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 30 Aug 2023 15:12:33 -0700 Subject: [PATCH 138/198] get `x` off the edge (#191849) Fixes https://github.com/microsoft/vscode/issues/191701 --- src/vs/workbench/contrib/chat/browser/media/chat.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/media/chat.css b/src/vs/workbench/contrib/chat/browser/media/chat.css index 5c36c297345..eb1c33b9fa6 100644 --- a/src/vs/workbench/contrib/chat/browser/media/chat.css +++ b/src/vs/workbench/contrib/chat/browser/media/chat.css @@ -238,7 +238,7 @@ .interactive-session .interactive-input-and-side-toolbar { display: flex; - gap: 6px; + gap: 4px; align-items: center; } @@ -427,6 +427,7 @@ .quick-input-widget .interactive-session .interactive-input-and-execute-toolbar { margin: 0; border-radius: 2px; + padding: 0 4px 0 6px; } .quick-input-widget .interactive-list { From d89cac9ac10d1aa4310e827c458f2bea597685ed Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:20:02 -0700 Subject: [PATCH 139/198] Partially revert a change that broke dimming in active group Reopens #191608 --- .../browser/unfocusedViewDimmingContribution.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts index d4c7a06284c..0d9c1bec943 100644 --- a/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution.ts @@ -45,19 +45,19 @@ export class UnfocusedViewDimmingContribution extends Disposable implements IWor // Terminals rules.add(`.monaco-workbench .pane-body.integrated-terminal .terminal-wrapper:not(:focus-within) { ${filterRule} }`); // Text editors - rules.add(`.monaco-workbench .editor-group-container:not(.active) .monaco-editor { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .monaco-editor { ${filterRule} }`); // Breadcrumbs - rules.add(`.monaco-workbench .editor-group-container:not(.active) .tabs-breadcrumbs { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .tabs-breadcrumbs { ${filterRule} }`); // Terminal editors - rules.add(`.monaco-workbench .editor-group-container:not(.active) .terminal-wrapper { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .terminal-wrapper { ${filterRule} }`); // Settings editor - rules.add(`.monaco-workbench .editor-group-container:not(.active) .settings-editor { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .settings-editor { ${filterRule} }`); // Keybindings editor - rules.add(`.monaco-workbench .editor-group-container:not(.active) .keybindings-editor { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .keybindings-editor { ${filterRule} }`); // Editor placeholder (error case) - rules.add(`.monaco-workbench .editor-group-container:not(.active) .monaco-editor-pane-placeholder { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .monaco-editor-pane-placeholder { ${filterRule} }`); // Welcome editor - rules.add(`.monaco-workbench .editor-group-container:not(.active) .gettingStartedContainer { ${filterRule} }`); + rules.add(`.monaco-workbench .editor-instance:not(:focus-within) .gettingStartedContainer { ${filterRule} }`); cssTextContent = [...rules].join('\n'); } From 8f1af4b86865b421a585e398c53a53726cdd41a6 Mon Sep 17 00:00:00 2001 From: David Dossett Date: Wed, 30 Aug 2023 15:24:03 -0700 Subject: [PATCH 140/198] Show focus state on editor tabs in hc themes (#191850) --- src/vs/workbench/browser/parts/editor/tabsTitleControl.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts index 3272b3e4839..5d5d132b05d 100644 --- a/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts +++ b/src/vs/workbench/browser/parts/editor/tabsTitleControl.ts @@ -2077,6 +2077,10 @@ registerThemingParticipant((theme, collector) => { outline-offset: -5px; } + .monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active:focus { + outline-style: dashed; + } + .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active { outline: 1px dotted; outline-offset: -5px; From 700bf1a4db0c2b9b557c4ffe19b8b57c2a485f05 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Wed, 30 Aug 2023 15:29:07 -0700 Subject: [PATCH 141/198] Fix progressive rendering of updated markdown content (#191851) Fix progressive rendering updated markdown content --- src/vs/workbench/contrib/chat/browser/chatListRenderer.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 06f2c24dfb6..8ba6d711809 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -452,9 +452,10 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer Date: Thu, 31 Aug 2023 00:35:53 +0200 Subject: [PATCH 142/198] view descriptor created with containerTitle that is not a string (#191842) --- src/vs/workbench/api/browser/viewsExtensionPoint.ts | 8 ++++---- src/vs/workbench/common/views.ts | 10 ++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index 5fc7d5dc63d..f97885e8e02 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -18,7 +18,7 @@ import { Extensions as ViewletExtensions, PaneCompositeRegistry } from 'vs/workb import { CustomTreeView, RawCustomTreeViewContextKey, TreeViewPane } from 'vs/workbench/browser/parts/views/treeView'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions'; -import { Extensions as ViewContainerExtensions, ICustomTreeViewDescriptor, ICustomViewDescriptor, IViewContainersRegistry, IViewDescriptor, IViewsRegistry, ResolvableTreeItem, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views'; +import { Extensions as ViewContainerExtensions, ICustomViewDescriptor, IViewContainersRegistry, IViewDescriptor, IViewsRegistry, ResolvableTreeItem, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views'; import { VIEWLET_ID as DEBUG } from 'vs/workbench/contrib/debug/common/debug'; import { VIEWLET_ID as EXPLORER } from 'vs/workbench/contrib/files/common/files'; import { VIEWLET_ID as REMOTE } from 'vs/workbench/contrib/remote/browser/remoteExplorer'; @@ -530,14 +530,14 @@ class ViewsExtensionHandler implements IWorkbenchContribution { } } - const viewDescriptor = { + const viewDescriptor: ICustomViewDescriptor = { type: type, ctorDescriptor: type === ViewType.Tree ? new SyncDescriptor(TreeViewPane) : new SyncDescriptor(WebviewViewPane), id: item.id, name: item.name, when: ContextKeyExpr.deserialize(item.when), containerIcon: icon || viewContainer?.icon, - containerTitle: item.contextualTitle || viewContainer?.title, + containerTitle: item.contextualTitle || (viewContainer && (typeof viewContainer.title === 'string' ? viewContainer.title : viewContainer.title.value)), canToggleVisibility: true, canMoveView: viewContainer?.id !== REMOTE, treeView: type === ViewType.Tree ? this.instantiationService.createInstance(CustomTreeView, item.id, item.name, extension.description.identifier.value) : undefined, @@ -587,7 +587,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution { if (removedViews.length) { this.viewsRegistry.deregisterViews(removedViews, viewContainer); for (const view of removedViews) { - const anyView = view as ICustomTreeViewDescriptor; + const anyView = view as ICustomViewDescriptor; if (anyView.treeView) { anyView.treeView.dispose(); } diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 95f89542805..07578cb75b6 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -300,18 +300,12 @@ export interface IViewDescriptor { readonly openCommandActionDescriptor?: OpenCommandActionDescriptor; } -export interface ICustomTreeViewDescriptor extends ITreeViewDescriptor { +export interface ICustomViewDescriptor extends IViewDescriptor { readonly extensionId: ExtensionIdentifier; readonly originalContainerId: string; + readonly treeView?: ITreeView; } -export interface ICustomWebviewViewDescriptor extends IViewDescriptor { - readonly extensionId: ExtensionIdentifier; - readonly originalContainerId: string; -} - -export type ICustomViewDescriptor = ICustomTreeViewDescriptor | ICustomWebviewViewDescriptor; - export interface IViewDescriptorRef { viewDescriptor: IViewDescriptor; index: number; From e7756c8870ee1df7360e6624e220534174039b02 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 30 Aug 2023 17:19:18 -0700 Subject: [PATCH 143/198] reinstate `github-auth` parameter that was accidentally removed (#191862) Fixes https://github.com/microsoft/vscode/issues/191861 --- src/vs/code/browser/workbench/workbench.ts | 42 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 029cf8b10e7..962e2f4c314 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -17,6 +17,7 @@ import product from 'vs/platform/product/common/product'; import { ISecretStorageProvider } from 'vs/platform/secrets/common/secrets'; import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/window/common/window'; import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api'; +import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService'; import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService'; import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService'; import { create } from 'vs/workbench/workbench.web.main'; @@ -176,11 +177,13 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider ) { } private async load(): Promise> { + const record = this.loadAuthSessionFromElement(); // Get the secrets from localStorage const encrypted = window.localStorage.getItem(this._storageKey); if (encrypted) { try { - return JSON.parse(await this.crypto.unseal(encrypted)); + const decrypted = JSON.parse(await this.crypto.unseal(encrypted)); + return { ...record, ...decrypted }; } catch (err) { // TODO: send telemetry console.error('Failed to decrypt secrets from localStorage', err); @@ -188,7 +191,42 @@ export class LocalStorageSecretStorageProvider implements ISecretStorageProvider } } - return {}; + return record; + } + + private loadAuthSessionFromElement(): Record { + let authSessionInfo: (AuthenticationSessionInfo & { scopes: string[][] }) | undefined; + const authSessionElement = document.getElementById('vscode-workbench-auth-session'); + const authSessionElementAttribute = authSessionElement ? authSessionElement.getAttribute('data-settings') : undefined; + if (authSessionElementAttribute) { + try { + authSessionInfo = JSON.parse(authSessionElementAttribute); + } catch (error) { /* Invalid session is passed. Ignore. */ } + } + + if (!authSessionInfo) { + return {}; + } + + const record: Record = {}; + + // Settings Sync Entry + record[`${product.urlProtocol}.loginAccount`] = JSON.stringify(authSessionInfo); + + // Auth extension Entry + if (authSessionInfo.providerId !== 'github') { + console.error(`Unexpected auth provider: ${authSessionInfo.providerId}. Expected 'github'.`); + return record; + } + + const authAccount = JSON.stringify({ extensionId: 'vscode.github-authentication', key: 'github.auth' }); + record[authAccount] = JSON.stringify(authSessionInfo.scopes.map(scopes => ({ + id: authSessionInfo!.id, + scopes, + accessToken: authSessionInfo!.accessToken + }))); + + return record; } async get(key: string): Promise { From 9e927a6111882ef550806e06efb82be9b1b55571 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Wed, 30 Aug 2023 22:24:20 -0700 Subject: [PATCH 144/198] After 30s re-layout the quick chat (#191853) fixes https://github.com/microsoft/vscode/issues/191627 --- .../workbench/contrib/chat/browser/chatQuick.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index cc32d7adbd3..32592d223ab 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -5,9 +5,10 @@ import * as dom from 'vs/base/browser/dom'; import { Orientation, Sash } from 'vs/base/browser/ui/sash/sash'; +import { disposableTimeout } from 'vs/base/common/async'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Emitter } from 'vs/base/common/event'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore, IDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; @@ -132,6 +133,7 @@ class QuickChat extends Disposable { private sash!: Sash; private model: ChatModel | undefined; private _currentQuery: string | undefined; + private maintainScrollTimer: MutableDisposable = this._register(new MutableDisposable()); constructor( private readonly _options: IChatViewOptions, @@ -168,10 +170,22 @@ class QuickChat extends Disposable { hide(): void { this.widget.setVisible(false); + // Maintain scroll position for a short time so that if the user re-shows the chat + // the same scroll position will be used. + this.maintainScrollTimer.value = disposableTimeout(() => { + // At this point, clear this mutable disposable which will be our signal that + // the timer has expired and we should stop maintaining scroll position + this.maintainScrollTimer.clear(); + }, 30 * 1000); // 30 seconds } show(): void { this.widget.setVisible(true); + // If the mutable disposable is set, then we are keeping the existing scroll position + // so we should not update the layout. + if (!this.maintainScrollTimer.value) { + this.widget.layoutDynamicChatTreeItemMode(); + } } render(parent: HTMLElement): void { From 9293e05e89108972c3c70a9326bd454b2a2ea8d3 Mon Sep 17 00:00:00 2001 From: Karel Frederix Date: Thu, 31 Aug 2023 09:38:24 +0200 Subject: [PATCH 145/198] wrap handler for resize observer in requestAnimationFrame() (#183325) * wrap handler for resize observer in requestAnimationFrame() (fixes #183324) * React immediately on first notification during an animation frame and only delay the second notification during the same animation frame --------- Co-authored-by: Karel Frederix Co-authored-by: Alexandru Dima --- .../browser/config/elementSizeObserver.ts | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/browser/config/elementSizeObserver.ts b/src/vs/editor/browser/config/elementSizeObserver.ts index 3529822e209..f6b344f1872 100644 --- a/src/vs/editor/browser/config/elementSizeObserver.ts +++ b/src/vs/editor/browser/config/elementSizeObserver.ts @@ -41,12 +41,42 @@ export class ElementSizeObserver extends Disposable { public startObserving(): void { if (!this._resizeObserver && this._referenceDomElement) { - this._resizeObserver = new ResizeObserver((entries) => { - if (entries && entries[0] && entries[0].contentRect) { - this.observe({ width: entries[0].contentRect.width, height: entries[0].contentRect.height }); + // We want to react to the resize observer only once per animation frame + // The first time the resize observer fires, we will react to it immediately. + // Otherwise we will postpone to the next animation frame. + // We'll use `observeContentRect` to store the content rect we received. + + let observeContentRect: DOMRectReadOnly | null = null; + const observeNow = () => { + if (observeContentRect) { + this.observe({ width: observeContentRect.width, height: observeContentRect.height }); } else { this.observe(); } + }; + + let shouldObserve = false; + let alreadyObservedThisAnimationFrame = false; + + const update = () => { + if (shouldObserve && !alreadyObservedThisAnimationFrame) { + try { + shouldObserve = false; + alreadyObservedThisAnimationFrame = true; + observeNow(); + } finally { + requestAnimationFrame(() => { + alreadyObservedThisAnimationFrame = false; + update(); + }); + } + } + }; + + this._resizeObserver = new ResizeObserver((entries) => { + observeContentRect = (entries && entries[0] && entries[0].contentRect ? entries[0].contentRect : null); + shouldObserve = true; + update(); }); this._resizeObserver.observe(this._referenceDomElement); } From 6d62f83a762fc9b82e663a2adde684977daade97 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 31 Aug 2023 10:01:25 +0200 Subject: [PATCH 146/198] voice - start to better understand different chat input contexts (#191884) * voice - start to have context and actions per chat kind * voice - add context to `stop` * voice - add todo for focus issue when starting --- .../actions/voiceChatActions.ts | 310 ++++++++++++++---- 1 file changed, 247 insertions(+), 63 deletions(-) diff --git a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts index 05e454d36a2..b244992f104 100644 --- a/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts +++ b/src/vs/workbench/contrib/chat/electron-sandbox/actions/voiceChatActions.ts @@ -17,7 +17,7 @@ import { ContextKeyExpr, IContextKeyService, RawContextKey } from 'vs/platform/c import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { spinningLoading } from 'vs/platform/theme/common/iconRegistry'; import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions'; -import { IChatWidgetService, IQuickChatService } from 'vs/workbench/contrib/chat/browser/chat'; +import { IChatWidget, IChatWidgetService, IQuickChatService } from 'vs/workbench/contrib/chat/browser/chat'; import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; import { IWorkbenchVoiceRecognitionService } from 'vs/workbench/services/voiceRecognition/electron-sandbox/workbenchVoiceRecognitionService'; import { MENU_INLINE_CHAT_WIDGET } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; @@ -34,15 +34,25 @@ import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatC import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode } from 'vs/base/common/keyCodes'; import { isExecuteActionContext } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions'; +import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService'; -const CONTEXT_VOICE_CHAT_GETTING_READY = new RawContextKey('voiceChatGettingReady', false, { type: 'boolean', description: localize('voiceChatGettingReady', "True when getting ready for receiving voice input from the microphone.") }); -const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey('voiceChatInProgress', false, { type: 'boolean', description: localize('voiceChatInProgress', "True when voice recording from microphone is in progress.") }); +const CONTEXT_VOICE_CHAT_GETTING_READY = new RawContextKey('voiceChatGettingReady', false, { type: 'boolean', description: localize('voiceChatGettingReady', "True when getting ready for receiving voice input from the microphone for voice chat.") }); +const CONTEXT_VOICE_CHAT_IN_PROGRESS = new RawContextKey('voiceChatInProgress', false, { type: 'boolean', description: localize('voiceChatInProgress', "True when voice recording from microphone is in progress for voice chat.") }); + +const CONTEXT_QUICK_VOICE_CHAT_IN_PROGRESS = new RawContextKey('quickVoiceChatInProgress', false, { type: 'boolean', description: localize('quickVoiceChatInProgress', "True when voice recording from microphone is in progress for quick chat.") }); +const CONTEXT_INLINE_VOICE_CHAT_IN_PROGRESS = new RawContextKey('inlineVoiceChatInProgress', false, { type: 'boolean', description: localize('inlineVoiceChatInProgress', "True when voice recording from microphone is in progress for inline chat.") }); +const CONTEXT_VOICE_CHAT_IN_VIEW_IN_PROGRESS = new RawContextKey('voiceChatInViewInProgress', false, { type: 'boolean', description: localize('voiceChatInViewInProgress', "True when voice recording from microphone is in progress in the chat view.") }); +const CONTEXT_VOICE_CHAT_IN_EDITOR_IN_PROGRESS = new RawContextKey('voiceChatInEditorInProgress', false, { type: 'boolean', description: localize('voiceChatInEditorInProgress', "True when voice recording from microphone is in progress in the chat editor.") }); + +type VoiceChatSessionContext = 'inline' | 'quick' | 'view' | 'editor'; interface IVoiceChatSessionController { readonly onDidAcceptInput: Event; readonly onDidCancelInput: Event; + readonly context: VoiceChatSessionContext; + focusInput(): void; acceptInput(): void; updateInput(text: string): void; @@ -61,6 +71,7 @@ class VoiceChatSessionControllerFactory { const chatContributionService = accessor.get(IChatContributionService); const editorService = accessor.get(IEditorService); const quickChatService = accessor.get(IQuickChatService); + const layoutService = accessor.get(IWorkbenchLayoutService); // Currently Focussed Context if (context === 'focussed') { @@ -70,19 +81,21 @@ class VoiceChatSessionControllerFactory { // https://github.com/microsoft/vscode/issues/191191 const chatInput = chatWidgetService.lastFocusedWidget; if (chatInput?.hasInputFocus()) { - return { - onDidAcceptInput: chatInput.onDidAcceptInput, - onDidCancelInput: Event.any( - // Since we do not know if the view or the quick chat - // is container of the chat input, we need to listen - // to both events here... - Event.filter(viewsService.onDidChangeViewVisibility, e => e.id === chatContributionService.getViewIdForProvider(chatInput.providerId)), - quickChatService.onDidClose - ), - focusInput: () => chatInput.focusInput(), - acceptInput: () => chatInput.acceptInput(), - updateInput: text => chatInput.updateInput(text) - }; + // Unfortunately there does not seem to be a better way + // to figure out if the chat widget is in a part or picker + if ( + layoutService.hasFocus(Parts.SIDEBAR_PART) || + layoutService.hasFocus(Parts.PANEL_PART) || + layoutService.hasFocus(Parts.AUXILIARYBAR_PART) + ) { + return VoiceChatSessionControllerFactory.doCreateForChatView(chatInput, viewsService, chatContributionService); + } + + if (layoutService.hasFocus(Parts.EDITOR_PART)) { + return VoiceChatSessionControllerFactory.doCreateForChatEditor(chatInput, viewsService, chatContributionService); + } + + return VoiceChatSessionControllerFactory.doCreateForQuickChat(chatInput, quickChatService); } // Try with the inline chat @@ -90,13 +103,7 @@ class VoiceChatSessionControllerFactory { if (activeCodeEditor) { const inlineChat = InlineChatController.get(activeCodeEditor); if (inlineChat?.hasFocus()) { - return { - onDidAcceptInput: inlineChat.onDidAcceptInput, - onDidCancelInput: inlineChat.onDidCancelInput, - focusInput: () => inlineChat.focus(), - acceptInput: () => inlineChat.acceptInput(), - updateInput: text => inlineChat.updateInput(text) - }; + return VoiceChatSessionControllerFactory.doCreateForInlineChat(inlineChat); } } } @@ -107,13 +114,7 @@ class VoiceChatSessionControllerFactory { if (provider) { const chatView = await chatWidgetService.revealViewForProvider(provider.id); if (chatView) { - return { - onDidAcceptInput: chatView.onDidAcceptInput, - onDidCancelInput: Event.filter(viewsService.onDidChangeViewVisibility, e => e.id === chatContributionService.getViewIdForProvider(provider.id)), - focusInput: () => chatView.focusInput(), - acceptInput: () => chatView.acceptInput(), - updateInput: text => chatView.updateInput(text) - }; + return VoiceChatSessionControllerFactory.doCreateForChatView(chatView, viewsService, chatContributionService); } } } @@ -124,18 +125,7 @@ class VoiceChatSessionControllerFactory { if (activeCodeEditor) { const inlineChat = InlineChatController.get(activeCodeEditor); if (inlineChat) { - const inlineChatSession = inlineChat.run(); - - return { - onDidAcceptInput: inlineChat.onDidAcceptInput, - onDidCancelInput: Event.any( - inlineChat.onDidCancelInput, - Event.fromPromise(inlineChatSession) - ), - focusInput: () => inlineChat.focus(), - acceptInput: () => inlineChat.acceptInput(), - updateInput: text => inlineChat.updateInput(text) - }; + return VoiceChatSessionControllerFactory.doCreateForInlineChat(inlineChat); } } } @@ -146,18 +136,59 @@ class VoiceChatSessionControllerFactory { const quickChat = chatWidgetService.lastFocusedWidget; if (quickChat) { - return { - onDidAcceptInput: quickChat.onDidAcceptInput, - onDidCancelInput: quickChatService.onDidClose, - focusInput: () => quickChat.focusInput(), - acceptInput: () => quickChat.acceptInput(), - updateInput: text => quickChat.updateInput(text) - }; + return VoiceChatSessionControllerFactory.doCreateForQuickChat(quickChat, quickChatService); } } return undefined; } + + private static doCreateForChatView(chatView: IChatWidget, viewsService: IViewsService, chatContributionService: IChatContributionService): IVoiceChatSessionController { + return VoiceChatSessionControllerFactory.doCreateForChatViewOrEditor('view', chatView, viewsService, chatContributionService); + } + + private static doCreateForChatEditor(chatView: IChatWidget, viewsService: IViewsService, chatContributionService: IChatContributionService): IVoiceChatSessionController { + return VoiceChatSessionControllerFactory.doCreateForChatViewOrEditor('editor', chatView, viewsService, chatContributionService); + } + + private static doCreateForChatViewOrEditor(context: 'view' | 'editor', chatView: IChatWidget, viewsService: IViewsService, chatContributionService: IChatContributionService): IVoiceChatSessionController { + return { + context, + onDidAcceptInput: chatView.onDidAcceptInput, + // TODO@bpasero cancellation needs to work better for chat editors that are not view bound + onDidCancelInput: Event.filter(viewsService.onDidChangeViewVisibility, e => e.id === chatContributionService.getViewIdForProvider(chatView.providerId)), + focusInput: () => chatView.focusInput(), + acceptInput: () => chatView.acceptInput(), + updateInput: text => chatView.updateInput(text) + }; + } + + private static doCreateForQuickChat(quickChat: IChatWidget, quickChatService: IQuickChatService): IVoiceChatSessionController { + return { + context: 'quick', + onDidAcceptInput: quickChat.onDidAcceptInput, + onDidCancelInput: quickChatService.onDidClose, + focusInput: () => quickChat.focusInput(), + acceptInput: () => quickChat.acceptInput(), + updateInput: text => quickChat.updateInput(text) + }; + } + + private static doCreateForInlineChat(inlineChat: InlineChatController,): IVoiceChatSessionController { + const inlineChatSession = inlineChat.run(); + + return { + context: 'inline', + onDidAcceptInput: inlineChat.onDidAcceptInput, + onDidCancelInput: Event.any( + inlineChat.onDidCancelInput, + Event.fromPromise(inlineChatSession) + ), + focusInput: () => inlineChat.focus(), + acceptInput: () => inlineChat.acceptInput(), + updateInput: text => inlineChat.updateInput(text) + }; + } } interface ActiveVoiceChatSession { @@ -179,6 +210,11 @@ class VoiceChatSessions { private voiceChatInProgressKey = CONTEXT_VOICE_CHAT_IN_PROGRESS.bindTo(this.contextKeyService); private voiceChatGettingReadyKey = CONTEXT_VOICE_CHAT_GETTING_READY.bindTo(this.contextKeyService); + private quickVoiceChatInProgressKey = CONTEXT_QUICK_VOICE_CHAT_IN_PROGRESS.bindTo(this.contextKeyService); + private inlineVoiceChatInProgressKey = CONTEXT_INLINE_VOICE_CHAT_IN_PROGRESS.bindTo(this.contextKeyService); + private voiceChatInViewInProgressKey = CONTEXT_VOICE_CHAT_IN_VIEW_IN_PROGRESS.bindTo(this.contextKeyService); + private voiceChatInEditorInProgressKey = CONTEXT_VOICE_CHAT_IN_EDITOR_IN_PROGRESS.bindTo(this.contextKeyService); + private currentVoiceChatSession: ActiveVoiceChatSession | undefined = undefined; private voiceChatSessionIds = 0; @@ -199,8 +235,8 @@ class VoiceChatSessions { const cts = new CancellationTokenSource(); this.currentVoiceChatSession.disposables.add(toDisposable(() => cts.dispose(true))); - this.currentVoiceChatSession.disposables.add(controller.onDidAcceptInput(() => this.stop(voiceChatSessionId))); - this.currentVoiceChatSession.disposables.add(controller.onDidCancelInput(() => this.stop(voiceChatSessionId))); + this.currentVoiceChatSession.disposables.add(controller.onDidAcceptInput(() => this.stop(voiceChatSessionId, controller.context))); + this.currentVoiceChatSession.disposables.add(controller.onDidCancelInput(() => this.stop(voiceChatSessionId, controller.context))); controller.updateInput(''); controller.focusInput(); @@ -208,7 +244,7 @@ class VoiceChatSessions { this.voiceChatGettingReadyKey.set(true); const onDidTranscribe = await this.voiceRecognitionService.transcribe(cts.token, { - onDidCancel: () => this.stop(voiceChatSessionId) + onDidCancel: () => this.stop(voiceChatSessionId, controller.context) }); if (cts.token.isCancellationRequested) { @@ -218,6 +254,21 @@ class VoiceChatSessions { this.voiceChatGettingReadyKey.set(false); this.voiceChatInProgressKey.set(true); + switch (controller.context) { + case 'inline': + this.inlineVoiceChatInProgressKey.set(true); + break; + case 'quick': + this.quickVoiceChatInProgressKey.set(true); + break; + case 'view': + this.voiceChatInViewInProgressKey.set(true); + break; + case 'editor': + this.voiceChatInEditorInProgressKey.set(true); + break; + } + this.registerTranscriptionListener(this.currentVoiceChatSession, onDidTranscribe); } @@ -243,7 +294,6 @@ class VoiceChatSessions { } else { session.controller.updateInput(text); } - } })); } @@ -262,10 +312,11 @@ class VoiceChatSessions { ); } - stop(voiceChatSessionId = this.voiceChatSessionIds): void { + stop(voiceChatSessionId = this.voiceChatSessionIds, context?: VoiceChatSessionContext): void { if ( !this.currentVoiceChatSession || - this.voiceChatSessionIds !== voiceChatSessionId + this.voiceChatSessionIds !== voiceChatSessionId || + (context && this.currentVoiceChatSession.controller.context !== context) ) { return; } @@ -275,6 +326,11 @@ class VoiceChatSessions { this.voiceChatGettingReadyKey.set(false); this.voiceChatInProgressKey.set(false); + + this.quickVoiceChatInProgressKey.set(false); + this.inlineVoiceChatInProgressKey.set(false); + this.voiceChatInViewInProgressKey.set(false); + this.voiceChatInEditorInProgressKey.set(false); } accept(voiceChatSessionId = this.voiceChatSessionIds): void { @@ -381,16 +437,16 @@ class StartVoiceChatAction extends Action2 { value: localize('workbench.action.chat.startVoiceChat', "Start Voice Chat"), original: 'Start Voice Chat' }, - icon: Codicon.record, + icon: Codicon.mic, precondition: CONTEXT_VOICE_CHAT_GETTING_READY.negate(), menu: [{ id: MenuId.ChatExecute, - when: CONTEXT_VOICE_CHAT_IN_PROGRESS.negate(), + when: ContextKeyExpr.and(CONTEXT_VOICE_CHAT_IN_VIEW_IN_PROGRESS.negate(), CONTEXT_QUICK_VOICE_CHAT_IN_PROGRESS.negate(), CONTEXT_VOICE_CHAT_IN_EDITOR_IN_PROGRESS.negate()), group: 'navigation', order: -1 }, { id: MENU_INLINE_CHAT_WIDGET, - when: CONTEXT_VOICE_CHAT_IN_PROGRESS.negate(), + when: CONTEXT_INLINE_VOICE_CHAT_IN_PROGRESS.negate(), group: 'main', order: -1 }] @@ -406,6 +462,9 @@ class StartVoiceChatAction extends Action2 { // from a toolbar within the chat widget, then make sure // to move focus into the input field so that the controller // is properly retrieved + // TODO@bpasero this will actually not work if the button + // is clicked from the inline editor while focus is in a + // chat input field in a view or picker context.widget.focusInput(); } @@ -437,16 +496,136 @@ class StopVoiceChatAction extends Action2 { when: CONTEXT_VOICE_CHAT_IN_PROGRESS, primary: KeyCode.Escape }, - precondition: CONTEXT_VOICE_CHAT_IN_PROGRESS, + precondition: CONTEXT_VOICE_CHAT_IN_PROGRESS + }); + } + + run(accessor: ServicesAccessor): void { + VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).stop(); + } +} + +class StopVoiceChatInChatViewAction extends Action2 { + + static readonly ID = 'workbench.action.chat.stopVoiceChatInChatView'; + + constructor() { + super({ + id: StopVoiceChatInChatViewAction.ID, + title: { + value: localize('workbench.action.chat.stopVoiceChatInChatView.label', "Stop Voice Chat (Chat View)"), + original: 'Stop Voice Chat (Chat View)' + }, + category: CHAT_CATEGORY, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib + 100, + when: CONTEXT_VOICE_CHAT_IN_VIEW_IN_PROGRESS, + primary: KeyCode.Escape + }, + precondition: CONTEXT_VOICE_CHAT_IN_VIEW_IN_PROGRESS, icon: spinningLoading, menu: [{ id: MenuId.ChatExecute, - when: CONTEXT_VOICE_CHAT_IN_PROGRESS, + when: CONTEXT_VOICE_CHAT_IN_VIEW_IN_PROGRESS, group: 'navigation', order: -1 - }, { + }] + }); + } + + run(accessor: ServicesAccessor): void { + VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).stop(undefined, 'view'); + } +} + +class StopVoiceChatInChatEditorAction extends Action2 { + + static readonly ID = 'workbench.action.chat.stopVoiceChatInChatEditor'; + + constructor() { + super({ + id: StopVoiceChatInChatEditorAction.ID, + title: { + value: localize('workbench.action.chat.stopVoiceChatInChatEditor.label', "Stop Voice Chat (Chat Editor)"), + original: 'Stop Voice Chat (Chat Editor)' + }, + category: CHAT_CATEGORY, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib + 100, + when: CONTEXT_VOICE_CHAT_IN_EDITOR_IN_PROGRESS, + primary: KeyCode.Escape + }, + precondition: CONTEXT_VOICE_CHAT_IN_EDITOR_IN_PROGRESS, + icon: spinningLoading, + menu: [{ + id: MenuId.ChatExecute, + when: CONTEXT_VOICE_CHAT_IN_EDITOR_IN_PROGRESS, + group: 'navigation', + order: -1 + }] + }); + } + + run(accessor: ServicesAccessor): void { + VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).stop(undefined, 'editor'); + } +} + +class StopQuickVoiceChatAction extends Action2 { + + static readonly ID = 'workbench.action.chat.stopQuickVoiceChat'; + + constructor() { + super({ + id: StopQuickVoiceChatAction.ID, + title: { + value: localize('workbench.action.chat.stopQuickVoiceChat.label', "Stop Voice Chat (Quick Chat)"), + original: 'Stop Voice Chat (Quick Chat)' + }, + category: CHAT_CATEGORY, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib + 100, + when: CONTEXT_QUICK_VOICE_CHAT_IN_PROGRESS, + primary: KeyCode.Escape + }, + precondition: CONTEXT_QUICK_VOICE_CHAT_IN_PROGRESS, + icon: spinningLoading, + menu: [{ + id: MenuId.ChatExecute, + when: CONTEXT_QUICK_VOICE_CHAT_IN_PROGRESS, + group: 'navigation', + order: -1 + }] + }); + } + + run(accessor: ServicesAccessor): void { + VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).stop(undefined, 'quick'); + } +} + +class StopInlineVoiceChatAction extends Action2 { + + static readonly ID = 'workbench.action.chat.stopInlineVoiceChat'; + + constructor() { + super({ + id: StopInlineVoiceChatAction.ID, + title: { + value: localize('workbench.action.chat.stopInlineVoiceChat.label', "Stop Voice Chat (Inline Editor)"), + original: 'Stop Voice Chat (Inline Editor)' + }, + category: CHAT_CATEGORY, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib + 100, + when: CONTEXT_INLINE_VOICE_CHAT_IN_PROGRESS, + primary: KeyCode.Escape + }, + precondition: CONTEXT_INLINE_VOICE_CHAT_IN_PROGRESS, + icon: spinningLoading, + menu: [{ id: MENU_INLINE_CHAT_WIDGET, - when: CONTEXT_VOICE_CHAT_IN_PROGRESS, + when: CONTEXT_INLINE_VOICE_CHAT_IN_PROGRESS, group: 'main', order: -1 }] @@ -454,7 +633,7 @@ class StopVoiceChatAction extends Action2 { } run(accessor: ServicesAccessor): void { - VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).stop(); + VoiceChatSessions.getInstance(accessor.get(IInstantiationService)).stop(undefined, 'inline'); } } @@ -489,5 +668,10 @@ export function registerVoiceChatActions() { registerAction2(StartVoiceChatAction); registerAction2(StopVoiceChatAction); registerAction2(StopVoiceChatAndSubmitAction); + + registerAction2(StopVoiceChatInChatViewAction); + registerAction2(StopVoiceChatInChatEditorAction); + registerAction2(StopQuickVoiceChatAction); + registerAction2(StopInlineVoiceChatAction); } } From 204d0b30381bfaf3300061c42466bb5f3c0ed1a0 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 31 Aug 2023 10:05:57 +0200 Subject: [PATCH 147/198] window.title setting feedback (fix #191579) (#191885) --- src/vs/workbench/browser/workbench.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/workbench.contribution.ts b/src/vs/workbench/browser/workbench.contribution.ts index e41769f836d..a0aa8d51b7b 100644 --- a/src/vs/workbench/browser/workbench.contribution.ts +++ b/src/vs/workbench/browser/workbench.contribution.ts @@ -533,7 +533,7 @@ const registry = Registry.as(ConfigurationExtensions.Con // Window - let windowTitleDescription = localize('windowTitle', "Controls the window title based on the active editor. Variables are substituted based on the context:"); + let windowTitleDescription = localize('windowTitle', "Controls the window title based on the current context such as the opened workspace or active editor. Variables are substituted based on the context:"); windowTitleDescription += '\n- ' + [ localize('activeEditorShort', "`${activeEditorShort}`: the file name (e.g. myFile.txt)."), localize('activeEditorMedium', "`${activeEditorMedium}`: the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)."), From 8800b431813386df04a1cae1b7e592e9462b17d7 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 31 Aug 2023 10:41:37 +0200 Subject: [PATCH 148/198] some Some grid operations cause the `activeElement` to get lost (fix #189256) (#191886) --- src/vs/workbench/browser/parts/editor/editorActions.ts | 3 ++- src/vs/workbench/browser/parts/editor/editorPart.ts | 9 --------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index e3e5c11bfa6..149b76d8df9 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2264,7 +2264,8 @@ abstract class AbstractCreateEditorGroupAction extends Action2 { override async run(accessor: ServicesAccessor): Promise { const editorGroupService = accessor.get(IEditorGroupsService); - editorGroupService.addGroup(editorGroupService.activeGroup, this.direction, { activate: true }); + const group = editorGroupService.addGroup(editorGroupService.activeGroup, this.direction, { activate: true }); + group.focus(); } } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 8b733caa867..c424f439a4f 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -515,21 +515,12 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro addGroup(location: IEditorGroupView | GroupIdentifier, direction: GroupDirection, options?: IAddGroupOptions): IEditorGroupView { const locationView = this.assertGroupView(location); - const restoreFocus = this.shouldRestoreFocus(locationView.element); - const group = this.doAddGroup(locationView, direction); if (options?.activate) { this.doSetGroupActive(group); } - // Restore focus if we had it previously after completing the grid - // operation. That operation might cause reparenting of grid views - // which moves focus to the element otherwise. - if (restoreFocus) { - locationView.focus(); - } - return group; } From 1ebb673280bc69f979e56f1c4be49e79bad73530 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 31 Aug 2023 11:02:57 +0200 Subject: [PATCH 149/198] Linux: Notifications Accessible View only opens when focusing with mouse (fix #191705) (#191888) --- .../parts/notifications/notificationsCommands.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts index 1f3ec683798..52910366b5f 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts @@ -68,9 +68,19 @@ export function getNotificationFromContext(listService: IListService, context?: const list = listService.lastFocusedList; if (list instanceof WorkbenchList) { - const focusedElement = list.getFocusedElements()[0]; - if (isNotificationViewItem(focusedElement)) { - return focusedElement; + let element = list.getFocusedElements()[0]; + if (!isNotificationViewItem(element)) { + if (list.isDOMFocused()) { + // the notification list might have received focus + // via keyboard and might not have a focussed element. + // in that case just return the first element + // https://github.com/microsoft/vscode/issues/191705 + element = list.element(0); + } + } + + if (isNotificationViewItem(element)) { + return element; } } From fffb813460a4c51dc04f1391600c9f2f5018d13d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 31 Aug 2023 11:19:33 +0200 Subject: [PATCH 150/198] adding code --- .../client/src/jsonClient.ts | 24 +++++++++---------- .../server/src/jsonServer.ts | 21 +++++++++++++--- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonClient.ts b/extensions/json-language-features/client/src/jsonClient.ts index a801245a46d..ac918999e1a 100644 --- a/extensions/json-language-features/client/src/jsonClient.ts +++ b/extensions/json-language-features/client/src/jsonClient.ts @@ -8,12 +8,12 @@ export type JSONLanguageStatus = { schemas: string[] }; import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange, - ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, CodeActionKind, CodeAction + ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, CodeActionContext, CodeAction, Command, } from 'vscode'; import { LanguageClientOptions, RequestType, NotificationType, FormattingOptions as LSPFormattingOptions, DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams, - DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, BaseLanguageClient, ProvideFoldingRangeSignature, ProvideDocumentSymbolsSignature, ProvideDocumentColorsSignature + DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, BaseLanguageClient, ProvideFoldingRangeSignature, ProvideDocumentSymbolsSignature, ProvideDocumentColorsSignature, ProvideCodeActionsSignature } from 'vscode-languageclient'; @@ -172,7 +172,6 @@ export async function startClient(context: ExtensionContext, newLanguageClient: toDispose.push(commands.registerCommand('json.sort', async () => { - if (isClientReady) { const textEditor = window.activeTextEditor; if (textEditor) { @@ -303,16 +302,15 @@ export async function startClient(context: ExtensionContext, newLanguageClient: } return checkLimit(r); }, - provideCodeActions(doc) { - console.log('doc : ', doc); - console.log('inside of provideCodeActions'); - const codeActions: CodeAction[] = []; - const sortCodeAction = new CodeAction('Sort JSON', CodeActionKind.Source); - sortCodeAction.command = { - command: 'json.sort', - title: 'Sort JSON' - }; - return codeActions; + provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken, next: ProvideCodeActionsSignature) { + console.log('inside of provide code actions'); + console.log('next : ', next); + const r = next(document, range, context, token); + console.log('r : ', r); + if (isThenable<(Command | CodeAction)[] | null | undefined>(r)) { + return r; + } + return r; } } }; diff --git a/extensions/json-language-features/server/src/jsonServer.ts b/extensions/json-language-features/server/src/jsonServer.ts index 0282e6fa939..ae14131082c 100644 --- a/extensions/json-language-features/server/src/jsonServer.ts +++ b/extensions/json-language-features/server/src/jsonServer.ts @@ -6,12 +6,12 @@ import { Connection, TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType, - DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic + DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic, CodeActionKind } from 'vscode-languageserver'; import { runSafe, runSafeAsync } from './utils/runner'; import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnosticsPushSupport } from './utils/validation'; -import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position, SortOptions } from 'vscode-json-languageservice'; +import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position, SortOptions, CodeAction } from 'vscode-json-languageservice'; import { getLanguageModelCache } from './languageModelCache'; import { Utils, URI } from 'vscode-uri'; @@ -188,7 +188,8 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) documentSelector: null, interFileDependencies: false, workspaceDiagnostics: false - } + }, + codeActionProvider: true }; return { capabilities }; @@ -411,6 +412,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) connection.onDocumentSymbol((documentSymbolParams, token) => { return runSafe(runtime, () => { + console.log('inside of on document symbol'); const document = documents.get(documentSymbolParams.textDocument.uri); if (document) { const jsonDocument = getJSONDocument(document); @@ -424,6 +426,19 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) }, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token); }); + connection.onCodeAction((_codeActionParams, token) => { + return runSafe(runtime, () => { + console.log('Inside of on code action'); + const codeActions: CodeAction[] = []; + const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source); + sortCodeAction.command = { + command: 'json.sort', + title: 'Sort JSON' + }; + return codeActions; + }, [], `Error while retrieving code actions`, token); + }); + function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] { options.keepLines = keepLinesEnabled; From 31b6e070b2e97a7518cda7af1011b71b6383029f Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 31 Aug 2023 12:11:59 +0200 Subject: [PATCH 151/198] use CSS mask and icon-foreground color so that customized foreground colors also work for CSS --- .../browser/menuEntryActionViewItem.ts | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index 356ff5e1013..5a053caa296 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { $, addDisposableListener, append, asCSSUrl, EventType, ModifierKeyEmitter, prepend } from 'vs/base/browser/dom'; +import { $, addDisposableListener, append, asCSSUrl, EventType, ModifierKeyEmitter, prepend, reset } from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionViewItem, BaseActionViewItem, SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { DropdownMenuActionViewItem, IDropdownMenuActionViewItemOptions } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem'; @@ -257,17 +257,26 @@ export class MenuEntryActionViewItem extends ActionViewItem { }); } else { - // icon path/url - label.style.backgroundImage = ( - isDark(this._themeService.getColorTheme().type) - ? asCSSUrl(icon.dark) - : asCSSUrl(icon.light) - ); + // icon path/url - add special element with SVG-mask and icon color background + const svgUrl = isDark(this._themeService.getColorTheme().type) + ? asCSSUrl(icon.dark) + : asCSSUrl(icon.light); + + const svgIcon = $('span'); + svgIcon.style.webkitMask = `${svgUrl} no-repeat 50% 50%`; + svgIcon.style.webkitMaskOrigin = 'padding'; + svgIcon.style.background = 'var(--vscode-icon-foreground)'; + svgIcon.style.display = 'inline-block'; + svgIcon.style.width = '100%'; + svgIcon.style.height = '100%'; + + label.appendChild(svgIcon); label.classList.add('icon'); + this._itemClassDispose.value = combinedDisposable( toDisposable(() => { - label.style.backgroundImage = ''; label.classList.remove('icon'); + reset(label); }), this._themeService.onDidColorThemeChange(() => { // refresh when the theme changes in case we go between dark <-> light From 5306d2b89814ca1e52d4d9e7929dbc8c8cb18157 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 31 Aug 2023 12:21:38 +0200 Subject: [PATCH 152/198] don't inherit color for codicons from parent but use theme defined color --- src/vs/workbench/browser/media/part.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/workbench/browser/media/part.css b/src/vs/workbench/browser/media/part.css index bec9b2a6d75..a0628d68945 100644 --- a/src/vs/workbench/browser/media/part.css +++ b/src/vs/workbench/browser/media/part.css @@ -82,10 +82,6 @@ display: none; } -.monaco-workbench .part > .title > .title-actions .action-label.codicon { - color: inherit; -} - .monaco-workbench .part > .content { font-size: 13px; } From 07aacd25bbd0463b29e7274b46d2f1510d3ad735 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Thu, 31 Aug 2023 12:22:11 +0200 Subject: [PATCH 153/198] Initialize all services as soon as the first service is needed (#191890) Fixes microsoft/monaco-editor#4120: initialize all services as soon as the first service is needed --- src/vs/editor/standalone/browser/standaloneServices.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/editor/standalone/browser/standaloneServices.ts b/src/vs/editor/standalone/browser/standaloneServices.ts index e7297361013..01f2c6987ac 100644 --- a/src/vs/editor/standalone/browser/standaloneServices.ts +++ b/src/vs/editor/standalone/browser/standaloneServices.ts @@ -1114,6 +1114,9 @@ export module StandaloneServices { serviceCollection.set(IInstantiationService, instantiationService); export function get(serviceId: ServiceIdentifier): T { + if (!initialized) { + initialize({}); + } const r = serviceCollection.get(serviceId); if (!r) { throw new Error('Missing service ' + serviceId); From 596a9a8926eafd92b4b5a127cb6740da710f4c79 Mon Sep 17 00:00:00 2001 From: Johannes Date: Thu, 31 Aug 2023 12:24:29 +0200 Subject: [PATCH 154/198] removed unneccessary mask property, make FF happy --- src/vs/platform/actions/browser/menuEntryActionViewItem.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts index 5a053caa296..c6e7a926213 100644 --- a/src/vs/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/vs/platform/actions/browser/menuEntryActionViewItem.ts @@ -263,8 +263,7 @@ export class MenuEntryActionViewItem extends ActionViewItem { : asCSSUrl(icon.light); const svgIcon = $('span'); - svgIcon.style.webkitMask = `${svgUrl} no-repeat 50% 50%`; - svgIcon.style.webkitMaskOrigin = 'padding'; + svgIcon.style.webkitMask = svgIcon.style.mask = `${svgUrl} no-repeat 50% 50%`; svgIcon.style.background = 'var(--vscode-icon-foreground)'; svgIcon.style.display = 'inline-block'; svgIcon.style.width = '100%'; From 6b49d155ca9f2547e9e8ddfdb324db47da97411b Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Thu, 31 Aug 2023 12:21:07 +0200 Subject: [PATCH 155/198] Fixes #191892 --- src/vs/editor/common/config/diffEditor.ts | 4 ++-- .../config/editorConfigurationSchema.ts | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/common/config/diffEditor.ts b/src/vs/editor/common/config/diffEditor.ts index 2f2bc06f2d2..2a62c479848 100644 --- a/src/vs/editor/common/config/diffEditor.ts +++ b/src/vs/editor/common/config/diffEditor.ts @@ -5,7 +5,7 @@ import { ValidDiffEditorBaseOptions } from 'vs/editor/common/config/editorOptions'; -export const diffEditorDefaultOptions: ValidDiffEditorBaseOptions = { +export const diffEditorDefaultOptions = { enableSplitViewResizing: true, splitViewDefaultRatio: 0.5, renderSideBySide: true, @@ -34,4 +34,4 @@ export const diffEditorDefaultOptions: ValidDiffEditorBaseOptions = { onlyShowAccessibleDiffViewer: false, renderSideBySideInlineBreakpoint: 900, useInlineViewWhenSpaceIsLimited: true, -}; +} satisfies ValidDiffEditorBaseOptions; diff --git a/src/vs/editor/common/config/editorConfigurationSchema.ts b/src/vs/editor/common/config/editorConfigurationSchema.ts index 845adcd40ac..684ec85c33b 100644 --- a/src/vs/editor/common/config/editorConfigurationSchema.ts +++ b/src/vs/editor/common/config/editorConfigurationSchema.ts @@ -151,53 +151,53 @@ const editorConfiguration: IConfigurationNode = { }, 'diffEditor.maxComputationTime': { type: 'number', - default: 5000, + default: diffEditorDefaultOptions.maxComputationTime, description: nls.localize('maxComputationTime', "Timeout in milliseconds after which diff computation is cancelled. Use 0 for no timeout.") }, 'diffEditor.maxFileSize': { type: 'number', - default: 50, + default: diffEditorDefaultOptions.maxFileSize, description: nls.localize('maxFileSize', "Maximum file size in MB for which to compute diffs. Use 0 for no limit.") }, 'diffEditor.renderSideBySide': { type: 'boolean', - default: true, + default: diffEditorDefaultOptions.renderSideBySide, description: nls.localize('sideBySide', "Controls whether the diff editor shows the diff side by side or inline.") }, 'diffEditor.renderSideBySideInlineBreakpoint': { type: 'number', - default: true, + default: diffEditorDefaultOptions.renderSideBySideInlineBreakpoint, description: nls.localize('renderSideBySideInlineBreakpoint', "If the diff editor width is smaller than this value, the inline view is used.") }, 'diffEditor.useInlineViewWhenSpaceIsLimited': { type: 'boolean', - default: true, + default: diffEditorDefaultOptions.useInlineViewWhenSpaceIsLimited, description: nls.localize('useInlineViewWhenSpaceIsLimited', "If enabled and the editor width is too small, the inline view is used.") }, 'diffEditor.renderMarginRevertIcon': { type: 'boolean', - default: true, + default: diffEditorDefaultOptions.renderMarginRevertIcon, description: nls.localize('renderMarginRevertIcon', "When enabled, the diff editor shows arrows in its glyph margin to revert changes.") }, 'diffEditor.ignoreTrimWhitespace': { type: 'boolean', - default: true, + default: diffEditorDefaultOptions.ignoreTrimWhitespace, description: nls.localize('ignoreTrimWhitespace', "When enabled, the diff editor ignores changes in leading or trailing whitespace.") }, 'diffEditor.renderIndicators': { type: 'boolean', - default: true, + default: diffEditorDefaultOptions.renderIndicators, description: nls.localize('renderIndicators', "Controls whether the diff editor shows +/- indicators for added/removed changes.") }, 'diffEditor.codeLens': { type: 'boolean', - default: false, + default: diffEditorDefaultOptions.diffCodeLens, description: nls.localize('codeLens', "Controls whether the editor shows CodeLens.") }, 'diffEditor.wordWrap': { type: 'string', enum: ['off', 'on', 'inherit'], - default: 'inherit', + default: diffEditorDefaultOptions.diffWordWrap, markdownEnumDescriptions: [ nls.localize('wordWrap.off', "Lines will never wrap."), nls.localize('wordWrap.on', "Lines will wrap at the viewport width."), @@ -239,7 +239,7 @@ const editorConfiguration: IConfigurationNode = { }, 'diffEditor.experimental.showMoves': { type: 'boolean', - default: false, + default: diffEditorDefaultOptions.experimental.showMoves, markdownDescription: nls.localize('showMoves', "Controls whether the diff editor should show detected code moves. Only works when {0} is set.", '`#diffEditor.experimental.useVersion2#`') }, 'diffEditor.experimental.useVersion2': { @@ -250,7 +250,7 @@ const editorConfiguration: IConfigurationNode = { }, 'diffEditor.experimental.showEmptyDecorations': { type: 'boolean', - default: true, + default: diffEditorDefaultOptions.experimental.showEmptyDecorations, description: nls.localize('showEmptyDecorations', "Controls whether the diff editor shows empty decorations to see where characters got inserted or deleted."), } } From 06fdc0a6339c1b10c4b0d9739191d7606d43e9cb Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 31 Aug 2023 15:10:14 +0200 Subject: [PATCH 156/198] unsure how to register the provider --- .../client/src/jsonClient.ts | 52 +++++++++++++++---- .../server/src/jsonServer.ts | 11 ++-- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonClient.ts b/extensions/json-language-features/client/src/jsonClient.ts index ac918999e1a..171d1c33d44 100644 --- a/extensions/json-language-features/client/src/jsonClient.ts +++ b/extensions/json-language-features/client/src/jsonClient.ts @@ -8,7 +8,7 @@ export type JSONLanguageStatus = { schemas: string[] }; import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange, - ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, CodeActionContext, CodeAction, Command, + ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, CodeActionContext, CodeAction, Command, CodeActionProvider, Selection, CodeActionKind, } from 'vscode'; import { LanguageClientOptions, RequestType, NotificationType, FormattingOptions as LSPFormattingOptions, @@ -172,6 +172,7 @@ export async function startClient(context: ExtensionContext, newLanguageClient: toDispose.push(commands.registerCommand('json.sort', async () => { + if (isClientReady) { const textEditor = window.activeTextEditor; if (textEditor) { @@ -189,6 +190,35 @@ export async function startClient(context: ExtensionContext, newLanguageClient: } })); + class JSONCodeActionProvider implements CodeActionProvider { + + provideCodeActions(document: TextDocument, range: Range | Selection, context: CodeActionContext, token: CancellationToken): ProviderResult<(CodeAction | Command)[]> { + console.log('inside of provide code actions'); + const codeActions: CodeAction[] = []; + const sortCodeAction = new CodeAction('Sort JSON', CodeActionKind.Source); + sortCodeAction.command = { + command: 'json.sort', + title: 'Sort JSON' + }; + return codeActions; + } + } + + languages.registerCodeActionsProvider('*', new JSONCodeActionProvider()); + + // connection.onCodeAction((_codeActionParams, token) => { + // return runSafe(runtime, () => { + // console.log('Inside of on code action'); + // const codeActions: CodeAction[] = []; + // const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source); + // sortCodeAction.command = { + // command: 'json.sort', + // title: 'Sort JSON' + // }; + // return codeActions; + // }, [], `Error while retrieving code actions`, token); + // }); + // Options to control the language client const clientOptions: LanguageClientOptions = { // Register the server for json documents @@ -302,16 +332,16 @@ export async function startClient(context: ExtensionContext, newLanguageClient: } return checkLimit(r); }, - provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken, next: ProvideCodeActionsSignature) { - console.log('inside of provide code actions'); - console.log('next : ', next); - const r = next(document, range, context, token); - console.log('r : ', r); - if (isThenable<(Command | CodeAction)[] | null | undefined>(r)) { - return r; - } - return r; - } + // provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken, next: ProvideCodeActionsSignature) { + // console.log('inside of provide code actions'); + // console.log('next : ', next); + // const r = next(document, range, context, token); + // console.log('r : ', r); + // if (isThenable<(Command | CodeAction)[] | null | undefined>(r)) { + // return r; + // } + // return r; + // } } }; diff --git a/extensions/json-language-features/server/src/jsonServer.ts b/extensions/json-language-features/server/src/jsonServer.ts index ae14131082c..82c6a3cc317 100644 --- a/extensions/json-language-features/server/src/jsonServer.ts +++ b/extensions/json-language-features/server/src/jsonServer.ts @@ -6,12 +6,12 @@ import { Connection, TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType, - DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic, CodeActionKind + DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic, CodeAction, CodeActionKind } from 'vscode-languageserver'; import { runSafe, runSafeAsync } from './utils/runner'; import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnosticsPushSupport } from './utils/validation'; -import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position, SortOptions, CodeAction } from 'vscode-json-languageservice'; +import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position, SortOptions } from 'vscode-json-languageservice'; import { getLanguageModelCache } from './languageModelCache'; import { Utils, URI } from 'vscode-uri'; @@ -412,7 +412,6 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) connection.onDocumentSymbol((documentSymbolParams, token) => { return runSafe(runtime, () => { - console.log('inside of on document symbol'); const document = documents.get(documentSymbolParams.textDocument.uri); if (document) { const jsonDocument = getJSONDocument(document); @@ -426,6 +425,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) }, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token); }); + // connection.onCodeAction((_codeActionParams, token) => { return runSafe(runtime, () => { console.log('Inside of on code action'); @@ -439,6 +439,11 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) }, [], `Error while retrieving code actions`, token); }); + connection.onCodeActionResolve(async (codeAction, token) => { + return codeAction; + }); + // + function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] { options.keepLines = keepLinesEnabled; From 70694338048e575132149ac39b91102cb552d6f9 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 31 Aug 2023 15:34:10 +0200 Subject: [PATCH 157/198] cleaning the code --- .../client/src/jsonClient.ts | 45 ++----------------- .../server/src/jsonServer.ts | 30 ++++++------- 2 files changed, 16 insertions(+), 59 deletions(-) diff --git a/extensions/json-language-features/client/src/jsonClient.ts b/extensions/json-language-features/client/src/jsonClient.ts index 171d1c33d44..3f191f165cf 100644 --- a/extensions/json-language-features/client/src/jsonClient.ts +++ b/extensions/json-language-features/client/src/jsonClient.ts @@ -8,12 +8,12 @@ export type JSONLanguageStatus = { schemas: string[] }; import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange, - ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n, CodeActionContext, CodeAction, Command, CodeActionProvider, Selection, CodeActionKind, + ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation, l10n } from 'vscode'; import { LanguageClientOptions, RequestType, NotificationType, FormattingOptions as LSPFormattingOptions, DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams, - DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, BaseLanguageClient, ProvideFoldingRangeSignature, ProvideDocumentSymbolsSignature, ProvideDocumentColorsSignature, ProvideCodeActionsSignature + DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, BaseLanguageClient, ProvideFoldingRangeSignature, ProvideDocumentSymbolsSignature, ProvideDocumentColorsSignature } from 'vscode-languageclient'; @@ -190,35 +190,6 @@ export async function startClient(context: ExtensionContext, newLanguageClient: } })); - class JSONCodeActionProvider implements CodeActionProvider { - - provideCodeActions(document: TextDocument, range: Range | Selection, context: CodeActionContext, token: CancellationToken): ProviderResult<(CodeAction | Command)[]> { - console.log('inside of provide code actions'); - const codeActions: CodeAction[] = []; - const sortCodeAction = new CodeAction('Sort JSON', CodeActionKind.Source); - sortCodeAction.command = { - command: 'json.sort', - title: 'Sort JSON' - }; - return codeActions; - } - } - - languages.registerCodeActionsProvider('*', new JSONCodeActionProvider()); - - // connection.onCodeAction((_codeActionParams, token) => { - // return runSafe(runtime, () => { - // console.log('Inside of on code action'); - // const codeActions: CodeAction[] = []; - // const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source); - // sortCodeAction.command = { - // command: 'json.sort', - // title: 'Sort JSON' - // }; - // return codeActions; - // }, [], `Error while retrieving code actions`, token); - // }); - // Options to control the language client const clientOptions: LanguageClientOptions = { // Register the server for json documents @@ -331,17 +302,7 @@ export async function startClient(context: ExtensionContext, newLanguageClient: return r.then(checkLimit); } return checkLimit(r); - }, - // provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken, next: ProvideCodeActionsSignature) { - // console.log('inside of provide code actions'); - // console.log('next : ', next); - // const r = next(document, range, context, token); - // console.log('r : ', r); - // if (isThenable<(Command | CodeAction)[] | null | undefined>(r)) { - // return r; - // } - // return r; - // } + } } }; diff --git a/extensions/json-language-features/server/src/jsonServer.ts b/extensions/json-language-features/server/src/jsonServer.ts index 82c6a3cc317..d88b80587dc 100644 --- a/extensions/json-language-features/server/src/jsonServer.ts +++ b/extensions/json-language-features/server/src/jsonServer.ts @@ -425,25 +425,21 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) }, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token); }); - // - connection.onCodeAction((_codeActionParams, token) => { - return runSafe(runtime, () => { - console.log('Inside of on code action'); - const codeActions: CodeAction[] = []; - const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source); - sortCodeAction.command = { - command: 'json.sort', - title: 'Sort JSON' - }; - return codeActions; - }, [], `Error while retrieving code actions`, token); + connection.onCodeAction((codeActionParams, token) => { + return runSafeAsync(runtime, async () => { + const document = documents.get(codeActionParams.textDocument.uri); + if (document) { + const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source); + sortCodeAction.command = { + command: 'json.sort', + title: 'Sort JSON' + }; + return [sortCodeAction]; + } + return []; + }, [], `Error while computing code actions for ${codeActionParams.textDocument.uri}`, token); }); - connection.onCodeActionResolve(async (codeAction, token) => { - return codeAction; - }); - // - function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] { options.keepLines = keepLinesEnabled; From ab975ebe2868796ef2847b5fe4389a078f0c1cd5 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 31 Aug 2023 16:02:06 +0200 Subject: [PATCH 158/198] adding also sort and json into the name --- extensions/json-language-features/server/src/jsonServer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/json-language-features/server/src/jsonServer.ts b/extensions/json-language-features/server/src/jsonServer.ts index d88b80587dc..9b353d913ed 100644 --- a/extensions/json-language-features/server/src/jsonServer.ts +++ b/extensions/json-language-features/server/src/jsonServer.ts @@ -429,7 +429,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) return runSafeAsync(runtime, async () => { const document = documents.get(codeActionParams.textDocument.uri); if (document) { - const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source); + const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source.concat('.sort', '.json')); sortCodeAction.command = { command: 'json.sort', title: 'Sort JSON' From a5fabc665be6c92ab5e4537c91347a661f8a4918 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 31 Aug 2023 07:47:49 -0700 Subject: [PATCH 159/198] fix #186904 --- .../accessibility/browser/textAreaSyncAddon.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts index 9916a6f60d0..c779eef46dc 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -100,9 +100,9 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } - if (!!currentCommand.commandStartX) { - this._currentCommand = commandLine.substring(currentCommand.commandStartX); - this._cursorX = buffer.cursorX - currentCommand.commandStartX; + if (!!currentCommand) { + this._currentCommand = commandLine.substring(currentCommand.commandStartX ?? 0); + this._cursorX = buffer.cursorX - (currentCommand.commandStartX ?? 0); } else { this._currentCommand = undefined; this._cursorX = undefined; From 9637c47fdc5498a5206470ea36e28977bf271f56 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 31 Aug 2023 08:03:54 -0700 Subject: [PATCH 160/198] check if mac --- .../accessibility/browser/textAreaSyncAddon.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts index c779eef46dc..5c6d8579ac3 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -10,6 +10,7 @@ import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; import type { Terminal, ITerminalAddon } from 'xterm'; import { debounce } from 'vs/base/common/decorators'; import { addDisposableListener } from 'vs/base/browser/dom'; +import { isMacintosh } from 'vs/base/common/platform'; export interface ITextAreaData { content: string; @@ -100,9 +101,10 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } - if (!!currentCommand) { - this._currentCommand = commandLine.substring(currentCommand.commandStartX ?? 0); - this._cursorX = buffer.cursorX - (currentCommand.commandStartX ?? 0); + const startX = isMacintosh ? currentCommand.commandStartX : 0; + if (!!currentCommand && !!startX) { + this._currentCommand = commandLine.substring(startX); + this._cursorX = buffer.cursorX - startX; } else { this._currentCommand = undefined; this._cursorX = undefined; From 414606b665b564d5ea4cce008531c7b23555bdd0 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Thu, 31 Aug 2023 17:30:16 +0200 Subject: [PATCH 161/198] Don't throw if view doesn't exist when visibility false (#191781) --- src/vs/workbench/api/common/extHostTreeViews.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vs/workbench/api/common/extHostTreeViews.ts b/src/vs/workbench/api/common/extHostTreeViews.ts index 3f33b7d7b62..844b0b63eae 100644 --- a/src/vs/workbench/api/common/extHostTreeViews.ts +++ b/src/vs/workbench/api/common/extHostTreeViews.ts @@ -246,6 +246,9 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape { $setVisible(treeViewId: string, isVisible: boolean): void { const treeView = this.treeViews.get(treeViewId); if (!treeView) { + if (!isVisible) { + return; + } throw new NoTreeViewError(treeViewId); } treeView.setVisible(isVisible); From 68a8e14d305982c6468019082454681a1bd76c76 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 31 Aug 2023 08:43:49 -0700 Subject: [PATCH 162/198] fix issue --- .../accessibility/browser/textAreaSyncAddon.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts index 5c6d8579ac3..8e6e18b28e5 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -101,8 +101,8 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } - const startX = isMacintosh ? currentCommand.commandStartX : 0; - if (!!currentCommand && !!startX) { + const startX = isMacintosh || currentCommand.commandStartX !== undefined ? currentCommand.commandStartX : 0; + if (!!currentCommand && startX !== undefined) { this._currentCommand = commandLine.substring(startX); this._cursorX = buffer.cursorX - startX; } else { From 6ca26d992b6de880cae1e5eb975ce88582260caa Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 31 Aug 2023 09:08:40 -0700 Subject: [PATCH 163/198] different udf check --- .../accessibility/browser/textAreaSyncAddon.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts index 8e6e18b28e5..b5e800a788d 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -10,7 +10,6 @@ import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; import type { Terminal, ITerminalAddon } from 'xterm'; import { debounce } from 'vs/base/common/decorators'; import { addDisposableListener } from 'vs/base/browser/dom'; -import { isMacintosh } from 'vs/base/common/platform'; export interface ITextAreaData { content: string; @@ -101,10 +100,9 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } - const startX = isMacintosh || currentCommand.commandStartX !== undefined ? currentCommand.commandStartX : 0; - if (!!currentCommand && startX !== undefined) { - this._currentCommand = commandLine.substring(startX); - this._cursorX = buffer.cursorX - startX; + if (currentCommand?.commandStartX !== undefined) { + this._currentCommand = commandLine.substring(currentCommand.commandStartX); + this._cursorX = buffer.cursorX - currentCommand.commandStartX; } else { this._currentCommand = undefined; this._cursorX = undefined; From a3d842ed4d190fbcf30d2c76460379cd8bab8b50 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Thu, 31 Aug 2023 09:29:53 -0700 Subject: [PATCH 164/198] Update src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com> --- .../terminalContrib/accessibility/browser/textAreaSyncAddon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts index b5e800a788d..33d4b52e956 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/browser/textAreaSyncAddon.ts @@ -100,7 +100,7 @@ export class TextAreaSyncAddon extends Disposable implements ITerminalAddon { this._logService.debug(`TextAreaSyncAddon#updateCommandAndCursor: no line`); return; } - if (currentCommand?.commandStartX !== undefined) { + if (currentCommand.commandStartX !== undefined) { this._currentCommand = commandLine.substring(currentCommand.commandStartX); this._cursorX = buffer.cursorX - currentCommand.commandStartX; } else { From eec2fc723c952f18c7ca0005c2bcf8840c819d38 Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 31 Aug 2023 13:10:26 -0700 Subject: [PATCH 165/198] Disable Local Server flow for REH (#191930) Because spinning up ports on the remote won't always work. Instead, we have the trusty device code flow. Fixes https://github.com/microsoft/vscode/issues/191866 Fixes https://github.com/microsoft/vscode/issues/191867 --- extensions/github-authentication/src/flows.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/github-authentication/src/flows.ts b/extensions/github-authentication/src/flows.ts index 5bc9d095385..1e988d92d30 100644 --- a/extensions/github-authentication/src/flows.ts +++ b/extensions/github-authentication/src/flows.ts @@ -200,7 +200,9 @@ const allFlows: IFlow[] = [ // other flows that work well. supportsGitHubEnterpriseServer: false, supportsHostedGitHubEnterprise: true, - supportsRemoteExtensionHost: true, + // Opening a port on the remote side can't be open in the browser on + // the client side so this flow won't work in remote extension hosts + supportsRemoteExtensionHost: false, // Web worker can't open a port to listen for the redirect supportsWebWorkerExtensionHost: false, // exchanging a code for a token requires a client secret From 065d4c1e23b278e2a277e80b23c07627b0efa4eb Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Thu, 31 Aug 2023 14:28:15 -0700 Subject: [PATCH 166/198] Do not show parent checkbox contents for ai generated workspaces (#191933) --- .../contrib/workspace/browser/workspace.contribution.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts index 077b248bc0f..864a19e1ce4 100644 --- a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts +++ b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts @@ -311,13 +311,12 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon this._register(this.workspaceTrustRequestService.onDidInitiateWorkspaceTrustRequestOnStartup(async () => { let titleString: string | undefined; - let checkboxString: string | undefined; let learnMoreString: string | undefined; let trustOption: string | undefined; let dontTrustOption: string | undefined; - if (await this.isAiGeneratedWorkspace() && this.productService.aiGeneratedWorkspaceTrust) { + const isAiGeneratedWorkspace = await this.isAiGeneratedWorkspace(); + if (isAiGeneratedWorkspace && this.productService.aiGeneratedWorkspaceTrust) { titleString = this.productService.aiGeneratedWorkspaceTrust.title; - checkboxString = this.productService.aiGeneratedWorkspaceTrust.checkboxText; learnMoreString = this.productService.aiGeneratedWorkspaceTrust.startupTrustRequestLearnMore; trustOption = this.productService.aiGeneratedWorkspaceTrust.trustOption; dontTrustOption = this.productService.aiGeneratedWorkspaceTrust.dontTrustOption; @@ -333,9 +332,9 @@ export class WorkspaceTrustUXHandler extends Disposable implements IWorkbenchCon const workspaceIdentifier = toWorkspaceIdentifier(this.workspaceContextService.getWorkspace()); const isSingleFolderWorkspace = isSingleFolderWorkspaceIdentifier(workspaceIdentifier); const isEmptyWindow = isEmptyWorkspaceIdentifier(workspaceIdentifier); - if (this.workspaceTrustManagementService.canSetParentFolderTrust()) { + if (!isAiGeneratedWorkspace && this.workspaceTrustManagementService.canSetParentFolderTrust()) { const name = basename(uriDirname((workspaceIdentifier as ISingleFolderWorkspaceIdentifier).uri)); - checkboxText = checkboxString ?? localize('checkboxString', "Trust the authors of all files in the parent folder '{0}'", name); + checkboxText = localize('checkboxString', "Trust the authors of all files in the parent folder '{0}'", name); } // Show Workspace Trust Start Dialog From 79277e0b8f045483a49f8a6834d476410c0d3cba Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 31 Aug 2023 14:34:22 -0700 Subject: [PATCH 167/198] Skip flakey smoke test (#191936) * Skip flakey smoke test ref https://github.com/microsoft/vscode/issues/191860 * skip at describe since there's only 1 test --- test/smoke/src/areas/extensions/extensions.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/smoke/src/areas/extensions/extensions.test.ts b/test/smoke/src/areas/extensions/extensions.test.ts index 7a4875bcd7f..a8120cb12bf 100644 --- a/test/smoke/src/areas/extensions/extensions.test.ts +++ b/test/smoke/src/areas/extensions/extensions.test.ts @@ -7,7 +7,7 @@ import { Application, Logger } from '../../../../automation'; import { installAllHandlers } from '../../utils'; export function setup(logger: Logger) { - describe('Extensions', () => { + describe.skip('Extensions', () => { // Shared before/after handling installAllHandlers(logger); From 4c6dbcf90f338caae79babdf8d48e6524a86fbe7 Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Thu, 31 Aug 2023 15:28:39 -0700 Subject: [PATCH 168/198] Add check to see if resource has file extension before setting FILE | FOLDER (#191923) * Set resource as FILE only if children are undefined * Add check to see if resource has extension before setting FileKind --- src/vs/workbench/contrib/chat/browser/chatListRenderer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 8ba6d711809..4bfefbd3af3 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -1200,7 +1200,8 @@ class ChatListTreeRenderer implements ICompressibleTreeRenderer, index: number, templateData: IChatListTreeRendererTemplate, height: number | undefined): void { templateData.label.element.style.display = 'flex'; - if (!element.children.length) { + const hasExtension = /\.[^/.]+$/.test(element.element.label); + if (!element.children.length && hasExtension) { templateData.label.setFile(element.element.uri, { fileKind: FileKind.FILE, hidePath: true, From 8f33e459f6af6c408655a1875c3475e71f45993f Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Thu, 31 Aug 2023 15:51:04 -0700 Subject: [PATCH 169/198] Only update layout when chat is visible (#191943) Fixes https://github.com/microsoft/vscode/issues/191942 --- src/vs/workbench/contrib/chat/browser/chatQuick.ts | 14 +++++++++++++- .../workbench/contrib/chat/browser/chatWidget.ts | 11 +++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatQuick.ts b/src/vs/workbench/contrib/chat/browser/chatQuick.ts index 32592d223ab..5c41a1a6f7e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatQuick.ts +++ b/src/vs/workbench/contrib/chat/browser/chatQuick.ts @@ -134,6 +134,7 @@ class QuickChat extends Disposable { private model: ChatModel | undefined; private _currentQuery: string | undefined; private maintainScrollTimer: MutableDisposable = this._register(new MutableDisposable()); + private _deferUpdatingDynamicLayout: boolean = false; constructor( private readonly _options: IChatViewOptions, @@ -183,6 +184,10 @@ class QuickChat extends Disposable { this.widget.setVisible(true); // If the mutable disposable is set, then we are keeping the existing scroll position // so we should not update the layout. + if (this._deferUpdatingDynamicLayout) { + this._deferUpdatingDynamicLayout = false; + this.widget.updateDynamicChatTreeItemLayout(2, this.maxHeight); + } if (!this.maintainScrollTimer.value) { this.widget.layoutDynamicChatTreeItemMode(); } @@ -222,7 +227,14 @@ class QuickChat extends Disposable { private registerListeners(parent: HTMLElement): void { this._register(this.layoutService.onDidLayout(() => { - this.widget.updateDynamicChatTreeItemLayout(2, this.maxHeight); + if (this.widget.visible) { + this.widget.updateDynamicChatTreeItemLayout(2, this.maxHeight); + } else { + // If the chat is not visible, then we should defer updating the layout + // because it relies on offsetHeight which only works correctly + // when the chat is visible. + this._deferUpdatingDynamicLayout = true; + } })); this._register(this.widget.inputEditor.onDidChangeModelContent((e) => { this._currentQuery = this.widget.inputEditor.getValue(); diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index b37163a9990..91c15635f2e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -77,9 +77,12 @@ export class ChatWidget extends Disposable implements IChatWidget { private container!: HTMLElement; private bodyDimension: dom.Dimension | undefined; - private visible = false; private visibleChangeCount = 0; private requestInProgress: IContextKey; + private _visible = false; + public get visible() { + return this._visible; + } private previousTreeScrollHeight: number = 0; @@ -214,7 +217,7 @@ export class ChatWidget extends Disposable implements IChatWidget { } private onDidChangeItems(skipDynamicLayout?: boolean) { - if (this.tree && this.visible) { + if (this.tree && this._visible) { const treeItems = (this.viewModel?.getItems() ?? []) .map(item => { return >{ @@ -261,7 +264,7 @@ export class ChatWidget extends Disposable implements IChatWidget { } setVisible(visible: boolean): void { - this.visible = visible; + this._visible = visible; this.visibleChangeCount++; this.renderer.setVisible(visible); @@ -269,7 +272,7 @@ export class ChatWidget extends Disposable implements IChatWidget { this._register(disposableTimeout(() => { // Progressive rendering paused while hidden, so start it up again. // Do it after a timeout because the container is not visible yet (it should be but offsetHeight returns 0 here) - if (this.visible) { + if (this._visible) { this.onDidChangeItems(true); } }, 0)); From ee08fd53cc990f4e8abaabf6e8014b3208128771 Mon Sep 17 00:00:00 2001 From: Joyce Er Date: Thu, 31 Aug 2023 15:52:13 -0700 Subject: [PATCH 170/198] Don't show chat widget context menu for filetree (#191940) --- src/vs/workbench/contrib/chat/browser/chatListRenderer.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts index 4bfefbd3af3..ebb17cc541f 100644 --- a/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts +++ b/src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @@ -539,6 +539,10 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer { this._onDidChangeItemHeight.fire({ element, height: templateData.rowContainer.offsetHeight }); })); + treeDisposables.add(tree.onContextMenu((e) => { + e.browserEvent.preventDefault(); + e.browserEvent.stopPropagation(); + })); tree.setInput(data).then(() => { if (!ref.isStale()) { From dd112ec0243c4b42bb3106e64df1688e242a6559 Mon Sep 17 00:00:00 2001 From: Bhavya U Date: Thu, 31 Aug 2023 16:37:56 -0700 Subject: [PATCH 171/198] Open walkthrough if a gettingStarted page is found (#191947) --- .../browser/gettingStarted.contribution.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts index a6da647dbcc..1e57d47d68a 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts @@ -66,10 +66,8 @@ registerAction2(class extends Action2 { // Try first to select the walkthrough on an active welcome page with no selected walkthrough for (const group of editorGroupsService.groups) { if (group.activeEditor instanceof GettingStartedInput) { - if (!group.activeEditor.selectedCategory) { - (group.activeEditorPane as GettingStartedPage).makeCategoryVisibleWhenAvailable(selectedCategory, selectedStep); - return; - } + (group.activeEditorPane as GettingStartedPage).makeCategoryVisibleWhenAvailable(selectedCategory, selectedStep); + return; } } @@ -106,7 +104,10 @@ registerAction2(class extends Action2 { editorService.openEditor({ resource: GettingStartedInput.RESOURCE, options: { selectedCategory: selectedCategory, selectedStep: selectedStep, preserveFocus: toSide ?? false } + }).then((editor) => { + (editor as GettingStartedPage)?.makeCategoryVisibleWhenAvailable(selectedCategory, selectedStep); }); + } } else { editorService.openEditor({ resource: GettingStartedInput.RESOURCE }); From 5f7b620db8ec603453798554a6596a7ad608fb3e Mon Sep 17 00:00:00 2001 From: Robo Date: Fri, 1 Sep 2023 15:32:05 +0900 Subject: [PATCH 172/198] chore: bump electron@25.8.0 (#191905) * chore: bump electron@25.8.0 * chore: update internal build id * chore: bump distro --- .yarnrc | 4 +-- build/checksums/electron.txt | 54 ++++++++++++++++++------------------ cgmanifest.json | 4 +-- package.json | 4 +-- yarn.lock | 8 +++--- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/.yarnrc b/.yarnrc index 7b3fff4b526..fff0be195f2 100644 --- a/.yarnrc +++ b/.yarnrc @@ -1,5 +1,5 @@ disturl "https://electronjs.org/headers" -target "25.7.0" -ms_build_id "23434598" +target "25.8.0" +ms_build_id "23503258" runtime "electron" build_from_source "true" diff --git a/build/checksums/electron.txt b/build/checksums/electron.txt index a19497f08e8..9c46b2ad8ef 100644 --- a/build/checksums/electron.txt +++ b/build/checksums/electron.txt @@ -1,27 +1,27 @@ -efbcf77eb1a0783766f9579ffb9f9b68f04fea8cb091eab7ab8484ba0cd13fbf *electron-v25.7.0-darwin-arm64-symbols.zip -76a415165d212a345a5689de83078adc715fc10562bfaa35d7323094780ba683 *electron-v25.7.0-darwin-arm64.zip -07b9049848e877019d1dce71e06713125b605dda8ac5d0b8ab3aa899cf40551d *electron-v25.7.0-darwin-x64-symbols.zip -dea726ae9adc1c36206ce8d20ce32f630bcd684b869e0cb302f97c8bd26616d6 *electron-v25.7.0-darwin-x64.zip -b6c8ba123353984b2d3ffd6ccd52aec2d3238f71611c4c94bab75aa92804eebf *electron-v25.7.0-linux-arm64-symbols.zip -19e1e2c7ea1ab024f069e3dad6a26605e14b2c605e134484196343118fccf925 *electron-v25.7.0-linux-arm64.zip -ba0bbe84ea626c8064809c66487a3b77ad39bcf8b1daa0d9421428f78ad4d665 *electron-v25.7.0-linux-armv7l-symbols.zip -832a68cddb20eb847aca982b89f89e145f50dd483c71c8a705bbb9248fb7c665 *electron-v25.7.0-linux-armv7l.zip -2e616b446112533d3aa69ed1074ab1e0be5400996129aa636273d01462dc9506 *electron-v25.7.0-linux-x64-symbols.zip -002641e8103b77060e23b9c77c51ffb942372d01306210cdc3d32fc6ae5d112b *electron-v25.7.0-linux-x64.zip -162e0f7ca9fc1c17b8d84e9b9eccc65bb0f527a67f6339a19292d798085848e4 *electron-v25.7.0-win32-arm64-pdb.zip -7d98734ffcf10e1d002c30a212dd1f203b1418a295da67410490f83e9ced388c *electron-v25.7.0-win32-arm64-symbols.zip -9777d47f74d129f7c68ebffad640a6a527b83895c173c7d344f80fc9588bad85 *electron-v25.7.0-win32-arm64.zip -c805c6356378dccb21b5725004934534e187bdaf8149a6a457fdd60d243b41e4 *electron-v25.7.0-win32-ia32-pdb.zip -5f1a3b09153cf934f24f3b1853ad1788e7c27c6ddceb80e52fe07e2e69b6bb2b *electron-v25.7.0-win32-ia32-symbols.zip -fdf8e100c3d3cdb75b54ced1ecae96d6206eca08ebb07c5d8f08740e5e703509 *electron-v25.7.0-win32-ia32.zip -aa56314a675351e9457355f2cb0660c62a3be62cc340dad76fd216741064824d *electron-v25.7.0-win32-x64-pdb.zip -25d664dfe0823e1a12269feb6eb3886dba44b2d130b8787c4d58d3d0cbcf1c22 *electron-v25.7.0-win32-x64-symbols.zip -7ddb0b38207fd837cdf4e2b2778c365751315e321b09d346c8bb8476300d0ec0 *electron-v25.7.0-win32-x64.zip -02619733aadb13b6bf21df966e04775506d0d7595a0795003fed45631c4a0af6 *ffmpeg-v25.7.0-darwin-arm64.zip -69a8e2021e48f504021913c15633cbef2b4a7b28656c51cd238acdbf7c94e358 *ffmpeg-v25.7.0-darwin-x64.zip -bd52d57ff97fb56ac01a3482af905d04f0d4e9c13c53858c6d9f99957eca82da *ffmpeg-v25.7.0-linux-arm64.zip -9b3d09177fa1e63e2a6beecfa70aeec30aeb5c1873ff21128a68051c4e23f95d *ffmpeg-v25.7.0-linux-armv7l.zip -edc7b1c9f1a0733f109a2c0375a4e40c5bfe0bf28b7f06dcc76e1ada0aa2f125 *ffmpeg-v25.7.0-linux-x64.zip -7076d4593f2e2e2abf0dc9ad8f6490d72b2fa89710def822f39da4363e49e504 *ffmpeg-v25.7.0-win32-arm64.zip -bd07183c1b6a93586d73c4106ceef0faae77f46763d15d6901d5954c2c5bba1b *ffmpeg-v25.7.0-win32-ia32.zip -b056e71a7c59441c551d5bbc1a8d99f2464a5809a3ba17d41540dc7174cab7b7 *ffmpeg-v25.7.0-win32-x64.zip +88cafda8394985e59d3d84cb4a6692ad04d8e32db9ecd6429e748e41526ddad7 *electron-v25.8.0-darwin-arm64-symbols.zip +6e33d3b8041561722ed41777e055a8c15d3f4e61b67367b2618918bcf0cfea76 *electron-v25.8.0-darwin-arm64.zip +438ac9915e062a239fb6d2595323c4783d2c820efc9cbcf3d2c1253d0e057e83 *electron-v25.8.0-darwin-x64-symbols.zip +798907d2a66bc79202c8213c61e7fd147ae2a8c31c485d814950b11d43bbbba8 *electron-v25.8.0-darwin-x64.zip +3243f3764319cff6c942d9f90a86323c36ec05ec51ef01e782c4e9a7194187e1 *electron-v25.8.0-linux-arm64-symbols.zip +f24f858b76bf8a2e18419f62e0f891712b2fa541089123e9caa8d5cd67fc3276 *electron-v25.8.0-linux-arm64.zip +dc3ff0489a0ebeda56d06b31eeae75dd7321a52bb601069c4475c56462b4814a *electron-v25.8.0-linux-armv7l-symbols.zip +3b7a0c3899f828a5cf30043b73992e90231400b90c1afa700a44f892a55e326b *electron-v25.8.0-linux-armv7l.zip +44803b2487406eca8fff9cec405e9e50bd92a911808dfaaa523b9ef52a0e72d8 *electron-v25.8.0-linux-x64-symbols.zip +d54fb2df0ad7318240220aa26327171ed1e891fb296f3c27c58b8b487c4df8eb *electron-v25.8.0-linux-x64.zip +bf7be6c0c8d0df06f0ce22e16c97aea823415d7f5cbf0ffdadf65d75feaf3cd8 *electron-v25.8.0-win32-arm64-pdb.zip +5d91757660b44bf30907f9c2b52225ade4d127d0fe48dc83dec134cc06c949f0 *electron-v25.8.0-win32-arm64-symbols.zip +d1e6f30a8d8c7aed28d08ddf915d79de6b16b3a0a7c84c45fd3cc0d47f2b7f53 *electron-v25.8.0-win32-arm64.zip +e389fef61c14ea0eefad91a9725aa0afd4dbdc982f7b30aba97bd9c2871c2061 *electron-v25.8.0-win32-ia32-pdb.zip +374d6c8897f97fab04e990ecf928e05f643ae33801546bf7d39bf4045b9d8b52 *electron-v25.8.0-win32-ia32-symbols.zip +73fc3382202b70dcaf7928f09a791662de82c701b8f403ed72cc5aa9b1401593 *electron-v25.8.0-win32-ia32.zip +010d248bd2e77585e1fa977e58b016659566de5a91c1e6845c85a7e6e1851bb9 *electron-v25.8.0-win32-x64-pdb.zip +72adb74fd92edff35c177c3c5d96765f230bc7adb8af11b30d5122b9e54c26e1 *electron-v25.8.0-win32-x64-symbols.zip +0051d0f241aedc6cdab4751c60f48758936122796f06c9e3033c7710a531686c *electron-v25.8.0-win32-x64.zip +2956915642c45eb0099228368d0af50e891e4c10014fa4d3d3bcfb135fbb89a7 *ffmpeg-v25.8.0-darwin-arm64.zip +099ee69d44f8ac3802cdd612895f279f7adb043a5b9c9d123479b0f96514a44c *ffmpeg-v25.8.0-darwin-x64.zip +bd52d57ff97fb56ac01a3482af905d04f0d4e9c13c53858c6d9f99957eca82da *ffmpeg-v25.8.0-linux-arm64.zip +9b3d09177fa1e63e2a6beecfa70aeec30aeb5c1873ff21128a68051c4e23f95d *ffmpeg-v25.8.0-linux-armv7l.zip +edc7b1c9f1a0733f109a2c0375a4e40c5bfe0bf28b7f06dcc76e1ada0aa2f125 *ffmpeg-v25.8.0-linux-x64.zip +a58e9480dab981ff973749e9d1e08936b2dd63a4b7f9523c030b1833387a4eb5 *ffmpeg-v25.8.0-win32-arm64.zip +6866b23a4d561c0322aeb7690aae646718c54398739946e352bf80d0dd721bfd *ffmpeg-v25.8.0-win32-ia32.zip +7b906df4ad6252881cf1e58619285b624f74d593379fbc6728e238b852d6abad *ffmpeg-v25.8.0-win32-x64.zip diff --git a/cgmanifest.json b/cgmanifest.json index df2f75f3209..6b2d2bfff44 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -528,12 +528,12 @@ "git": { "name": "electron", "repositoryUrl": "https://github.com/electron/electron", - "commitHash": "f818ec3295c9688585e3cfea532ccc5b705746bb" + "commitHash": "84d7f7f071ae11637d4a41b95536410293672750" } }, "isOnlyProductionDependency": true, "license": "MIT", - "version": "25.7.0" + "version": "25.8.0" }, { "component": { diff --git a/package.json b/package.json index 1a58592be0a..997a4931166 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.82.0", - "distro": "021e674d5265eb9125cfc0282c3a9a6091f4982d", + "distro": "0a5805caff2d59440704a3bf75eebaa509be862f", "author": { "name": "Microsoft Corporation" }, @@ -150,7 +150,7 @@ "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.8.0", - "electron": "25.7.0", + "electron": "25.8.0", "eslint": "8.36.0", "eslint-plugin-header": "3.1.1", "eslint-plugin-jsdoc": "^39.3.2", diff --git a/yarn.lock b/yarn.lock index e171d0e0f55..aac325ba08f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3587,10 +3587,10 @@ electron-to-chromium@^1.4.202: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.207.tgz#9c3310ebace2952903d05dcaba8abe3a4ed44c01" integrity sha512-piH7MJDJp4rJCduWbVvmUd59AUne1AFBJ8JaRQvk0KzNTSUnZrVXHCZc+eg+CGE4OujkcLJznhGKD6tuAshj5Q== -electron@25.7.0: - version "25.7.0" - resolved "https://registry.yarnpkg.com/electron/-/electron-25.7.0.tgz#0076c2e6acfe363f666a7b77d826a6f8a3028bcd" - integrity sha512-P82EzYZ8k9J21x5syhXV7EkezDmEXwycReXnagfzS0kwepnrlWzq1aDIUWdNvzTdHobky4m/nYcL98qd73mEVA== +electron@25.8.0: + version "25.8.0" + resolved "https://registry.yarnpkg.com/electron/-/electron-25.8.0.tgz#60c84f1f256924ac5a0aff13276b901b0c43767a" + integrity sha512-T3kC1a/3ntSaYMCVVfUUc9v7myPzi6J2GP0Ad/CyfWKDPp054dGyKxb2EEjKnxQQ7wfjsT1JTEdBG04x6ekVBw== dependencies: "@electron/get" "^2.0.0" "@types/node" "^18.11.18" From a5f4583b51a2d181a7495b7344d9ef90ee3fc2f8 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 1 Sep 2023 09:41:12 +0200 Subject: [PATCH 173/198] 1.83.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 997a4931166..dfd24be8535 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "code-oss-dev", - "version": "1.82.0", + "version": "1.83.0", "distro": "0a5805caff2d59440704a3bf75eebaa509be862f", "author": { "name": "Microsoft Corporation" From 2ed3ef258820640f4bffbdd26c3393edc14910ac Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 1 Sep 2023 10:32:59 +0200 Subject: [PATCH 174/198] editors - do not focus empty editor group when created (#191966) --- src/vs/workbench/browser/parts/editor/editorActions.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index 149b76d8df9..e13b41e522f 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2264,8 +2264,12 @@ abstract class AbstractCreateEditorGroupAction extends Action2 { override async run(accessor: ServicesAccessor): Promise { const editorGroupService = accessor.get(IEditorGroupsService); - const group = editorGroupService.addGroup(editorGroupService.activeGroup, this.direction, { activate: true }); - group.focus(); + // We intentionally do not want the new group to be focussed so that + // a user can have keyboard focus e.g. in a tree/list, open a new + // editor group that is active and then arrow-up/down in the tree/list + // to pick an editor to open in that group + + editorGroupService.addGroup(editorGroupService.activeGroup, this.direction, { activate: true }); } } From e4a24b361aae8b1fa2d6513b46c7fa10f90d30cd Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Fri, 1 Sep 2023 11:41:21 +0200 Subject: [PATCH 175/198] Enable the family autodetection algorithm (#191971) Fixes #191945: Enable the family autodetection algorithm to support a case where localhost resolves first to the ipv6 address and only second to the ipv4 address, and the desired server listens only on ipv4 --- src/vs/server/node/remoteExtensionHostAgentServer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/server/node/remoteExtensionHostAgentServer.ts b/src/vs/server/node/remoteExtensionHostAgentServer.ts index 5a2d9943ac9..d1a0f51e783 100644 --- a/src/vs/server/node/remoteExtensionHostAgentServer.ts +++ b/src/vs/server/node/remoteExtensionHostAgentServer.ts @@ -551,7 +551,8 @@ class RemoteExtensionHostAgentServer extends Disposable implements IServerAPI { const socket = net.createConnection( { host: host, - port: port + port: port, + autoSelectFamily: true }, () => { socket.removeListener('error', e); socket.pause(); From 2c021905ad67daf18551e06661f86a76e2c64129 Mon Sep 17 00:00:00 2001 From: Alexandru Dima Date: Fri, 1 Sep 2023 13:40:20 +0200 Subject: [PATCH 176/198] Do not repaint decorations overview ruler if it is not necessary (#191931) Fixes #191423: Do not repaint decorations overview ruler if it is not necessary --- .../overviewRuler/decorationsOverviewRuler.ts | 57 ++++++++++++++++--- src/vs/editor/common/viewModel.ts | 12 ++++ 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts index 86db61f97e1..31e38a56c4d 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts @@ -17,6 +17,7 @@ import { EditorTheme } from 'vs/editor/common/editorTheme'; import * as viewEvents from 'vs/editor/common/viewEvents'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { OverviewRulerDecorationsGroup } from 'vs/editor/common/viewModel'; +import { equals } from 'vs/base/common/arrays'; class Settings { @@ -212,13 +213,24 @@ const enum OverviewRulerLane { Full = 7 } +const enum ShouldRenderValue { + NotNeeded = 0, + Maybe = 1, + Needed = 2 +} + export class DecorationsOverviewRuler extends ViewPart { + private _actualShouldRender: ShouldRenderValue = ShouldRenderValue.NotNeeded; + private readonly _tokensColorTrackerListener: IDisposable; private readonly _domNode: FastDomNode; private _settings!: Settings; private _cursorPositions: Position[]; + private _renderedDecorations: OverviewRulerDecorationsGroup[] = []; + private _renderedCursorPositions: Position[] = []; + constructor(context: ViewContext) { super(context); @@ -270,8 +282,18 @@ export class DecorationsOverviewRuler extends ViewPart { // ---- begin view event handlers + private _markRenderingIsNeeded(): true { + this._actualShouldRender = ShouldRenderValue.Needed; + return true; + } + + private _markRenderingIsMaybeNeeded(): true { + this._actualShouldRender = ShouldRenderValue.Maybe; + return true; + } + public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - return this._updateSettings(false); + return this._updateSettings(false) ? this._markRenderingIsNeeded() : false; } public override onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean { this._cursorPositions = []; @@ -279,25 +301,25 @@ export class DecorationsOverviewRuler extends ViewPart { this._cursorPositions[i] = e.selections[i].getPosition(); } this._cursorPositions.sort(Position.compare); - return true; + return this._markRenderingIsMaybeNeeded(); } public override onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { if (e.affectsOverviewRuler) { - return true; + return this._markRenderingIsMaybeNeeded(); } return false; } public override onFlushed(e: viewEvents.ViewFlushedEvent): boolean { - return true; + return this._markRenderingIsNeeded(); } public override onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean { - return e.scrollHeightChanged; + return e.scrollHeightChanged ? this._markRenderingIsNeeded() : false; } public override onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean { - return true; + return this._markRenderingIsNeeded(); } public override onThemeChanged(e: viewEvents.ViewThemeChangedEvent): boolean { - return this._updateSettings(false); + return this._updateSettings(false) ? this._markRenderingIsNeeded() : false; } // ---- end view event handlers @@ -312,6 +334,7 @@ export class DecorationsOverviewRuler extends ViewPart { public render(editorCtx: RestrictedRenderingContext): void { this._render(); + this._actualShouldRender = ShouldRenderValue.NotNeeded; } private _render(): void { @@ -322,6 +345,23 @@ export class DecorationsOverviewRuler extends ViewPart { this._domNode.setDisplay('none'); return; } + + const decorations = this._context.viewModel.getAllOverviewRulerDecorations(this._context.theme); + decorations.sort(OverviewRulerDecorationsGroup.cmp); + + if (this._actualShouldRender === ShouldRenderValue.Maybe && !OverviewRulerDecorationsGroup.equalsArr(this._renderedDecorations, decorations)) { + this._actualShouldRender = ShouldRenderValue.Needed; + } + if (this._actualShouldRender === ShouldRenderValue.Maybe && !equals(this._renderedCursorPositions, this._cursorPositions, (a, b) => a.lineNumber === b.lineNumber)) { + this._actualShouldRender = ShouldRenderValue.Needed; + } + if (this._actualShouldRender === ShouldRenderValue.Maybe) { + // both decorations and cursor positions are unchanged, nothing to do + return; + } + this._renderedDecorations = decorations; + this._renderedCursorPositions = this._cursorPositions; + this._domNode.setDisplay('block'); const canvasWidth = this._settings.canvasWidth; const canvasHeight = this._settings.canvasHeight; @@ -329,7 +369,6 @@ export class DecorationsOverviewRuler extends ViewPart { const viewLayout = this._context.viewLayout; const outerHeight = this._context.viewLayout.getScrollHeight(); const heightRatio = canvasHeight / outerHeight; - const decorations = this._context.viewModel.getAllOverviewRulerDecorations(this._context.theme); const minDecorationHeight = (Constants.MIN_DECORATION_HEIGHT * this._settings.pixelRatio) | 0; const halfMinDecorationHeight = (minDecorationHeight / 2) | 0; @@ -355,7 +394,7 @@ export class DecorationsOverviewRuler extends ViewPart { const x = this._settings.x; const w = this._settings.w; - decorations.sort(OverviewRulerDecorationsGroup.cmp); + for (const decorationGroup of decorations) { const color = decorationGroup.color; diff --git a/src/vs/editor/common/viewModel.ts b/src/vs/editor/common/viewModel.ts index e61ba01dc15..4e4b4d3032f 100644 --- a/src/vs/editor/common/viewModel.ts +++ b/src/vs/editor/common/viewModel.ts @@ -445,4 +445,16 @@ export class OverviewRulerDecorationsGroup { } return a.zIndex - b.zIndex; } + + public static equalsArr(a: OverviewRulerDecorationsGroup[], b: OverviewRulerDecorationsGroup[]): boolean { + if (a.length !== b.length) { + return false; + } + for (let i = 0, len = a.length; i < len; i++) { + if (OverviewRulerDecorationsGroup.cmp(a[i], b[i]) !== 0) { + return false; + } + } + return true; + } } From 02ddb145e8ae681362607bc76291fe9b8135c75b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 1 Sep 2023 14:10:57 +0200 Subject: [PATCH 177/198] additing translation l10n --- extensions/json-language-features/server/src/jsonServer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/json-language-features/server/src/jsonServer.ts b/extensions/json-language-features/server/src/jsonServer.ts index 9b353d913ed..36ca0dc591d 100644 --- a/extensions/json-language-features/server/src/jsonServer.ts +++ b/extensions/json-language-features/server/src/jsonServer.ts @@ -14,6 +14,7 @@ import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnostics import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position, SortOptions } from 'vscode-json-languageservice'; import { getLanguageModelCache } from './languageModelCache'; import { Utils, URI } from 'vscode-uri'; +import * as l10n from '@vscode/l10n'; type ISchemaAssociations = Record; @@ -432,7 +433,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) const sortCodeAction = CodeAction.create('Sort JSON', CodeActionKind.Source.concat('.sort', '.json')); sortCodeAction.command = { command: 'json.sort', - title: 'Sort JSON' + title: l10n.t('Sort JSON') }; return [sortCodeAction]; } From 415bc174ea00a7bbda4ca709e8dd86dd36a16336 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 Sep 2023 14:23:16 +0200 Subject: [PATCH 178/198] refine lint config, add missing jsdoc and jsdoc-tag corrections --- .eslintrc.json | 10 +- src/vscode-dts/vscode.d.ts | 1435 ++++++++++++++++++++++++++++-------- 2 files changed, 1141 insertions(+), 304 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index b2c303da84a..f44673cd1cd 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -201,9 +201,6 @@ "**/vscode.d.ts" ], "rules": { - "extends": [ - "plugin:jsdoc/recommended-typescript" - ], "jsdoc/tag-lines": "off", "jsdoc/valid-types": "off", "jsdoc/no-multi-asterisks": [ @@ -220,6 +217,7 @@ "TSInterfaceDeclaration", "TSPropertySignature", "TSMethodSignature", + "TSDeclareFunction", "ClassDeclaration", "MethodDefinition", "PropertyDeclaration", @@ -232,9 +230,11 @@ "jsdoc/check-param-names": [ "warn", { - "enableFixer": false + "enableFixer": false, + "checkDestructured": false } - ] + ], + "jsdoc/require-returns": "warn" } }, { diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 4f5c61daaa7..97f52cb344d 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -136,7 +136,7 @@ declare module 'vscode' { /** * Save the underlying file. * - * @return A promise that will resolve to `true` when the file + * @returns A promise that will resolve to `true` when the file * has been saved. If the save failed, will return `false`. */ save(): Thenable; @@ -158,7 +158,7 @@ declare module 'vscode' { * document are not reflected. * * @param line A line number in [0, lineCount). - * @return A {@link TextLine line}. + * @returns A {@link TextLine line}. */ lineAt(line: number): TextLine; @@ -172,7 +172,7 @@ declare module 'vscode' { * @see {@link TextDocument.lineAt} * * @param position A position. - * @return A {@link TextLine line}. + * @returns A {@link TextLine line}. */ lineAt(position: Position): TextLine; @@ -182,7 +182,7 @@ declare module 'vscode' { * The position will be {@link TextDocument.validatePosition adjusted}. * * @param position A position. - * @return A valid zero-based offset. + * @returns A valid zero-based offset. */ offsetAt(position: Position): number; @@ -190,7 +190,7 @@ declare module 'vscode' { * Converts a zero-based offset to a position. * * @param offset A zero-based offset. - * @return A valid {@link Position}. + * @returns A valid {@link Position}. */ positionAt(offset: number): Position; @@ -199,7 +199,7 @@ declare module 'vscode' { * a range. The range will be {@link TextDocument.validateRange adjusted}. * * @param range Include only the text included by the range. - * @return The text inside the provided range or the entire text. + * @returns The text inside the provided range or the entire text. */ getText(range?: Range): string; @@ -219,7 +219,7 @@ declare module 'vscode' { * * @param position A position. * @param regex Optional regular expression that describes what a word is. - * @return A range spanning a word, or `undefined`. + * @returns A range spanning a word, or `undefined`. */ getWordRangeAtPosition(position: Position, regex?: RegExp): Range | undefined; @@ -227,7 +227,7 @@ declare module 'vscode' { * Ensure a range is completely contained in this document. * * @param range A range. - * @return The given range or a new, adjusted range. + * @returns The given range or a new, adjusted range. */ validateRange(range: Range): Range; @@ -235,7 +235,7 @@ declare module 'vscode' { * Ensure a position is contained in the range of this document. * * @param position A position. - * @return The given position or a new, adjusted position. + * @returns The given position or a new, adjusted position. */ validatePosition(position: Position): Position; } @@ -270,7 +270,7 @@ declare module 'vscode' { * Check if this position is before `other`. * * @param other A position. - * @return `true` if position is on a smaller line + * @returns `true` if position is on a smaller line * or on the same line on a smaller character. */ isBefore(other: Position): boolean; @@ -279,7 +279,7 @@ declare module 'vscode' { * Check if this position is before or equal to `other`. * * @param other A position. - * @return `true` if position is on a smaller line + * @returns `true` if position is on a smaller line * or on the same line on a smaller or equal character. */ isBeforeOrEqual(other: Position): boolean; @@ -288,7 +288,7 @@ declare module 'vscode' { * Check if this position is after `other`. * * @param other A position. - * @return `true` if position is on a greater line + * @returns `true` if position is on a greater line * or on the same line on a greater character. */ isAfter(other: Position): boolean; @@ -297,7 +297,7 @@ declare module 'vscode' { * Check if this position is after or equal to `other`. * * @param other A position. - * @return `true` if position is on a greater line + * @returns `true` if position is on a greater line * or on the same line on a greater or equal character. */ isAfterOrEqual(other: Position): boolean; @@ -306,7 +306,7 @@ declare module 'vscode' { * Check if this position is equal to `other`. * * @param other A position. - * @return `true` if the line and character of the given position are equal to + * @returns `true` if the line and character of the given position are equal to * the line and character of this position. */ isEqual(other: Position): boolean; @@ -315,7 +315,7 @@ declare module 'vscode' { * Compare this to `other`. * * @param other A position. - * @return A number smaller than zero if this position is before the given position, + * @returns A number smaller than zero if this position is before the given position, * a number greater than zero if this position is after the given position, or zero when * this and the given position are equal. */ @@ -326,7 +326,7 @@ declare module 'vscode' { * * @param lineDelta Delta value for the line value, default is `0`. * @param characterDelta Delta value for the character value, default is `0`. - * @return A position which line and character is the sum of the current line and + * @returns A position which line and character is the sum of the current line and * character and the corresponding deltas. */ translate(lineDelta?: number, characterDelta?: number): Position; @@ -335,17 +335,26 @@ declare module 'vscode' { * Derived a new position relative to this position. * * @param change An object that describes a delta to this position. - * @return A position that reflects the given delta. Will return `this` position if the change + * @returns A position that reflects the given delta. Will return `this` position if the change * is not changing anything. */ - translate(change: { lineDelta?: number; characterDelta?: number }): Position; + translate(change: { + /** + * Delta value for the line value, default is `0`. + */ + lineDelta?: number; + /** + * Delta value for the character value, default is `0`. + */ + characterDelta?: number; + }): Position; /** * Create a new position derived from this position. * * @param line Value that should be used as line value, default is the {@link Position.line existing value} * @param character Value that should be used as character value, default is the {@link Position.character existing value} - * @return A position where line and character are replaced by the given values. + * @returns A position where line and character are replaced by the given values. */ with(line?: number, character?: number): Position; @@ -353,10 +362,19 @@ declare module 'vscode' { * Derived a new position from this position. * * @param change An object that describes a change to this position. - * @return A position that reflects the given change. Will return `this` position if the change + * @returns A position that reflects the given change. Will return `this` position if the change * is not changing anything. */ - with(change: { line?: number; character?: number }): Position; + with(change: { + /** + * New line value, defaults the line value of `this`. + */ + line?: number; + /** + * New character value, defaults the character value of `this`. + */ + character?: number; + }): Position; } /** @@ -413,7 +431,7 @@ declare module 'vscode' { * Check if a position or a range is contained in this range. * * @param positionOrRange A position or a range. - * @return `true` if the position or range is inside or equal + * @returns `true` if the position or range is inside or equal * to this range. */ contains(positionOrRange: Position | Range): boolean; @@ -422,7 +440,7 @@ declare module 'vscode' { * Check if `other` equals this range. * * @param other A range. - * @return `true` when start and end are {@link Position.isEqual equal} to + * @returns `true` when start and end are {@link Position.isEqual equal} to * start and end of this range. */ isEqual(other: Range): boolean; @@ -432,7 +450,7 @@ declare module 'vscode' { * if the ranges have no overlap. * * @param range A range. - * @return A range of the greater start and smaller end positions. Will + * @returns A range of the greater start and smaller end positions. Will * return undefined when there is no overlap. */ intersection(range: Range): Range | undefined; @@ -441,7 +459,7 @@ declare module 'vscode' { * Compute the union of `other` with this range. * * @param other A range. - * @return A range of smaller start position and the greater end position. + * @returns A range of smaller start position and the greater end position. */ union(other: Range): Range; @@ -450,7 +468,7 @@ declare module 'vscode' { * * @param start A position that should be used as start. The default value is the {@link Range.start current start}. * @param end A position that should be used as end. The default value is the {@link Range.end current end}. - * @return A range derived from this range with the given start and end position. + * @returns A range derived from this range with the given start and end position. * If start and end are not different `this` range will be returned. */ with(start?: Position, end?: Position): Range; @@ -459,10 +477,19 @@ declare module 'vscode' { * Derived a new range from this range. * * @param change An object that describes a change to this range. - * @return A range that reflects the given change. Will return `this` range if the change + * @returns A range that reflects the given change. Will return `this` range if the change * is not changing anything. */ - with(change: { start?: Position; end?: Position }): Range; + with(change: { + /** + * New start position, defaults to {@link Range.start current start} + */ + start?: Position; + /** + * New end position, defaults to {@link Range.end current end} + */ + end?: Position; + }): Range; } /** @@ -718,9 +745,21 @@ declare module 'vscode' { * The overview ruler supports three lanes. */ export enum OverviewRulerLane { + /** + * The left lane of the overview ruler. + */ Left = 1, + /** + * The center lane of the overview ruler. + */ Center = 2, + /** + * The right lane of the overview ruler. + */ Right = 4, + /** + * All lanes of the overview ruler. + */ Full = 7 } @@ -1020,6 +1059,10 @@ declare module 'vscode' { after?: ThemableDecorationAttachmentRenderOptions; } + /** + * Represents theme specific rendeirng styles for {@link ThemableDecorationRenderOptions.before before} and + * {@link ThemableDecorationRenderOptions.after after} the content of text decorations. + */ export interface ThemableDecorationAttachmentRenderOptions { /** * Defines a text content that is shown in the attachment. Either an icon or a text can be shown, but not both. @@ -1126,6 +1169,9 @@ declare module 'vscode' { renderOptions?: DecorationInstanceRenderOptions; } + /** + * Represents themable render options for decoration instances. + */ export interface ThemableDecorationInstanceRenderOptions { /** * Defines the rendering options of the attachment that is inserted before the decorated text. @@ -1138,6 +1184,9 @@ declare module 'vscode' { after?: ThemableDecorationAttachmentRenderOptions; } + /** + * Represents render options for decoration instances. See {@link DecorationOptions.renderOptions}. + */ export interface DecorationInstanceRenderOptions extends ThemableDecorationInstanceRenderOptions { /** * Overwrite options for light themes. @@ -1197,9 +1246,18 @@ declare module 'vscode' { * * @param callback A function which can create edits using an {@link TextEditorEdit edit-builder}. * @param options The undo/redo behavior around this edit. By default, undo stops will be created before and after this edit. - * @return A promise that resolves with a value indicating if the edits could be applied. + * @returns A promise that resolves with a value indicating if the edits could be applied. */ - edit(callback: (editBuilder: TextEditorEdit) => void, options?: { readonly undoStopBefore: boolean; readonly undoStopAfter: boolean }): Thenable; + edit(callback: (editBuilder: TextEditorEdit) => void, options?: { + /** + * Add undo stop before making the edits. + */ + readonly undoStopBefore: boolean; + /** + * Add undo stop after making the edits. + */ + readonly undoStopAfter: boolean; + }): Thenable; /** * Insert a {@link SnippetString snippet} and put the editor into snippet mode. "Snippet mode" @@ -1209,10 +1267,19 @@ declare module 'vscode' { * @param snippet The snippet to insert in this edit. * @param location Position or range at which to insert the snippet, defaults to the current editor selection or selections. * @param options The undo/redo behavior around this edit. By default, undo stops will be created before and after this edit. - * @return A promise that resolves with a value indicating if the snippet could be inserted. Note that the promise does not signal + * @returns A promise that resolves with a value indicating if the snippet could be inserted. Note that the promise does not signal * that the snippet is completely filled-in or accepted. */ - insertSnippet(snippet: SnippetString, location?: Position | Range | readonly Position[] | readonly Range[], options?: { readonly undoStopBefore: boolean; readonly undoStopAfter: boolean }): Thenable; + insertSnippet(snippet: SnippetString, location?: Position | Range | readonly Position[] | readonly Range[], options?: { + /** + * Add undo stop before making the edits. + */ + readonly undoStopBefore: boolean; + /** + * Add undo stop after making the edits. + */ + readonly undoStopAfter: boolean; + }): Thenable; /** * Adds a set of decorations to the text editor. If a set of decorations already exists with @@ -1325,7 +1392,7 @@ declare module 'vscode' { * @see {@link Uri.toString} * @param value The string value of an Uri. * @param strict Throw an error when `value` is empty or when no `scheme` can be parsed. - * @return A new Uri instance. + * @returns A new Uri instance. */ static parse(value: string, strict?: boolean): Uri; @@ -1350,7 +1417,7 @@ declare module 'vscode' { * ``` * * @param path A file system or UNC path. - * @return A new Uri instance. + * @returns A new Uri instance. */ static file(path: string): Uri; @@ -1381,9 +1448,30 @@ declare module 'vscode' { * * @see {@link Uri.toString} * @param components The component parts of an Uri. - * @return A new Uri instance. + * @returns A new Uri instance. */ - static from(components: { readonly scheme: string; readonly authority?: string; readonly path?: string; readonly query?: string; readonly fragment?: string }): Uri; + static from(components: { + /** + * The scheme of the uri + */ + readonly scheme: string; + /** + * The authority of the uri + */ + readonly authority?: string; + /** + * The path of the uri + */ + readonly path?: string; + /** + * The query string of the uri + */ + readonly query?: string; + /** + * The fragment identifier of the uri + */ + readonly fragment?: string; + }): Uri; /** * Use the `file` and `parse` factory functions to create new `Uri` objects. @@ -1450,10 +1538,31 @@ declare module 'vscode' { * * @param change An object that describes a change to this Uri. To unset components use `null` or * the empty string. - * @return A new Uri that reflects the given change. Will return `this` Uri if the change + * @returns A new Uri that reflects the given change. Will return `this` Uri if the change * is not changing anything. */ - with(change: { scheme?: string; authority?: string; path?: string; query?: string; fragment?: string }): Uri; + with(change: { + /** + * The new scheme, defauls to this Uri's scheme. + */ + scheme?: string; + /** + * The new authority, defaults to this Uri's authority. + */ + authority?: string; + /** + * The new path, defaults to this Uri's path. + */ + path?: string; + /** + * The new query, defaults to this Uri's query. + */ + query?: string; + /** + * The new fragment, defaults to this Uri's fragment. + */ + fragment?: string; + }): Uri; /** * Returns a string representation of this Uri. The representation and normalization @@ -1477,7 +1586,7 @@ declare module 'vscode' { /** * Returns a JSON representation of this Uri. * - * @return An object. + * @returns An object. */ toJSON(): any; } @@ -1551,10 +1660,15 @@ declare module 'vscode' { * * @param disposableLikes Objects that have at least a `dispose`-function member. Note that asynchronous * dispose-functions aren't awaited. - * @return Returns a new disposable which, upon dispose, will + * @returns Returns a new disposable which, upon dispose, will * dispose all provided disposables. */ - static from(...disposableLikes: { dispose: () => any }[]): Disposable; + static from(...disposableLikes: { + /** + * Function to clean up resources. + */ + dispose: () => any; + }[]): Disposable; /** * Creates a new disposable that calls the provided function @@ -1590,7 +1704,7 @@ declare module 'vscode' { * @param listener The listener function will be called when the event happens. * @param thisArgs The `this`-argument which will be used when calling the event listener. * @param disposables An array to which a {@link Disposable} will be added. - * @return A disposable which unsubscribes the event listener. + * @returns A disposable which unsubscribes the event listener. */ (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable; } @@ -1695,7 +1809,7 @@ declare module 'vscode' { * * @param uri An uri which scheme matches the scheme this provider was {@link workspace.registerTextDocumentContentProvider registered} for. * @param token A cancellation token. - * @return A string or a thenable that resolves to such. + * @returns A string or a thenable that resolves to such. */ provideTextDocumentContent(uri: Uri, token: CancellationToken): ProviderResult; } @@ -1736,7 +1850,16 @@ declare module 'vscode' { /** * The icon path or {@link ThemeIcon} for the QuickPickItem. */ - iconPath?: Uri | { light: Uri; dark: Uri } | ThemeIcon; + iconPath?: Uri | { + /** + * The icon path for the light theme. + */ + light: Uri; + /** + * The icon path for the dark theme. + */ + dark: Uri; + } | ThemeIcon; /** * A human-readable string which is rendered less prominent in the same line. Supports rendering of @@ -1983,9 +2106,21 @@ declare module 'vscode' { /** * Impacts the behavior and appearance of the validation message. */ + /** + * The severity level for input box validation. + */ export enum InputBoxValidationSeverity { + /** + * Informational severity level. + */ Info = 1, + /** + * Warning severity level. + */ Warning = 2, + /** + * Error severity level. + */ Error = 3 } @@ -2055,7 +2190,7 @@ declare module 'vscode' { * to the user. * * @param value The current value of the input box. - * @return Either a human-readable string which is presented as an error message or an {@link InputBoxValidationMessage} + * @returns Either a human-readable string which is presented as an error message or an {@link InputBoxValidationMessage} * which can provide a specific message severity. Return `undefined`, `null`, or the empty string when 'value' is valid. */ validateInput?(value: string): string | InputBoxValidationMessage | undefined | null | @@ -2330,6 +2465,11 @@ declare module 'vscode' { */ static readonly SourceFixAll: CodeActionKind; + /** + * Private constructor, use statix `CodeActionKind.XYZ` to derive from an existing code action kind. + * + * @param value The value of the kind, such as `refactor.extract.function`. + */ private constructor(value: string); /** @@ -2516,7 +2656,7 @@ declare module 'vscode' { * actions and avoid returning irrelevant code actions that the editor will discard. * @param token A cancellation token. * - * @return An array of code actions, such as quick fixes or refactorings. The lack of a result can be signaled + * @returns An array of code actions, such as quick fixes or refactorings. The lack of a result can be signaled * by returning `undefined`, `null`, or an empty array. * * We also support returning `Command` for legacy reasons, however all new extensions should return @@ -2535,7 +2675,7 @@ declare module 'vscode' { * * @param codeAction A code action. * @param token A cancellation token. - * @return The resolved code action or a thenable that resolves to such. It is OK to return the given + * @returns The resolved code action or a thenable that resolves to such. It is OK to return the given * `item`. When no result is returned, the given `item` will be used. */ resolveCodeAction?(codeAction: T, token: CancellationToken): ProviderResult; @@ -2644,7 +2784,7 @@ declare module 'vscode' { * * @param document The document in which the command was invoked. * @param token A cancellation token. - * @return An array of code lenses or a thenable that resolves to such. The lack of a result can be + * @returns An array of code lenses or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideCodeLenses(document: TextDocument, token: CancellationToken): ProviderResult; @@ -2655,7 +2795,7 @@ declare module 'vscode' { * * @param codeLens Code lens that must be resolved. * @param token A cancellation token. - * @return The given, resolved code lens or thenable that resolves to such. + * @returns The given, resolved code lens or thenable that resolves to such. */ resolveCodeLens?(codeLens: T, token: CancellationToken): ProviderResult; } @@ -2688,7 +2828,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param position The position at which the command was invoked. * @param token A cancellation token. - * @return A definition or a thenable that resolves to such. The lack of a result can be + * @returns A definition or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; @@ -2706,7 +2846,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param position The position at which the command was invoked. * @param token A cancellation token. - * @return A definition or a thenable that resolves to such. The lack of a result can be + * @returns A definition or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideImplementation(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; @@ -2724,7 +2864,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param position The position at which the command was invoked. * @param token A cancellation token. - * @return A definition or a thenable that resolves to such. The lack of a result can be + * @returns A definition or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideTypeDefinition(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; @@ -2748,7 +2888,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param position The position at which the command was invoked. * @param token A cancellation token. - * @return A declaration or a thenable that resolves to such. The lack of a result can be + * @returns A declaration or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideDeclaration(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; @@ -2774,10 +2914,13 @@ declare module 'vscode' { * markdown supports links that execute commands, e.g. `[Run it](command:myCommandId)`. * * Defaults to `false` (commands are disabled). - * - * If this is an object, only the set of commands listed in `enabledCommands` are allowed. */ - isTrusted?: boolean | { readonly enabledCommands: readonly string[] }; + isTrusted?: boolean | { + /** + * A set of commend ids that are allowed to be executed by this markdown string. + */ + readonly enabledCommands: readonly string[]; + }; /** * Indicates that this markdown string can contain {@link ThemeIcon ThemeIcons}, e.g. `$(zap)`. @@ -2852,7 +2995,18 @@ declare module 'vscode' { * * @deprecated This type is deprecated, please use {@linkcode MarkdownString} instead. */ - export type MarkedString = string | { language: string; value: string }; + export type MarkedString = string | { + /** + * The language of a markdown code block + * @deprecated, please use {@linkcode MarkdownString} instead + */ + language: string; + /** + * The code snippet of a markdown code block. + * @deprecated, please use {@linkcode MarkdownString} instead + */ + value: string; + }; /** * A hover represents additional information for a symbol or word. Hovers are @@ -2895,7 +3049,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param position The position at which the command was invoked. * @param token A cancellation token. - * @return A hover or a thenable that resolves to such. The lack of a result can be + * @returns A hover or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideHover(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; @@ -2944,7 +3098,7 @@ declare module 'vscode' { * @param document The document for which the debug hover is about to appear. * @param position The line and character position in the document where the debug hover is about to appear. * @param token A cancellation token. - * @return An EvaluatableExpression or a thenable that resolves to such. The lack of a result can be + * @returns An EvaluatableExpression or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideEvaluatableExpression(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; @@ -3072,7 +3226,7 @@ declare module 'vscode' { * @param viewPort The visible document range for which inline values should be computed. * @param context A bag containing contextual information like the current location. * @param token A cancellation token. - * @return An array of InlineValueDescriptors or a thenable that resolves to such. The lack of a result can be + * @returns An array of InlineValueDescriptors or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideInlineValues(document: TextDocument, viewPort: Range, context: InlineValueContext, token: CancellationToken): ProviderResult; @@ -3138,7 +3292,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param position The position at which the command was invoked. * @param token A cancellation token. - * @return An array of document highlights or a thenable that resolves to such. The lack of a result can be + * @returns An array of document highlights or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideDocumentHighlights(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; @@ -3148,31 +3302,109 @@ declare module 'vscode' { * A symbol kind. */ export enum SymbolKind { + /** + * The `File` symbol kind. + */ File = 0, + /** + * The `Module` symbol kind. + */ Module = 1, + /** + * The `Namespace` symbol kind. + */ Namespace = 2, + /** + * The `Package` symbol kind. + */ Package = 3, + /** + * The `Class` symbol kind. + */ Class = 4, + /** + * The `Method` symbol kind. + */ Method = 5, + /** + * The `Property` symbol kind. + */ Property = 6, + /** + * The `Field` symbol kind. + */ Field = 7, + /** + * The `Constructor` symbol kind. + */ Constructor = 8, + /** + * The `Enum` symbol kind. + */ Enum = 9, + /** + * The `Interface` symbol kind. + */ Interface = 10, + /** + * The `Function` symbol kind. + */ Function = 11, + /** + * The `Variable` symbol kind. + */ Variable = 12, + /** + * The `Constant` symbol kind. + */ Constant = 13, + /** + * The `String` symbol kind. + */ String = 14, + /** + * The `Number` symbol kind. + */ Number = 15, + /** + * The `Boolean` symbol kind. + */ Boolean = 16, + /** + * The `Array` symbol kind. + */ Array = 17, + /** + * The `Object` symbol kind. + */ Object = 18, + /** + * The `Key` symbol kind. + */ Key = 19, + /** + * The `Null` symbol kind. + */ Null = 20, + /** + * The `EnumMember` symbol kind. + */ EnumMember = 21, + /** + * The `Struct` symbol kind. + */ Struct = 22, + /** + * The `Event` symbol kind. + */ Event = 23, + /** + * The `Operator` symbol kind. + */ Operator = 24, + /** + * The `TypeParameter` symbol kind. + */ TypeParameter = 25 } @@ -3308,7 +3540,7 @@ declare module 'vscode' { * * @param document The document in which the command was invoked. * @param token A cancellation token. - * @return An array of document highlights or a thenable that resolves to such. The lack of a result can be + * @returns An array of document highlights or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideDocumentSymbols(document: TextDocument, token: CancellationToken): ProviderResult; @@ -3344,7 +3576,7 @@ declare module 'vscode' { * * @param query A query string, can be the empty string in which case all symbols should be returned. * @param token A cancellation token. - * @return An array of document highlights or a thenable that resolves to such. The lack of a result can be + * @returns An array of document highlights or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideWorkspaceSymbols(query: string, token: CancellationToken): ProviderResult; @@ -3358,7 +3590,7 @@ declare module 'vscode' { * @param symbol The symbol that is to be resolved. Guaranteed to be an instance of an object returned from an * earlier call to `provideWorkspaceSymbols`. * @param token A cancellation token. - * @return The resolved symbol or a thenable that resolves to that. When no result is returned, + * @returns The resolved symbol or a thenable that resolves to that. When no result is returned, * the given `symbol` is used. */ resolveWorkspaceSymbol?(symbol: T, token: CancellationToken): ProviderResult; @@ -3389,7 +3621,7 @@ declare module 'vscode' { * @param position The position at which the command was invoked. * @param token A cancellation token. * - * @return An array of locations or a thenable that resolves to such. The lack of a result can be + * @returns An array of locations or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideReferences(document: TextDocument, position: Position, context: ReferenceContext, token: CancellationToken): ProviderResult; @@ -3406,7 +3638,7 @@ declare module 'vscode' { * * @param range A range. * @param newText A string. - * @return A new text edit object. + * @returns A new text edit object. */ static replace(range: Range, newText: string): TextEdit; @@ -3415,7 +3647,7 @@ declare module 'vscode' { * * @param position A position, will become an empty range. * @param newText A string. - * @return A new text edit object. + * @returns A new text edit object. */ static insert(position: Position, newText: string): TextEdit; @@ -3423,7 +3655,7 @@ declare module 'vscode' { * Utility to create a delete edit. * * @param range A range. - * @return A new text edit object. + * @returns A new text edit object. */ static delete(range: Range): TextEdit; @@ -3431,7 +3663,7 @@ declare module 'vscode' { * Utility to create an eol-edit. * * @param eol An eol-sequence - * @return A new text edit object. + * @returns A new text edit object. */ static setEndOfLine(eol: EndOfLine): TextEdit; @@ -3478,7 +3710,7 @@ declare module 'vscode' { * * @param range A range. * @param snippet A snippet string. - * @return A new snippet edit object. + * @returns A new snippet edit object. */ static replace(range: Range, snippet: SnippetString): SnippetTextEdit; @@ -3487,7 +3719,7 @@ declare module 'vscode' { * * @param position A position, will become an empty range. * @param snippet A snippet string. - * @return A new snippet edit object. + * @returns A new snippet edit object. */ static insert(position: Position, snippet: SnippetString): SnippetTextEdit; @@ -3573,6 +3805,12 @@ declare module 'vscode' { */ newNotebookMetadata?: { [key: string]: any }; + /** + * Create a new notebook edit. + * + * @param range A notebook range. + * @param newCells An array of new cell data. + */ constructor(range: NotebookRange, newCells: NotebookCellData[]); } @@ -3601,7 +3839,16 @@ declare module 'vscode' { /** * The icon path or {@link ThemeIcon} for the edit. */ - iconPath?: Uri | { light: Uri; dark: Uri } | ThemeIcon; + iconPath?: Uri | { + /** + * The icon path for the light theme. + */ + light: Uri; + /** + * The icon path for the dark theme. + */ + dark: Uri; + } | ThemeIcon; } /** @@ -3660,7 +3907,7 @@ declare module 'vscode' { * Check if a text edit for a resource exists. * * @param uri A resource identifier. - * @return `true` if the given resource will be touched by this edit. + * @returns `true` if the given resource will be touched by this edit. */ has(uri: Uri): boolean; @@ -3700,7 +3947,7 @@ declare module 'vscode' { * Get the text edits for a resource. * * @param uri A resource identifier. - * @return An array of text edits. + * @returns An array of text edits. */ get(uri: Uri): TextEdit[]; @@ -3716,9 +3963,14 @@ declare module 'vscode' { * @param metadata Optional metadata for the entry. */ createFile(uri: Uri, options?: { + /** + * Overwrite existing file. Overwrite wins over `ignoreIfExists` + */ readonly overwrite?: boolean; + /** + * Do nothing if a file with `uri` exists already. + */ readonly ignoreIfExists?: boolean; - /** * The initial contents of the new file. * @@ -3734,7 +3986,16 @@ declare module 'vscode' { * @param uri The uri of the file that is to be deleted. * @param metadata Optional metadata for the entry. */ - deleteFile(uri: Uri, options?: { readonly recursive?: boolean; readonly ignoreIfNotExists?: boolean }, metadata?: WorkspaceEditEntryMetadata): void; + deleteFile(uri: Uri, options?: { + /** + * Delete the content recursively if a folder is denoted. + */ + readonly recursive?: boolean; + /** + * Do nothing if a file with `uri` exists already. + */ + readonly ignoreIfNotExists?: boolean; + }, metadata?: WorkspaceEditEntryMetadata): void; /** * Rename a file or folder. @@ -3745,12 +4006,21 @@ declare module 'vscode' { * ignored. When overwrite and ignoreIfExists are both set overwrite wins. * @param metadata Optional metadata for the entry. */ - renameFile(oldUri: Uri, newUri: Uri, options?: { readonly overwrite?: boolean; readonly ignoreIfExists?: boolean }, metadata?: WorkspaceEditEntryMetadata): void; + renameFile(oldUri: Uri, newUri: Uri, options?: { + /** + * Overwrite existing file. Overwrite wins over `ignoreIfExists` + */ + readonly overwrite?: boolean; + /** + * Do nothing if a file with `uri` exists already. + */ + readonly ignoreIfExists?: boolean; + }, metadata?: WorkspaceEditEntryMetadata): void; /** * Get all text edits grouped by resource. * - * @return A shallow copy of `[Uri, TextEdit[]]`-tuples. + * @returns A shallow copy of `[Uri, TextEdit[]]`-tuples. */ entries(): [Uri, TextEdit[]][]; } @@ -3772,6 +4042,11 @@ declare module 'vscode' { */ value: string; + /** + * Create a new snippet string. + * + * @param value A snippet string. + */ constructor(value?: string); /** @@ -3779,7 +4054,7 @@ declare module 'vscode' { * the {@linkcode SnippetString.value value} of this snippet string. * * @param string A value to append 'as given'. The string will be escaped. - * @return This snippet string. + * @returns This snippet string. */ appendText(string: string): SnippetString; @@ -3789,7 +4064,7 @@ declare module 'vscode' { * * @param number The number of this tabstop, defaults to an auto-increment * value starting at 1. - * @return This snippet string. + * @returns This snippet string. */ appendTabstop(number?: number): SnippetString; @@ -3801,7 +4076,7 @@ declare module 'vscode' { * with which a nested snippet can be created. * @param number The number of this tabstop, defaults to an auto-increment * value starting at 1. - * @return This snippet string. + * @returns This snippet string. */ appendPlaceholder(value: string | ((snippet: SnippetString) => any), number?: number): SnippetString; @@ -3812,7 +4087,7 @@ declare module 'vscode' { * @param values The values for choices - the array of strings * @param number The number of this tabstop, defaults to an auto-increment * value starting at 1. - * @return This snippet string. + * @returns This snippet string. */ appendChoice(values: readonly string[], number?: number): SnippetString; @@ -3823,7 +4098,7 @@ declare module 'vscode' { * @param name The name of the variable - excluding the `$`. * @param defaultValue The default value which is used when the variable name cannot * be resolved - either a string or a function with which a nested snippet can be created. - * @return This snippet string. + * @returns This snippet string. */ appendVariable(name: string, defaultValue: string | ((snippet: SnippetString) => any)): SnippetString; } @@ -3842,7 +4117,7 @@ declare module 'vscode' { * @param position The position at which the command was invoked. * @param newName The new name of the symbol. If the given name is not valid, the provider must return a rejected promise. * @param token A cancellation token. - * @return A workspace edit or a thenable that resolves to such. The lack of a result can be + * @returns A workspace edit or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): ProviderResult; @@ -3858,9 +4133,18 @@ declare module 'vscode' { * @param document The document in which rename will be invoked. * @param position The position at which rename will be invoked. * @param token A cancellation token. - * @return The range or range and placeholder text of the identifier that is to be renamed. The lack of a result can signaled by returning `undefined` or `null`. + * @returns The range or range and placeholder text of the identifier that is to be renamed. The lack of a result can signaled by returning `undefined` or `null`. */ - prepareRename?(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; + prepareRename?(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; } /** @@ -3877,6 +4161,12 @@ declare module 'vscode' { */ readonly tokenModifiers: string[]; + /** + * Creates a semantic tokens legend. + * + * @param tokenTypes An array of token types. + * @param tokenModifiers An array of token modifiers. + */ constructor(tokenTypes: string[], tokenModifiers?: string[]); } @@ -3886,6 +4176,11 @@ declare module 'vscode' { */ export class SemanticTokensBuilder { + /** + * Creates a semantic tokens builder. + * + * @param legend A semantic tokens legent. + */ constructor(legend?: SemanticTokensLegend); /** @@ -3932,6 +4227,12 @@ declare module 'vscode' { */ readonly data: Uint32Array; + /** + * Create new semantic tokens. + * + * @param data Token data. + * @param resultId Result identifier. + */ constructor(data: Uint32Array, resultId?: string); } @@ -3952,6 +4253,12 @@ declare module 'vscode' { */ readonly edits: SemanticTokensEdit[]; + /** + * Create new semantic tokens edits. + * + * @param edits An array of semantic token edits + * @param resultId Result identifier. + */ constructor(edits: SemanticTokensEdit[], resultId?: string); } @@ -3973,6 +4280,13 @@ declare module 'vscode' { */ readonly data: Uint32Array | undefined; + /** + * Create a semantic token edit. + * + * @param start Start offset + * @param deleteCount Number of elements to remove. + * @param data Elements to insert + */ constructor(start: number, deleteCount: number, data?: Uint32Array); } @@ -4123,7 +4437,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param options Options controlling formatting. * @param token A cancellation token. - * @return A set of text edits or a thenable that resolves to such. The lack of a result can be + * @returns A set of text edits or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideDocumentFormattingEdits(document: TextDocument, options: FormattingOptions, token: CancellationToken): ProviderResult; @@ -4146,7 +4460,7 @@ declare module 'vscode' { * @param range The range which should be formatted. * @param options Options controlling formatting. * @param token A cancellation token. - * @return A set of text edits or a thenable that resolves to such. The lack of a result can be + * @returns A set of text edits or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult; @@ -4166,7 +4480,7 @@ declare module 'vscode' { * @param ranges The ranges which should be formatted. * @param options Options controlling formatting. * @param token A cancellation token. - * @return A set of text edits or a thenable that resolves to such. The lack of a result can be + * @returns A set of text edits or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideDocumentRangesFormattingEdits?(document: TextDocument, ranges: Range[], options: FormattingOptions, token: CancellationToken): ProviderResult; @@ -4190,7 +4504,7 @@ declare module 'vscode' { * @param ch The character that has been typed. * @param options Options controlling formatting. * @param token A cancellation token. - * @return A set of text edits or a thenable that resolves to such. The lack of a result can be + * @returns A set of text edits or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined`, `null`, or an empty array. */ provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): ProviderResult; @@ -4358,7 +4672,7 @@ declare module 'vscode' { * @param token A cancellation token. * @param context Information about how signature help was triggered. * - * @return Signature help or a thenable that resolves to such. The lack of a result can be + * @returns Signature help or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken, context: SignatureHelpContext): ProviderResult; @@ -4411,32 +4725,113 @@ declare module 'vscode' { * Completion item kinds. */ export enum CompletionItemKind { + /** + * The `Text` completion item kind. + */ Text = 0, + /** + * The `Method` completion item kind. + */ Method = 1, + /** + * The `Function` completion item kind. + */ Function = 2, + /** + * The `Constructor` completion item kind. + */ Constructor = 3, + /** + * The `Field` completion item kind. + */ Field = 4, + /** + * The `Variable` completion item kind. + */ Variable = 5, + /** + * The `Class` completion item kind. + */ Class = 6, + /** + * The `Interface` completion item kind. + */ Interface = 7, + /** + * The `Module` completion item kind. + */ Module = 8, + /** + * The `Property` completion item kind. + */ Property = 9, + /** + * The `Unit` completion item kind. + */ Unit = 10, + /** + * The `Value` completion item kind. + */ Value = 11, + /** + * The `Enum` completion item kind. + */ Enum = 12, + /** + * The `Keyword` completion item kind. + */ Keyword = 13, + /** + * The `Snippet` completion item kind. + */ Snippet = 14, + /** + * The `Color` completion item kind. + */ Color = 15, + /** + * The `Reference` completion item kind. + */ Reference = 17, + /** + * The `File` completion item kind. + */ File = 16, + /** + * The `Folder` completion item kind. + */ Folder = 18, + /** + * The `EnumMember` completion item kind. + */ EnumMember = 19, + /** + * The `Constant` completion item kind. + */ Constant = 20, + /** + * The `Struct` completion item kind. + */ Struct = 21, + /** + * The `Event` completion item kind. + */ Event = 22, + /** + * The `Operator` completion item kind. + */ Operator = 23, + /** + * The `TypeParameter` completion item kind. + */ TypeParameter = 24, + /** + * The `User` completion item kind. + */ User = 25, + /** + * The `Issue` completion item kind. + */ Issue = 26, } @@ -4546,7 +4941,16 @@ declare module 'vscode' { * {@link Range.contains contain} the position at which completion has been {@link CompletionItemProvider.provideCompletionItems requested}. * *Note 2:* A insert range must be a prefix of a replace range, that means it must be contained and starting at the same position. */ - range?: Range | { inserting: Range; replacing: Range }; + range?: Range | { + /** + * The range that should be used when insert-accepting a completion. Must be a prefix of `replaceRange`. + */ + inserting: Range; + /** + * The range that should be used when replace-accepting a completion. + */ + replacing: Range; + }; /** * An optional set of characters that when pressed while this completion is active will accept it first and @@ -4687,7 +5091,7 @@ declare module 'vscode' { * @param token A cancellation token. * @param context How the completion was triggered. * - * @return An array of completions, a {@link CompletionList completion list}, or a thenable that resolves to either. + * @returns An array of completions, a {@link CompletionList completion list}, or a thenable that resolves to either. * The lack of a result can be signaled by returning `undefined`, `null`, or an empty array. */ provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext): ProviderResult>; @@ -4708,7 +5112,7 @@ declare module 'vscode' { * * @param item A completion item currently active in the UI. * @param token A cancellation token. - * @return The resolved completion item or a thenable that resolves to of such. It is OK to return the given + * @returns The resolved completion item or a thenable that resolves to of such. It is OK to return the given * `item`. When no result is returned, the given `item` will be used. */ resolveCompletionItem?(item: T, token: CancellationToken): ProviderResult; @@ -4734,7 +5138,7 @@ declare module 'vscode' { * @param position The position inline completions are requested for. * @param context A context object with additional information. * @param token A cancellation token. - * @return An array of completion items or a thenable that resolves to an array of completion items. + * @returns An array of completion items or a thenable that resolves to an array of completion items. */ provideInlineCompletionItems(document: TextDocument, position: Position, context: InlineCompletionContext, token: CancellationToken): ProviderResult; } @@ -4898,7 +5302,7 @@ declare module 'vscode' { * * @param document The document in which the command was invoked. * @param token A cancellation token. - * @return An array of {@link DocumentLink document links} or a thenable that resolves to such. The lack of a result + * @returns An array of {@link DocumentLink document links} or a thenable that resolves to such. The lack of a result * can be signaled by returning `undefined`, `null`, or an empty array. */ provideDocumentLinks(document: TextDocument, token: CancellationToken): ProviderResult; @@ -5024,7 +5428,7 @@ declare module 'vscode' { * * @param document The document in which the command was invoked. * @param token A cancellation token. - * @return An array of {@link ColorInformation color information} or a thenable that resolves to such. The lack of a result + * @returns An array of {@link ColorInformation color information} or a thenable that resolves to such. The lack of a result * can be signaled by returning `undefined`, `null`, or an empty array. */ provideDocumentColors(document: TextDocument, token: CancellationToken): ProviderResult; @@ -5035,10 +5439,19 @@ declare module 'vscode' { * @param color The color to show and insert. * @param context A context object with additional information * @param token A cancellation token. - * @return An array of color presentations or a thenable that resolves to such. The lack of a result + * @returns An array of color presentations or a thenable that resolves to such. The lack of a result * can be signaled by returning `undefined`, `null`, or an empty array. */ - provideColorPresentations(color: Color, context: { readonly document: TextDocument; readonly range: Range }, token: CancellationToken): ProviderResult; + provideColorPresentations(color: Color, context: { + /** + * The text document that contains the color + */ + readonly document: TextDocument; + /** + * The range in the document where the color is located. + */ + readonly range: Range; + }, token: CancellationToken): ProviderResult; } /** @@ -5194,7 +5607,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param range The range for which inlay hints should be computed. * @param token A cancellation token. - * @return An array of inlay hints or a thenable that resolves to such. + * @returns An array of inlay hints or a thenable that resolves to such. */ provideInlayHints(document: TextDocument, range: Range, token: CancellationToken): ProviderResult; @@ -5206,7 +5619,7 @@ declare module 'vscode' { * * @param hint An inlay hint. * @param token A cancellation token. - * @return The resolved inlay hint or a thenable that resolves to such. It is OK to return the given `item`. When no result is returned, the given `item` will be used. + * @returns The resolved inlay hint or a thenable that resolves to such. It is OK to return the given `item`. When no result is returned, the given `item` will be used. */ resolveInlayHint?(hint: T, token: CancellationToken): ProviderResult; } @@ -5321,6 +5734,9 @@ declare module 'vscode' { constructor(range: Range, parent?: SelectionRange); } + /** + * The selection range provider interface defines the contract between extensions and the "Expand and Shrink Selection" feature. + */ export interface SelectionRangeProvider { /** * Provide selection ranges for the given positions. @@ -5332,7 +5748,7 @@ declare module 'vscode' { * @param document The document in which the command was invoked. * @param positions The positions at which the command was invoked. * @param token A cancellation token. - * @return Selection ranges or a thenable that resolves to such. The lack of a result can be + * @returns Selection ranges or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideSelectionRanges(document: TextDocument, positions: readonly Position[], token: CancellationToken): ProviderResult; @@ -5618,7 +6034,7 @@ declare module 'vscode' { * @param document The document in which the provider was invoked. * @param position The position at which the provider was invoked. * @param token A cancellation token. - * @return A list of ranges that can be edited together + * @returns A list of ranges that can be edited together */ provideLinkedEditingRanges(document: TextDocument, position: Position, token: CancellationToken): ProviderResult; } @@ -5659,7 +6075,7 @@ declare module 'vscode' { * @param dataTransfer A {@link DataTransfer} object that holds data about what is being dragged and dropped. * @param token A cancellation token. * - * @return A {@link DocumentDropEdit} or a thenable that resolves to such. The lack of a result can be + * @returns A {@link DocumentDropEdit} or a thenable that resolves to such. The lack of a result can be * signaled by returning `undefined` or `null`. */ provideDocumentDropEdits(document: TextDocument, position: Position, dataTransfer: DataTransfer, token: CancellationToken): ProviderResult; @@ -5823,9 +6239,21 @@ declare module 'vscode' { * @deprecated */ docComment?: { + /** + * @deprecated + */ scope: string; + /** + * @deprecated + */ open: string; + /** + * @deprecated + */ lineStart: string; + /** + * @deprecated + */ close?: string; }; }; @@ -5836,9 +6264,21 @@ declare module 'vscode' { * @deprecated * Use the autoClosingPairs property in the language configuration file instead. */ __characterPairSupport?: { + /** + * @deprecated + */ autoClosingPairs: { + /** + * @deprecated + */ open: string; + /** + * @deprecated + */ close: string; + /** + * @deprecated + */ notIn?: string[]; }[]; }; @@ -5933,7 +6373,7 @@ declare module 'vscode' { * Return a value from this configuration. * * @param section Configuration name, supports _dotted_ names. - * @return The value `section` denotes or `undefined`. + * @returns The value `section` denotes or `undefined`. */ get(section: string): T | undefined; @@ -5942,7 +6382,7 @@ declare module 'vscode' { * * @param section Configuration name, supports _dotted_ names. * @param defaultValue A value should be returned when no value could be found, is `undefined`. - * @return The value `section` denotes or the default. + * @returns The value `section` denotes or the default. */ get(section: string, defaultValue: T): T; @@ -5950,7 +6390,7 @@ declare module 'vscode' { * Check if this configuration has a certain value. * * @param section Configuration name, supports _dotted_ names. - * @return `true` if the section doesn't resolve to `undefined`. + * @returns `true` if the section doesn't resolve to `undefined`. */ has(section: string): boolean; @@ -5966,21 +6406,58 @@ declare module 'vscode' { * (`editor.fontSize` vs `editor`) otherwise no result is returned. * * @param section Configuration name, supports _dotted_ names. - * @return Information about a configuration setting or `undefined`. + * @returns Information about a configuration setting or `undefined`. */ inspect(section: string): { + + /** + * The fully qualified key of the configuration value + */ key: string; + /** + * The default value which is used when no other value is defined + */ defaultValue?: T; + + /** + * The global or installation-wide value. + */ globalValue?: T; + + /** + * The workspace-specific value. + */ workspaceValue?: T; + + /** + * The workpace-folder-specific value. + */ workspaceFolderValue?: T; + /** + * Language specific default value when this configuration value is created for a {@link ConfigurationScope language scope}. + */ defaultLanguageValue?: T; + + /** + * Language specific global value when this configuration value is created for a {@link ConfigurationScope language scope}. + */ globalLanguageValue?: T; + + /** + * Language specific workspace value when this configuration value is created for a {@link ConfigurationScope language scope}. + */ workspaceLanguageValue?: T; + + /** + * Language specific workspace-folder value when this configuration value is created for a {@link ConfigurationScope language scope}. + */ workspaceFolderLanguageValue?: T; + /** + * All language identifiers for which this configuration is defined. + */ languageIds?: string[]; } | undefined; @@ -6317,9 +6794,21 @@ declare module 'vscode' { /** * Represents the severity of a language status item. */ + /** + * Represents the severity level of a language status. + */ export enum LanguageStatusSeverity { + /** + * Informational severity level. + */ Information = 0, + /** + * Warning severity level. + */ Warning = 1, + /** + * Error severity level. + */ Error = 2 } @@ -6884,7 +7373,7 @@ declare module 'vscode' { * that could have problems when asynchronous usage may overlap. * @param context Information about what links are being provided for. * @param token A cancellation token. - * @return A list of terminal links for the given line. + * @returns A list of terminal links for the given line. */ provideTerminalLinks(context: TerminalLinkContext, token: CancellationToken): ProviderResult; @@ -7094,7 +7583,7 @@ declare module 'vscode' { /** * Activates this extension and returns its public API. * - * @return A promise that will resolve when this extension has been activated. + * @returns A promise that will resolve when this extension has been activated. */ activate(): Thenable; } @@ -7138,7 +7627,12 @@ declare module 'vscode' { * * *Note* that asynchronous dispose-functions aren't awaited. */ - readonly subscriptions: { dispose(): any }[]; + readonly subscriptions: { + /** + * Function to clean up resources. + */ + dispose(): any; + }[]; /** * A memento object that stores state in the context @@ -7197,7 +7691,7 @@ declare module 'vscode' { * {@linkcode ExtensionContext.extensionUri extensionUri}, e.g. `vscode.Uri.joinPath(context.extensionUri, relativePath);` * * @param relativePath A relative path to a resource contained in the extension. - * @return The absolute path of the resource. + * @returns The absolute path of the resource. */ asAbsolutePath(relativePath: string): string; @@ -7291,7 +7785,7 @@ declare module 'vscode' { /** * Returns the stored keys. * - * @return The stored keys. + * @returns The stored keys. */ keys(): readonly string[]; @@ -7299,7 +7793,7 @@ declare module 'vscode' { * Return a value. * * @param key A string. - * @return The stored value or `undefined`. + * @returns The stored value or `undefined`. */ get(key: string): T | undefined; @@ -7309,7 +7803,7 @@ declare module 'vscode' { * @param key A string. * @param defaultValue A value that should be returned when there is no * value (`undefined`) with the given key. - * @return The stored value or the defaultValue. + * @returns The stored value or the defaultValue. */ get(key: string, defaultValue: T): T; @@ -7371,9 +7865,21 @@ declare module 'vscode' { * Represents a color theme kind. */ export enum ColorThemeKind { + /** + * A light color theme. + */ Light = 1, + /** + * A dark color theme. + */ Dark = 2, + /** + * A dark high contrast color theme. + */ HighContrast = 3, + /** + * A light high contrast color theme. + */ HighContrastLight = 4 } @@ -7512,6 +8018,12 @@ declare module 'vscode' { */ readonly id: string; + /** + * Private constructor + * + * @param id Identifier of a task group. + * @param label The human-readable name of a task group. + */ private constructor(id: string, label: string); } @@ -7715,6 +8227,9 @@ declare module 'vscode' { quoting: ShellQuoting; } + /** + * Represents a task execution that happens inside a shell. + */ export class ShellExecution { /** * Creates a shell execution with a full command line. @@ -7904,7 +8419,7 @@ declare module 'vscode' { /** * Provides tasks. * @param token A cancellation token. - * @return an array of tasks + * @returns an array of tasks */ provideTasks(token: CancellationToken): ProviderResult; @@ -7923,7 +8438,7 @@ declare module 'vscode' { * * @param task The task to resolve. * @param token A cancellation token. - * @return The resolved task + * @returns The resolved task */ resolveTask(task: T, token: CancellationToken): ProviderResult; } @@ -8004,6 +8519,9 @@ declare module 'vscode' { readonly exitCode: number | undefined; } + /** + * A task filter denotes tasks by their version and types + */ export interface TaskFilter { /** * The task version as used in the tasks.json file. @@ -8027,7 +8545,7 @@ declare module 'vscode' { * * @param type The task kind type this provider is registered for. * @param provider A task provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerTaskProvider(type: string, provider: TaskProvider): Disposable; @@ -8037,6 +8555,7 @@ declare module 'vscode' { * contributed through extensions. * * @param filter Optional filter to select tasks of a certain type or version. + * @returns A thenable that resolves to an array of tasks. */ export function fetchTasks(filter?: TaskFilter): Thenable; @@ -8049,6 +8568,7 @@ declare module 'vscode' { * In such an environment, only CustomExecution tasks can be run. * * @param task the task to execute + * @returns A thenable that resolves to a task execution. */ export function executeTask(task: Task): Thenable; @@ -8106,6 +8626,9 @@ declare module 'vscode' { SymbolicLink = 64 } + /** + * Permissions of a file. + */ export enum FilePermission { /** * The file is readonly. @@ -8303,7 +8826,16 @@ declare module 'vscode' { * @param options Configures the watch. * @returns A disposable that tells the provider to stop watching the `uri`. */ - watch(uri: Uri, options: { readonly recursive: boolean; readonly excludes: readonly string[] }): Disposable; + watch(uri: Uri, options: { + /** + * When enabled also watch subfolders. + */ + readonly recursive: boolean; + /** + * A list of paths and pattern to exclude from watching. + */ + readonly excludes: readonly string[]; + }): Disposable; /** * Retrieve metadata about a file. @@ -8313,7 +8845,7 @@ declare module 'vscode' { * `FileType.SymbolicLink | FileType.Directory`. * * @param uri The uri of the file to retrieve metadata about. - * @return The file metadata about the file. + * @returns The file metadata about the file. * @throws {@linkcode FileSystemError.FileNotFound FileNotFound} when `uri` doesn't exist. */ stat(uri: Uri): FileStat | Thenable; @@ -8322,7 +8854,7 @@ declare module 'vscode' { * Retrieve all entries of a {@link FileType.Directory directory}. * * @param uri The uri of the folder. - * @return An array of name/type-tuples or a thenable that resolves to such. + * @returns An array of name/type-tuples or a thenable that resolves to such. * @throws {@linkcode FileSystemError.FileNotFound FileNotFound} when `uri` doesn't exist. */ readDirectory(uri: Uri): [string, FileType][] | Thenable<[string, FileType][]>; @@ -8341,7 +8873,7 @@ declare module 'vscode' { * Read the entire contents of a file. * * @param uri The uri of the file. - * @return An array of bytes or a thenable that resolves to such. + * @returns An array of bytes or a thenable that resolves to such. * @throws {@linkcode FileSystemError.FileNotFound FileNotFound} when `uri` doesn't exist. */ readFile(uri: Uri): Uint8Array | Thenable; @@ -8357,7 +8889,16 @@ declare module 'vscode' { * @throws {@linkcode FileSystemError.FileExists FileExists} when `uri` already exists, `create` is set but `overwrite` is not set. * @throws {@linkcode FileSystemError.NoPermissions NoPermissions} when permissions aren't sufficient. */ - writeFile(uri: Uri, content: Uint8Array, options: { readonly create: boolean; readonly overwrite: boolean }): void | Thenable; + writeFile(uri: Uri, content: Uint8Array, options: { + /** + * Create the file if it does not exist already. + */ + readonly create: boolean; + /** + * Overwrite the file if it does exist. + */ + readonly overwrite: boolean; + }): void | Thenable; /** * Delete a file. @@ -8367,7 +8908,12 @@ declare module 'vscode' { * @throws {@linkcode FileSystemError.FileNotFound FileNotFound} when `uri` doesn't exist. * @throws {@linkcode FileSystemError.NoPermissions NoPermissions} when permissions aren't sufficient. */ - delete(uri: Uri, options: { readonly recursive: boolean }): void | Thenable; + delete(uri: Uri, options: { + /** + * Delete the content recursively if a folder is denoted. + */ + readonly recursive: boolean; + }): void | Thenable; /** * Rename a file or folder. @@ -8380,7 +8926,12 @@ declare module 'vscode' { * @throws {@linkcode FileSystemError.FileExists FileExists} when `newUri` exists and when the `overwrite` option is not `true`. * @throws {@linkcode FileSystemError.NoPermissions NoPermissions} when permissions aren't sufficient. */ - rename(oldUri: Uri, newUri: Uri, options: { readonly overwrite: boolean }): void | Thenable; + rename(oldUri: Uri, newUri: Uri, options: { + /** + * Overwrite the file if it does exist. + */ + readonly overwrite: boolean; + }): void | Thenable; /** * Copy files or folders. Implementing this function is optional but it will speedup @@ -8394,7 +8945,12 @@ declare module 'vscode' { * @throws {@linkcode FileSystemError.FileExists FileExists} when `destination` exists and when the `overwrite` option is not `true`. * @throws {@linkcode FileSystemError.NoPermissions NoPermissions} when permissions aren't sufficient. */ - copy?(source: Uri, destination: Uri, options: { readonly overwrite: boolean }): void | Thenable; + copy?(source: Uri, destination: Uri, options: { + /** + * Overwrite the file if it does exist. + */ + readonly overwrite: boolean; + }): void | Thenable; } /** @@ -8411,7 +8967,7 @@ declare module 'vscode' { * Retrieve metadata about a file. * * @param uri The uri of the file to retrieve metadata about. - * @return The file metadata about the file. + * @returns The file metadata about the file. */ stat(uri: Uri): Thenable; @@ -8419,7 +8975,7 @@ declare module 'vscode' { * Retrieve all entries of a {@link FileType.Directory directory}. * * @param uri The uri of the folder. - * @return An array of name/type-tuples or a thenable that resolves to such. + * @returns An array of name/type-tuples or a thenable that resolves to such. */ readDirectory(uri: Uri): Thenable<[string, FileType][]>; @@ -8437,7 +8993,7 @@ declare module 'vscode' { * Read the entire contents of a file. * * @param uri The uri of the file. - * @return An array of bytes or a thenable that resolves to such. + * @returns An array of bytes or a thenable that resolves to such. */ readFile(uri: Uri): Thenable; @@ -8455,7 +9011,16 @@ declare module 'vscode' { * @param uri The resource that is to be deleted. * @param options Defines if trash can should be used and if deletion of folders is recursive */ - delete(uri: Uri, options?: { recursive?: boolean; useTrash?: boolean }): Thenable; + delete(uri: Uri, options?: { + /** + * Delete the content recursively if a folder is denoted. + */ + recursive?: boolean; + /** + * Use the os's trashcan instead of permanently deleting files whenever possible. + */ + useTrash?: boolean; + }): Thenable; /** * Rename a file or folder. @@ -8464,7 +9029,12 @@ declare module 'vscode' { * @param target The new location. * @param options Defines if existing files should be overwritten. */ - rename(source: Uri, target: Uri, options?: { overwrite?: boolean }): Thenable; + rename(source: Uri, target: Uri, options?: { + /** + * Overwrite the file if it does exist. + */ + overwrite?: boolean; + }): Thenable; /** * Copy files or folders. @@ -8473,7 +9043,12 @@ declare module 'vscode' { * @param target The destination location. * @param options Defines if existing files should be overwritten. */ - copy(source: Uri, target: Uri, options?: { overwrite?: boolean }): Thenable; + copy(source: Uri, target: Uri, options?: { + /** + * Overwrite the file if it does exist. + */ + overwrite?: boolean; + }): Thenable; /** * Check if a given file system supports writing files. @@ -8484,7 +9059,7 @@ declare module 'vscode' { * * @param scheme The scheme of the filesystem, for example `file` or `git`. * - * @return `true` if the file system supports writing, `false` if it does not + * @returns `true` if the file system supports writing, `false` if it does not * support writing (i.e. it is readonly), and `undefined` if the editor does not * know about the filesystem. */ @@ -8622,7 +9197,7 @@ declare module 'vscode' { * efficiently transferred to the webview and will also be correctly recreated inside * of the webview. * - * @return A promise that resolves when the message is posted to a webview or when it is + * @returns A promise that resolves when the message is posted to a webview or when it is * dropped because the message was not deliverable. * * Returns `true` if the message was posted to the webview. Messages can only be posted to @@ -8709,7 +9284,16 @@ declare module 'vscode' { /** * Icon for the panel shown in UI. */ - iconPath?: Uri | { readonly light: Uri; readonly dark: Uri }; + iconPath?: Uri | { + /** + * The icon path for the light theme. + */ + readonly light: Uri; + /** + * The icon path for the dark theme. + */ + readonly dark: Uri; + }; /** * {@linkcode Webview} belonging to the panel. @@ -8826,7 +9410,7 @@ declare module 'vscode' { * serializer must restore the webview's `.html` and hook up all webview events. * @param state Persisted state from the webview content. * - * @return Thenable indicating that the webview has been fully restored. + * @returns Thenable indicating that the webview has been fully restored. */ deserializeWebviewPanel(webviewPanel: WebviewPanel, state: T): Thenable; } @@ -8955,7 +9539,7 @@ declare module 'vscode' { * @param context Additional metadata about the view being resolved. * @param token Cancellation token indicating that the view being provided is no longer needed. * - * @return Optional thenable indicating that the view has been fully resolved. + * @returns Optional thenable indicating that the view has been fully resolved. */ resolveWebviewView(webviewView: WebviewView, context: WebviewViewResolveContext, token: CancellationToken): Thenable | void; } @@ -8986,7 +9570,7 @@ declare module 'vscode' { * * @param token A cancellation token that indicates the result is no longer needed. * - * @return Thenable indicating that the custom editor has been resolved. + * @returns Thenable indicating that the custom editor has been resolved. */ resolveCustomTextEditor(document: TextDocument, webviewPanel: WebviewPanel, token: CancellationToken): Thenable | void; } @@ -9145,7 +9729,7 @@ declare module 'vscode' { * @param openContext Additional information about the opening custom document. * @param token A cancellation token that indicates the result is no longer needed. * - * @return The custom document. + * @returns The custom document. */ openCustomDocument(uri: Uri, openContext: CustomDocumentOpenContext, token: CancellationToken): Thenable | T; @@ -9164,7 +9748,7 @@ declare module 'vscode' { * * @param token A cancellation token that indicates the result is no longer needed. * - * @return Optional thenable indicating that the custom editor has been resolved. + * @returns Optional thenable indicating that the custom editor has been resolved. */ resolveCustomEditor(document: T, webviewPanel: WebviewPanel, token: CancellationToken): Thenable | void; } @@ -9216,7 +9800,7 @@ declare module 'vscode' { * @param document Document to save. * @param cancellation Token that signals the save is no longer required (for example, if another save was triggered). * - * @return Thenable signaling that saving has completed. + * @returns Thenable signaling that saving has completed. */ saveCustomDocument(document: T, cancellation: CancellationToken): Thenable; @@ -9232,7 +9816,7 @@ declare module 'vscode' { * @param destination Location to save to. * @param cancellation Token that signals the save is no longer required. * - * @return Thenable signaling that saving has completed. + * @returns Thenable signaling that saving has completed. */ saveCustomDocumentAs(document: T, destination: Uri, cancellation: CancellationToken): Thenable; @@ -9249,7 +9833,7 @@ declare module 'vscode' { * @param document Document to revert. * @param cancellation Token that signals the revert is no longer required. * - * @return Thenable signaling that the change has completed. + * @returns Thenable signaling that the change has completed. */ revertCustomDocument(document: T, cancellation: CancellationToken): Thenable; @@ -9517,7 +10101,7 @@ declare module 'vscode' { * Any other scheme will be handled as if the provided URI is a workspace URI. In that case, the method will return * a URI which, when handled, will make the editor open the workspace. * - * @return A uri that can be used on the client machine. + * @returns A uri that can be used on the client machine. */ export function asExternalUri(target: Uri): Thenable; @@ -9580,7 +10164,7 @@ declare module 'vscode' { * @param command A unique identifier for the command. * @param callback A command handler function. * @param thisArg The `this` context used when invoking the handler function. - * @return Disposable which unregisters this command on disposal. + * @returns Disposable which unregisters this command on disposal. */ export function registerCommand(command: string, callback: (...args: any[]) => any, thisArg?: any): Disposable; @@ -9597,7 +10181,7 @@ declare module 'vscode' { * @param command A unique identifier for the command. * @param callback A command handler function with access to an {@link TextEditor editor} and an {@link TextEditorEdit edit}. * @param thisArg The `this` context used when invoking the handler function. - * @return Disposable which unregisters this command on disposal. + * @returns Disposable which unregisters this command on disposal. */ export function registerTextEditorCommand(command: string, callback: (textEditor: TextEditor, edit: TextEditorEdit, ...args: any[]) => void, thisArg?: any): Disposable; @@ -9612,7 +10196,7 @@ declare module 'vscode' { * * @param command Identifier of the command to execute. * @param rest Parameters passed to the command function. - * @return A thenable that resolves to the returned value of the given command. Returns `undefined` when + * @returns A thenable that resolves to the returned value of the given command. Returns `undefined` when * the command handler function doesn't return anything. */ export function executeCommand(command: string, ...rest: any[]): Thenable; @@ -9622,7 +10206,7 @@ declare module 'vscode' { * treated as internal commands. * * @param filterInternal Set `true` to not see internal commands (starting with an underscore) - * @return Thenable that resolves to a list of command ids. + * @returns Thenable that resolves to a list of command ids. */ export function getCommands(filterInternal?: boolean): Thenable; } @@ -9801,7 +10385,7 @@ declare module 'vscode' { * Columns that do not exist will be created as needed up to the maximum of {@linkcode ViewColumn.Nine}. Use {@linkcode ViewColumn.Beside} * to open the editor to the side of the currently active one. * @param preserveFocus When `true` the editor will not take focus. - * @return A promise that resolves to an {@link TextEditor editor}. + * @returns A promise that resolves to an {@link TextEditor editor}. */ export function showTextDocument(document: TextDocument, column?: ViewColumn, preserveFocus?: boolean): Thenable; @@ -9811,7 +10395,7 @@ declare module 'vscode' { * * @param document A text document to be shown. * @param options {@link TextDocumentShowOptions Editor options} to configure the behavior of showing the {@link TextEditor editor}. - * @return A promise that resolves to an {@link TextEditor editor}. + * @returns A promise that resolves to an {@link TextEditor editor}. */ export function showTextDocument(document: TextDocument, options?: TextDocumentShowOptions): Thenable; @@ -9822,7 +10406,7 @@ declare module 'vscode' { * * @param uri A resource identifier. * @param options {@link TextDocumentShowOptions Editor options} to configure the behavior of showing the {@link TextEditor editor}. - * @return A promise that resolves to an {@link TextEditor editor}. + * @returns A promise that resolves to an {@link TextEditor editor}. */ export function showTextDocument(uri: Uri, options?: TextDocumentShowOptions): Thenable; @@ -9832,7 +10416,7 @@ declare module 'vscode' { * @param document A text document to be shown. * @param options {@link NotebookDocumentShowOptions Editor options} to configure the behavior of showing the {@link NotebookEditor notebook editor}. * - * @return A promise that resolves to an {@link NotebookEditor notebook editor}. + * @returns A promise that resolves to an {@link NotebookEditor notebook editor}. */ export function showNotebookDocument(document: NotebookDocument, options?: NotebookDocumentShowOptions): Thenable; @@ -9840,7 +10424,7 @@ declare module 'vscode' { * Create a TextEditorDecorationType that can be used to add decorations to text editors. * * @param options Rendering options for the decoration type. - * @return A new decoration type instance. + * @returns A new decoration type instance. */ export function createTextEditorDecorationType(options: DecorationRenderOptions): TextEditorDecorationType; @@ -9850,7 +10434,7 @@ declare module 'vscode' { * * @param message The message to show. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showInformationMessage(message: string, ...items: T[]): Thenable; @@ -9861,7 +10445,7 @@ declare module 'vscode' { * @param message The message to show. * @param options Configures the behaviour of the message. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showInformationMessage(message: string, options: MessageOptions, ...items: T[]): Thenable; @@ -9872,7 +10456,7 @@ declare module 'vscode' { * * @param message The message to show. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showInformationMessage(message: string, ...items: T[]): Thenable; @@ -9884,7 +10468,7 @@ declare module 'vscode' { * @param message The message to show. * @param options Configures the behaviour of the message. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showInformationMessage(message: string, options: MessageOptions, ...items: T[]): Thenable; @@ -9895,7 +10479,7 @@ declare module 'vscode' { * * @param message The message to show. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showWarningMessage(message: string, ...items: T[]): Thenable; @@ -9907,7 +10491,7 @@ declare module 'vscode' { * @param message The message to show. * @param options Configures the behaviour of the message. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showWarningMessage(message: string, options: MessageOptions, ...items: T[]): Thenable; @@ -9918,7 +10502,7 @@ declare module 'vscode' { * * @param message The message to show. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showWarningMessage(message: string, ...items: T[]): Thenable; @@ -9930,7 +10514,7 @@ declare module 'vscode' { * @param message The message to show. * @param options Configures the behaviour of the message. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showWarningMessage(message: string, options: MessageOptions, ...items: T[]): Thenable; @@ -9941,7 +10525,7 @@ declare module 'vscode' { * * @param message The message to show. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showErrorMessage(message: string, ...items: T[]): Thenable; @@ -9953,7 +10537,7 @@ declare module 'vscode' { * @param message The message to show. * @param options Configures the behaviour of the message. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showErrorMessage(message: string, options: MessageOptions, ...items: T[]): Thenable; @@ -9964,7 +10548,7 @@ declare module 'vscode' { * * @param message The message to show. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showErrorMessage(message: string, ...items: T[]): Thenable; @@ -9976,7 +10560,7 @@ declare module 'vscode' { * @param message The message to show. * @param options Configures the behaviour of the message. * @param items A set of items that will be rendered as actions in the message. - * @return A thenable that resolves to the selected item or `undefined` when being dismissed. + * @returns A thenable that resolves to the selected item or `undefined` when being dismissed. */ export function showErrorMessage(message: string, options: MessageOptions, ...items: T[]): Thenable; @@ -9986,9 +10570,9 @@ declare module 'vscode' { * @param items An array of strings, or a promise that resolves to an array of strings. * @param options Configures the behavior of the selection list. * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to the selected items or `undefined`. + * @returns A promise that resolves to the selected items or `undefined`. */ - export function showQuickPick(items: readonly string[] | Thenable, options: QuickPickOptions & { canPickMany: true }, token?: CancellationToken): Thenable; + export function showQuickPick(items: readonly string[] | Thenable, options: QuickPickOptions & { /** literal-type defines return type */canPickMany: true }, token?: CancellationToken): Thenable; /** * Shows a selection list. @@ -9996,7 +10580,7 @@ declare module 'vscode' { * @param items An array of strings, or a promise that resolves to an array of strings. * @param options Configures the behavior of the selection list. * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to the selection or `undefined`. + * @returns A promise that resolves to the selection or `undefined`. */ export function showQuickPick(items: readonly string[] | Thenable, options?: QuickPickOptions, token?: CancellationToken): Thenable; @@ -10006,9 +10590,9 @@ declare module 'vscode' { * @param items An array of items, or a promise that resolves to an array of items. * @param options Configures the behavior of the selection list. * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to the selected items or `undefined`. + * @returns A promise that resolves to the selected items or `undefined`. */ - export function showQuickPick(items: readonly T[] | Thenable, options: QuickPickOptions & { canPickMany: true }, token?: CancellationToken): Thenable; + export function showQuickPick(items: readonly T[] | Thenable, options: QuickPickOptions & { /** literal-type defines return type */ canPickMany: true }, token?: CancellationToken): Thenable; /** * Shows a selection list. @@ -10016,7 +10600,7 @@ declare module 'vscode' { * @param items An array of items, or a promise that resolves to an array of items. * @param options Configures the behavior of the selection list. * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to the selected item or `undefined`. + * @returns A promise that resolves to the selected item or `undefined`. */ export function showQuickPick(items: readonly T[] | Thenable, options?: QuickPickOptions, token?: CancellationToken): Thenable; @@ -10025,7 +10609,7 @@ declare module 'vscode' { * Returns `undefined` if no folder is open. * * @param options Configures the behavior of the workspace folder list. - * @return A promise that resolves to the workspace folder or `undefined`. + * @returns A promise that resolves to the workspace folder or `undefined`. */ export function showWorkspaceFolderPick(options?: WorkspaceFolderPickOptions): Thenable; @@ -10056,7 +10640,7 @@ declare module 'vscode' { * * @param options Configures the behavior of the input box. * @param token A token that can be used to signal cancellation. - * @return A promise that resolves to a string the user provided or to `undefined` in case of dismissal. + * @returns A promise that resolves to a string the user provided or to `undefined` in case of dismissal. */ export function showInputBox(options?: InputBoxOptions, token?: CancellationToken): Thenable; @@ -10068,7 +10652,7 @@ declare module 'vscode' { * is easier to use. {@link window.createQuickPick} should be used * when {@link window.showQuickPick} does not offer the required flexibility. * - * @return A new {@link QuickPick}. + * @returns A new {@link QuickPick}. */ export function createQuickPick(): QuickPick; @@ -10079,7 +10663,7 @@ declare module 'vscode' { * is easier to use. {@link window.createInputBox} should be used * when {@link window.showInputBox} does not offer the required flexibility. * - * @return A new {@link InputBox}. + * @returns A new {@link InputBox}. */ export function createInputBox(): InputBox; @@ -10092,6 +10676,7 @@ declare module 'vscode' { * * @param name Human-readable string which will be used to represent the channel in the UI. * @param languageId The identifier of the language associated with the channel. + * @returns A new output channel. */ export function createOutputChannel(name: string, languageId?: string): OutputChannel; @@ -10100,8 +10685,9 @@ declare module 'vscode' { * * @param name Human-readable string which will be used to represent the channel in the UI. * @param options Options for the log output channel. + * @returns A new log output channel. */ - export function createOutputChannel(name: string, options: { log: true }): LogOutputChannel; + export function createOutputChannel(name: string, options: { /** literal-type defines return type */log: true }): LogOutputChannel; /** * Create and show a new webview panel. @@ -10111,9 +10697,18 @@ declare module 'vscode' { * @param showOptions Where to show the webview in the editor. If preserveFocus is set, the new webview will not take focus. * @param options Settings for the new panel. * - * @return New webview panel. + * @returns New webview panel. */ - export function createWebviewPanel(viewType: string, title: string, showOptions: ViewColumn | { readonly viewColumn: ViewColumn; readonly preserveFocus?: boolean }, options?: WebviewPanelOptions & WebviewOptions): WebviewPanel; + export function createWebviewPanel(viewType: string, title: string, showOptions: ViewColumn | { + /** + * The view column in which the {@link WebviewPanel} should be shown. + */ + readonly viewColumn: ViewColumn; + /** + * An optional flag that when `true` will stop the panel from taking focus. + */ + readonly preserveFocus?: boolean; + }, options?: WebviewPanelOptions & WebviewOptions): WebviewPanel; /** * Set a message to the status bar. This is a short hand for the more powerful @@ -10121,7 +10716,7 @@ declare module 'vscode' { * * @param text The message to show, supports icon substitution as in status bar {@link StatusBarItem.text items}. * @param hideAfterTimeout Timeout in milliseconds after which the message will be disposed. - * @return A disposable which hides the status bar message. + * @returns A disposable which hides the status bar message. */ export function setStatusBarMessage(text: string, hideAfterTimeout: number): Disposable; @@ -10131,7 +10726,7 @@ declare module 'vscode' { * * @param text The message to show, supports icon substitution as in status bar {@link StatusBarItem.text items}. * @param hideWhenDone Thenable on which completion (resolve or reject) the message will be disposed. - * @return A disposable which hides the status bar message. + * @returns A disposable which hides the status bar message. */ export function setStatusBarMessage(text: string, hideWhenDone: Thenable): Disposable; @@ -10143,7 +10738,7 @@ declare module 'vscode' { * longer used. * * @param text The message to show, supports icon substitution as in status bar {@link StatusBarItem.text items}. - * @return A disposable which hides the status bar message. + * @returns A disposable which hides the status bar message. */ export function setStatusBarMessage(text: string): Disposable; @@ -10155,7 +10750,7 @@ declare module 'vscode' { * * @param task A callback returning a promise. Progress increments can be reported with * the provided {@link Progress}-object. - * @return The thenable the task did return. + * @returns The thenable the task did return. */ export function withScmProgress(task: (progress: Progress) => Thenable): Thenable; @@ -10164,6 +10759,7 @@ declare module 'vscode' { * and while the promise it returned isn't resolved nor rejected. The location at which * progress should show (and other details) is defined via the passed {@linkcode ProgressOptions}. * + * @param options A {@linkcode ProgressOptions}-object describing the options to use for showing progress, like its location * @param task A callback returning a promise. Progress state can be reported with * the provided {@link Progress}-object. * @@ -10176,9 +10772,18 @@ declare module 'vscode' { * Note that currently only `ProgressLocation.Notification` is supporting to show a cancel button to cancel the * long running operation. * - * @return The thenable the task-callback returned. + * @returns The thenable the task-callback returned. */ - export function withProgress(options: ProgressOptions, task: (progress: Progress<{ message?: string; increment?: number }>, token: CancellationToken) => Thenable): Thenable; + export function withProgress(options: ProgressOptions, task: (progress: Progress<{ + /** + * A progress message that represents a chunk of work + */ + message?: string; + /** + * An increment for discrete progress. Increments will be summed up until 100% is reached + */ + increment?: number; + }>, token: CancellationToken) => Thenable): Thenable; /** * Creates a status bar {@link StatusBarItem item}. @@ -10186,7 +10791,7 @@ declare module 'vscode' { * @param id The identifier of the item. Must be unique within the extension. * @param alignment The alignment of the item. * @param priority The priority of the item. Higher values mean the item should be shown more to the left. - * @return A new status bar item. + * @returns A new status bar item. */ export function createStatusBarItem(id: string, alignment?: StatusBarAlignment, priority?: number): StatusBarItem; @@ -10196,7 +10801,7 @@ declare module 'vscode' { * @see {@link createStatusBarItem} for creating a status bar item with an identifier. * @param alignment The alignment of the item. * @param priority The priority of the item. Higher values mean the item should be shown more to the left. - * @return A new status bar item. + * @returns A new status bar item. */ export function createStatusBarItem(alignment?: StatusBarAlignment, priority?: number): StatusBarItem; @@ -10209,7 +10814,7 @@ declare module 'vscode' { * @param shellArgs Optional args for the custom shell executable. A string can be used on Windows only which * allows specifying shell args in * [command-line format](https://msdn.microsoft.com/en-au/08dfcab2-eb6e-49a4-80eb-87d4076c98c6). - * @return A new Terminal. + * @returns A new Terminal. * @throws When running in an environment where a new process cannot be started. */ export function createTerminal(name?: string, shellPath?: string, shellArgs?: readonly string[] | string): Terminal; @@ -10218,7 +10823,7 @@ declare module 'vscode' { * Creates a {@link Terminal} with a backing shell process. * * @param options A TerminalOptions object describing the characteristics of the new terminal. - * @return A new Terminal. + * @returns A new Terminal. * @throws When running in an environment where a new process cannot be started. */ export function createTerminal(options: TerminalOptions): Terminal; @@ -10228,7 +10833,7 @@ declare module 'vscode' { * * @param options An {@link ExtensionTerminalOptions} object describing * the characteristics of the new terminal. - * @return A new Terminal. + * @returns A new Terminal. */ export function createTerminal(options: ExtensionTerminalOptions): Terminal; @@ -10240,6 +10845,7 @@ declare module 'vscode' { * * @param viewId Id of the view contributed using the extension point `views`. * @param treeDataProvider A {@link TreeDataProvider} that provides tree data for the view + * @returns A {@link Disposable disposable} that unregisters the {@link TreeDataProvider}. */ export function registerTreeDataProvider(viewId: string, treeDataProvider: TreeDataProvider): Disposable; @@ -10271,6 +10877,7 @@ declare module 'vscode' { * the current extension is about to be handled. * * @param handler The uri handler to register for this extension. + * @returns A {@link Disposable disposable} that unregisters the handler. */ export function registerUriHandler(handler: UriHandler): Disposable; @@ -10284,6 +10891,7 @@ declare module 'vscode' { * * @param viewType Type of the webview panel that can be serialized. * @param serializer Webview serializer. + * @returns A {@link Disposable disposable} that unregisters the serializer. */ export function registerWebviewPanelSerializer(viewType: string, serializer: WebviewPanelSerializer): Disposable; @@ -10294,7 +10902,7 @@ declare module 'vscode' { * `views` contribution in the package.json. * @param provider Provider for the webview views. * - * @return Disposable that unregisters the provider. + * @returns Disposable that unregisters the provider. */ export function registerWebviewViewProvider(viewId: string, provider: WebviewViewProvider, options?: { /** @@ -10333,7 +10941,7 @@ declare module 'vscode' { * @param provider Provider that resolves custom editors. * @param options Options for the provider. * - * @return Disposable that unregisters the provider. + * @returns Disposable that unregisters the provider. */ export function registerCustomEditorProvider(viewType: string, provider: CustomTextEditorProvider | CustomReadonlyEditorProvider | CustomEditorProvider, options?: { /** @@ -10361,21 +10969,23 @@ declare module 'vscode' { /** * Register provider that enables the detection and handling of links within the terminal. * @param provider The provider that provides the terminal links. - * @return Disposable that unregisters the provider. + * @returns Disposable that unregisters the provider. */ export function registerTerminalLinkProvider(provider: TerminalLinkProvider): Disposable; /** * Registers a provider for a contributed terminal profile. + * * @param id The ID of the contributed terminal profile. * @param provider The terminal profile provider. + * @returns A {@link Disposable disposable} that unregisters the provider. */ export function registerTerminalProfileProvider(id: string, provider: TerminalProfileProvider): Disposable; /** * Register a file decoration provider. * * @param provider A {@link FileDecorationProvider}. - * @return A {@link Disposable} that unregisters the provider. + * @returns A {@link Disposable} that unregisters the provider. */ export function registerFileDecorationProvider(provider: FileDecorationProvider): Disposable; @@ -10753,11 +11363,24 @@ declare module 'vscode' { * In order to not to select, set the option `select` to `false`. * In order to focus, set the option `focus` to `true`. * In order to expand the revealed element, set the option `expand` to `true`. To expand recursively set `expand` to the number of levels to expand. - * **NOTE:** You can expand only to 3 levels maximum. * - * **NOTE:** The {@link TreeDataProvider} that the `TreeView` {@link window.createTreeView is registered with} with must implement {@link TreeDataProvider.getParent getParent} method to access this API. + * * *NOTE:* You can expand only to 3 levels maximum. + * * *NOTE:* The {@link TreeDataProvider} that the `TreeView` {@link window.createTreeView is registered with} with must implement {@link TreeDataProvider.getParent getParent} method to access this API. */ - reveal(element: T, options?: { select?: boolean; focus?: boolean; expand?: boolean | number }): Thenable; + reveal(element: T, options?: { + /** + * If true, then the element will be selected. + */ + select?: boolean; + /** + * If true, then the element will be focused. + */ + focus?: boolean; + /** + * If true, then the element will be expanded. If a number is passed, then up to that number of levels of children will be expanded + */ + expand?: boolean | number; + }): Thenable; } /** @@ -10775,7 +11398,7 @@ declare module 'vscode' { * Get {@link TreeItem} representation of the `element` * * @param element The element for which {@link TreeItem} representation is asked for. - * @return TreeItem representation of the element. + * @returns TreeItem representation of the element. */ getTreeItem(element: T): TreeItem | Thenable; @@ -10783,7 +11406,7 @@ declare module 'vscode' { * Get the children of `element` or root if no element is passed. * * @param element The element from which the provider gets children. Can be `undefined`. - * @return Children of `element` or root if no element is passed. + * @returns Children of `element` or root if no element is passed. */ getChildren(element?: T): ProviderResult; @@ -10794,7 +11417,7 @@ declare module 'vscode' { * **NOTE:** This method should be implemented in order to access {@link TreeView.reveal reveal} API. * * @param element The element for which the parent has to be returned. - * @return Parent of `element`. + * @returns Parent of `element`. */ getParent?(element: T): ProviderResult; @@ -10816,12 +11439,15 @@ declare module 'vscode' { * @param item Undefined properties of `item` should be set then `item` should be returned. * @param element The object associated with the TreeItem. * @param token A cancellation token. - * @return The resolved tree item or a thenable that resolves to such. It is OK to return the given + * @returns The resolved tree item or a thenable that resolves to such. It is OK to return the given * `item`. When no result is returned, the given `item` will be used. */ resolveTreeItem?(item: TreeItem, element: T, token: CancellationToken): ProviderResult; } + /** + * A tree item is an UI element of the tree. Tree items are created by the {@link TreeDataProvider data provider}. + */ export class TreeItem { /** * A human-readable string describing this item. When `falsy`, it is derived from {@link TreeItem.resourceUri resourceUri}. @@ -10840,7 +11466,16 @@ declare module 'vscode' { * When `falsy`, {@link ThemeIcon.Folder Folder Theme Icon} is assigned, if item is collapsible otherwise {@link ThemeIcon.File File Theme Icon}. * When a file or folder {@link ThemeIcon} is specified, icon is derived from the current file icon theme for the specified theme icon using {@link TreeItem.resourceUri resourceUri} (if provided). */ - iconPath?: string | Uri | { light: string | Uri; dark: string | Uri } | ThemeIcon; + iconPath?: string | Uri | { + /** + * The icon path for the light theme. + */ + light: string | Uri; + /** + * The icon path for the dark theme. + */ + dark: string | Uri; + } | ThemeIcon; /** * A human-readable string which is rendered less prominent. @@ -10906,7 +11541,20 @@ declare module 'vscode' { * {@link TreeItemCheckboxState TreeItemCheckboxState} of the tree item. * {@link TreeDataProvider.onDidChangeTreeData onDidChangeTreeData} should be fired when {@link TreeItem.checkboxState checkboxState} changes. */ - checkboxState?: TreeItemCheckboxState | { readonly state: TreeItemCheckboxState; readonly tooltip?: string; readonly accessibilityInformation?: AccessibilityInformation }; + checkboxState?: TreeItemCheckboxState | { + /** + * The {@link TreeItemCheckboxState} of the tree item + */ + readonly state: TreeItemCheckboxState; + /** + * A tooltip for the checkbox + */ + readonly tooltip?: string; + /** + * Accessibility information used when screen readers interact with this checkbox + */ + readonly accessibilityInformation?: AccessibilityInformation; + }; /** * @param label A human-readable string describing this item @@ -11028,7 +11676,16 @@ declare module 'vscode' { /** * The icon path or {@link ThemeIcon} for the terminal. */ - iconPath?: Uri | { light: Uri; dark: Uri } | ThemeIcon; + iconPath?: Uri | { + /** + * The icon path for the light theme. + */ + light: Uri; + /** + * The icon path for the dark theme. + */ + dark: Uri; + } | ThemeIcon; /** * The icon {@link ThemeColor} for the terminal. @@ -11067,7 +11724,16 @@ declare module 'vscode' { /** * The icon path or {@link ThemeIcon} for the terminal. */ - iconPath?: Uri | { light: Uri; dark: Uri } | ThemeIcon; + iconPath?: Uri | { + /** + * The icon path for the light theme. + */ + light: Uri; + /** + * The icon path for the dark theme. + */ + dark: Uri; + } | ThemeIcon; /** * The icon {@link ThemeColor} for the terminal. @@ -11475,7 +12141,7 @@ declare module 'vscode' { * returned. For instance, if the 'workspaceFolder' parameter is not specified, the collection that applies * across all workspace folders will be returned. * - * @return Environment variable collection for the passed in scope. + * @returns Environment variable collection for the passed in scope. */ getScoped(scope: EnvironmentVariableScope): EnvironmentVariableCollection; } @@ -11524,7 +12190,12 @@ declare module 'vscode' { /** * The location at which progress should show. */ - location: ProgressLocation | { viewId: string }; + location: ProgressLocation | { + /** + * The identifier of a view for which progress should be shown. + */ + viewId: string; + }; /** * A human-readable string which will be used to describe the @@ -11701,7 +12372,7 @@ declare module 'vscode' { */ matchOnDetail: boolean; - /* + /** * An optional flag to maintain the scroll position of the quick pick when the quick pick items are updated. Defaults to false. */ keepScrollPosition?: boolean; @@ -11803,7 +12474,16 @@ declare module 'vscode' { /** * Icon for the button. */ - readonly iconPath: Uri | { light: Uri; dark: Uri } | ThemeIcon; + readonly iconPath: Uri | { + /** + * The icon path for the light theme. + */ + light: Uri; + /** + * The icon path for the dark theme. + */ + dark: Uri; + } | ThemeIcon; /** * An optional tooltip. @@ -11867,6 +12547,9 @@ declare module 'vscode' { readonly text: string; } + /** + * Reasons for why a text document has changed. + */ export enum TextDocumentChangeReason { /** The text change is caused by an undo operation. */ Undo = 1, @@ -12107,7 +12790,16 @@ declare module 'vscode' { /** * The files that are going to be renamed. */ - readonly files: ReadonlyArray<{ readonly oldUri: Uri; readonly newUri: Uri }>; + readonly files: ReadonlyArray<{ + /** + * The old uri of a file. + */ + readonly oldUri: Uri; + /** + * The new uri of a file. + */ + readonly newUri: Uri; + }>; /** * Allows to pause the event and to apply a {@link WorkspaceEdit workspace edit}. @@ -12147,7 +12839,16 @@ declare module 'vscode' { /** * The files that got renamed. */ - readonly files: ReadonlyArray<{ readonly oldUri: Uri; readonly newUri: Uri }>; + readonly files: ReadonlyArray<{ + /** + * The old uri of a file. + */ + readonly oldUri: Uri; + /** + * The new uri of a file. + */ + readonly newUri: Uri; + }>; } /** @@ -12296,7 +12997,7 @@ declare module 'vscode' { * * returns the *input* when the given uri is a workspace folder itself * * @param uri An uri. - * @return A workspace folder or `undefined` + * @returns A workspace folder or `undefined` */ export function getWorkspaceFolder(uri: Uri): WorkspaceFolder | undefined; @@ -12310,7 +13011,7 @@ declare module 'vscode' { * @param includeWorkspaceFolder When `true` and when the given path is contained inside a * workspace folder the name of the workspace is prepended. Defaults to `true` when there are * multiple workspace folders and `false` otherwise. - * @return A path relative to the root or the input. + * @returns A path relative to the root or the input. */ export function asRelativePath(pathOrUri: string | Uri, includeWorkspaceFolder?: boolean): string; @@ -12354,10 +13055,19 @@ declare module 'vscode' { * @param deleteCount the optional number of workspace folders to remove. * @param workspaceFoldersToAdd the optional variable set of workspace folders to add in place of the deleted ones. * Each workspace is identified with a mandatory URI and an optional name. - * @return true if the operation was successfully started and false otherwise if arguments were used that would result + * @returns true if the operation was successfully started and false otherwise if arguments were used that would result * in invalid workspace folder state (e.g. 2 folders with the same URI). */ - export function updateWorkspaceFolders(start: number, deleteCount: number | undefined | null, ...workspaceFoldersToAdd: { readonly uri: Uri; readonly name?: string }[]): boolean; + export function updateWorkspaceFolders(start: number, deleteCount: number | undefined | null, ...workspaceFoldersToAdd: { + /** + * The uri of a workspace folder that's to be added. + */ + readonly uri: Uri; + /** + * The name of a workspace folder that's to be added. + */ + readonly name?: string; + }[]): boolean; /** * Creates a file system watcher that is notified on file events (create, change, delete) @@ -12478,7 +13188,7 @@ declare module 'vscode' { * @param ignoreCreateEvents Ignore when files have been created. * @param ignoreChangeEvents Ignore when files have been changed. * @param ignoreDeleteEvents Ignore when files have been deleted. - * @return A new file system watcher instance. Must be disposed when no longer needed. + * @returns A new file system watcher instance. Must be disposed when no longer needed. */ export function createFileSystemWatcher(globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher; @@ -12496,7 +13206,7 @@ declare module 'vscode' { * but not `search.exclude`) will apply. When `null`, no excludes will apply. * @param maxResults An upper-bound for the result. * @param token A token that can be used to signal cancellation to the underlying search engine. - * @return A thenable that resolves to an array of resource identifiers. Will return no results if no + * @returns A thenable that resolves to an array of resource identifiers. Will return no results if no * {@link workspace.workspaceFolders workspace folders} are opened. */ export function findFiles(include: GlobPattern, exclude?: GlobPattern | null, maxResults?: number, token?: CancellationToken): Thenable; @@ -12505,7 +13215,7 @@ declare module 'vscode' { * Save all dirty files. * * @param includeUntitled Also save files that have been created during this session. - * @return A thenable that resolves when the files have been saved. Will return `false` + * @returns A thenable that resolves when the files have been saved. Will return `false` * for any file that failed to save. */ export function saveAll(includeUntitled?: boolean): Thenable; @@ -12525,7 +13235,7 @@ declare module 'vscode' { * * @param edit A workspace edit. * @param metadata Optional {@link WorkspaceEditMetadata metadata} for the edit. - * @return A thenable that resolves when the edit could be applied. + * @returns A thenable that resolves when the edit could be applied. */ export function applyEdit(edit: WorkspaceEdit, metadata?: WorkspaceEditMetadata): Thenable; @@ -12551,7 +13261,7 @@ declare module 'vscode' { * {@linkcode workspace.onDidCloseTextDocument onDidClose}-event can occur at any time after opening it. * * @param uri Identifies the resource to open. - * @return A promise that resolves to a {@link TextDocument document}. + * @returns A promise that resolves to a {@link TextDocument document}. */ export function openTextDocument(uri: Uri): Thenable; @@ -12560,7 +13270,7 @@ declare module 'vscode' { * * @see {@link workspace.openTextDocument} * @param fileName A name of a file on disk. - * @return A promise that resolves to a {@link TextDocument document}. + * @returns A promise that resolves to a {@link TextDocument document}. */ export function openTextDocument(fileName: string): Thenable; @@ -12570,9 +13280,18 @@ declare module 'vscode' { * specify the *language* and/or the *content* of the document. * * @param options Options to control how the document will be created. - * @return A promise that resolves to a {@link TextDocument document}. + * @returns A promise that resolves to a {@link TextDocument document}. */ - export function openTextDocument(options?: { language?: string; content?: string }): Thenable; + export function openTextDocument(options?: { + /** + * The {@link TextDocument.languageId language} of the document. + */ + language?: string; + /** + * The initial contents of the document. + */ + content?: string; + }): Thenable; /** * Register a text document content provider. @@ -12581,7 +13300,7 @@ declare module 'vscode' { * * @param scheme The uri-scheme to register for. * @param provider A content provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerTextDocumentContentProvider(scheme: string, provider: TextDocumentContentProvider): Disposable; @@ -12703,7 +13422,7 @@ declare module 'vscode' { * @param notebookType A notebook. * @param serializer A notebook serializer. * @param options Optional context options that define what parts of a notebook should be persisted - * @return A {@link Disposable} that unregisters this serializer when being disposed. + * @returns A {@link Disposable} that unregisters this serializer when being disposed. */ export function registerNotebookSerializer(notebookType: string, serializer: NotebookSerializer, options?: NotebookDocumentContentOptions): Disposable; @@ -12803,7 +13522,7 @@ declare module 'vscode' { * * @param section A dot-separated identifier. * @param scope A scope for which the configuration is asked for. - * @return The full configuration or a subset. + * @returns The full configuration or a subset. */ export function getConfiguration(section?: string, scope?: ConfigurationScope | null): WorkspaceConfiguration; @@ -12819,7 +13538,7 @@ declare module 'vscode' { * * @param type The task kind type this provider is registered for. * @param provider A task provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerTaskProvider(type: string, provider: TaskProvider): Disposable; @@ -12832,9 +13551,18 @@ declare module 'vscode' { * @param scheme The uri-{@link Uri.scheme scheme} the provider registers for. * @param provider The filesystem provider. * @param options Immutable metadata about the provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ - export function registerFileSystemProvider(scheme: string, provider: FileSystemProvider, options?: { readonly isCaseSensitive?: boolean; readonly isReadonly?: boolean }): Disposable; + export function registerFileSystemProvider(scheme: string, provider: FileSystemProvider, options?: { + /** + * Whether the file system provider use case sensitive compare for {@link Uri.path paths} + */ + readonly isCaseSensitive?: boolean; + /** + * Whether the file system provider is readonly, no modifications like write, delete, create are possible. + */ + readonly isReadonly?: boolean; + }): Disposable; /** * When true, the user has explicitly trusted the contents of the workspace. @@ -12853,7 +13581,16 @@ declare module 'vscode' { * a '{@link TextDocument}' or * a '{@link WorkspaceFolder}' */ - export type ConfigurationScope = Uri | TextDocument | WorkspaceFolder | { uri?: Uri; languageId: string }; + export type ConfigurationScope = Uri | TextDocument | WorkspaceFolder | { + /** + * The uri of a {@link TextDocument text document} + */ + uri?: Uri; + /** + * The language of a text document + */ + languageId: string; + }; /** * An event describing the change in Configuration @@ -12866,7 +13603,7 @@ declare module 'vscode' { * * @param section Configuration name, supports _dotted_ names. * @param scope A scope in which to check. - * @return `true` if the given section has changed. + * @returns `true` if the given section has changed. */ affectsConfiguration(section: string, scope?: ConfigurationScope): boolean; } @@ -12903,7 +13640,7 @@ declare module 'vscode' { /** * Return the identifiers of all known languages. - * @return Promise resolving to an array of identifier strings. + * @returns Promise resolving to an array of identifier strings. */ export function getLanguages(): Thenable; @@ -12963,7 +13700,7 @@ declare module 'vscode' { * * @param selector A document selector. * @param document A text document. - * @return A number `>0` when the selector matches and `0` when the selector does not match. + * @returns A number `>0` when the selector matches and `0` when the selector does not match. */ export function match(selector: DocumentSelector, document: TextDocument): number; @@ -12992,7 +13729,7 @@ declare module 'vscode' { * Create a diagnostics collection. * * @param name The {@link DiagnosticCollection.name name} of the collection. - * @return A new diagnostic collection. + * @returns A new diagnostic collection. */ export function createDiagnosticCollection(name?: string): DiagnosticCollection; @@ -13001,6 +13738,7 @@ declare module 'vscode' { * * @param id The identifier of the item. * @param selector The document selector that defines for what editors the item shows. + * @returns A new language status item. */ export function createLanguageStatusItem(id: string, selector: DocumentSelector): LanguageStatusItem; @@ -13021,7 +13759,7 @@ declare module 'vscode' { * @param selector A selector that defines the documents this provider is applicable to. * @param provider A completion provider. * @param triggerCharacters Trigger completion when the user types one of the characters. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerCompletionItemProvider(selector: DocumentSelector, provider: CompletionItemProvider, ...triggerCharacters: string[]): Disposable; @@ -13034,7 +13772,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider An inline completion provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerInlineCompletionItemProvider(selector: DocumentSelector, provider: InlineCompletionItemProvider): Disposable; @@ -13048,7 +13786,7 @@ declare module 'vscode' { * @param selector A selector that defines the documents this provider is applicable to. * @param provider A code action provider. * @param metadata Metadata about the kind of code actions the provider provides. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerCodeActionsProvider(selector: DocumentSelector, provider: CodeActionProvider, metadata?: CodeActionProviderMetadata): Disposable; @@ -13061,7 +13799,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A code lens provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerCodeLensProvider(selector: DocumentSelector, provider: CodeLensProvider): Disposable; @@ -13074,7 +13812,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A definition provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDefinitionProvider(selector: DocumentSelector, provider: DefinitionProvider): Disposable; @@ -13087,7 +13825,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider An implementation provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerImplementationProvider(selector: DocumentSelector, provider: ImplementationProvider): Disposable; @@ -13100,7 +13838,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A type definition provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerTypeDefinitionProvider(selector: DocumentSelector, provider: TypeDefinitionProvider): Disposable; @@ -13113,7 +13851,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A declaration provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDeclarationProvider(selector: DocumentSelector, provider: DeclarationProvider): Disposable; @@ -13126,7 +13864,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A hover provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerHoverProvider(selector: DocumentSelector, provider: HoverProvider): Disposable; @@ -13138,7 +13876,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider An evaluatable expression provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerEvaluatableExpressionProvider(selector: DocumentSelector, provider: EvaluatableExpressionProvider): Disposable; @@ -13153,7 +13891,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider An inline values provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerInlineValuesProvider(selector: DocumentSelector, provider: InlineValuesProvider): Disposable; @@ -13166,7 +13904,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document highlight provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDocumentHighlightProvider(selector: DocumentSelector, provider: DocumentHighlightProvider): Disposable; @@ -13180,7 +13918,7 @@ declare module 'vscode' { * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document symbol provider. * @param metaData metadata about the provider - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDocumentSymbolProvider(selector: DocumentSelector, provider: DocumentSymbolProvider, metaData?: DocumentSymbolProviderMetadata): Disposable; @@ -13192,7 +13930,7 @@ declare module 'vscode' { * a failure of the whole operation. * * @param provider A workspace symbol provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerWorkspaceSymbolProvider(provider: WorkspaceSymbolProvider): Disposable; @@ -13205,7 +13943,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A reference provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerReferenceProvider(selector: DocumentSelector, provider: ReferenceProvider): Disposable; @@ -13218,7 +13956,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A rename provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerRenameProvider(selector: DocumentSelector, provider: RenameProvider): Disposable; @@ -13231,7 +13969,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document semantic tokens provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDocumentSemanticTokensProvider(selector: DocumentSelector, provider: DocumentSemanticTokensProvider, legend: SemanticTokensLegend): Disposable; @@ -13250,7 +13988,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document range semantic tokens provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDocumentRangeSemanticTokensProvider(selector: DocumentSelector, provider: DocumentRangeSemanticTokensProvider, legend: SemanticTokensLegend): Disposable; @@ -13263,7 +14001,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document formatting edit provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDocumentFormattingEditProvider(selector: DocumentSelector, provider: DocumentFormattingEditProvider): Disposable; @@ -13280,7 +14018,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document range formatting edit provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDocumentRangeFormattingEditProvider(selector: DocumentSelector, provider: DocumentRangeFormattingEditProvider): Disposable; @@ -13295,7 +14033,7 @@ declare module 'vscode' { * @param provider An on type formatting edit provider. * @param firstTriggerCharacter A character on which formatting should be triggered, like `}`. * @param moreTriggerCharacter More trigger characters. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerOnTypeFormattingEditProvider(selector: DocumentSelector, provider: OnTypeFormattingEditProvider, firstTriggerCharacter: string, ...moreTriggerCharacter: string[]): Disposable; @@ -13309,10 +14047,18 @@ declare module 'vscode' { * @param selector A selector that defines the documents this provider is applicable to. * @param provider A signature help provider. * @param triggerCharacters Trigger signature help when the user types one of the characters, like `,` or `(`. - * @param metadata Information about the provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerSignatureHelpProvider(selector: DocumentSelector, provider: SignatureHelpProvider, ...triggerCharacters: string[]): Disposable; + + /** + * @see {@link languages.registerSignatureHelpProvider} + * + * @param selector A selector that defines the documents this provider is applicable to. + * @param provider A signature help provider. + * @param metadata Information about the provider. + * @returns A {@link Disposable} that unregisters this provider when being disposed. + */ export function registerSignatureHelpProvider(selector: DocumentSelector, provider: SignatureHelpProvider, metadata: SignatureHelpProviderMetadata): Disposable; /** @@ -13324,7 +14070,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A document link provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDocumentLinkProvider(selector: DocumentSelector, provider: DocumentLinkProvider): Disposable; @@ -13337,7 +14083,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A color provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerColorProvider(selector: DocumentSelector, provider: DocumentColorProvider): Disposable; @@ -13350,7 +14096,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider An inlay hints provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerInlayHintsProvider(selector: DocumentSelector, provider: InlayHintsProvider): Disposable; @@ -13367,7 +14113,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A folding range provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerFoldingRangeProvider(selector: DocumentSelector, provider: FoldingRangeProvider): Disposable; @@ -13380,7 +14126,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A selection range provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerSelectionRangeProvider(selector: DocumentSelector, provider: SelectionRangeProvider): Disposable; @@ -13389,7 +14135,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A call hierarchy provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerCallHierarchyProvider(selector: DocumentSelector, provider: CallHierarchyProvider): Disposable; @@ -13398,7 +14144,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A type hierarchy provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerTypeHierarchyProvider(selector: DocumentSelector, provider: TypeHierarchyProvider): Disposable; @@ -13411,7 +14157,7 @@ declare module 'vscode' { * * @param selector A selector that defines the documents this provider is applicable to. * @param provider A linked editing range provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerLinkedEditingRangeProvider(selector: DocumentSelector, provider: LinkedEditingRangeProvider): Disposable; @@ -13421,7 +14167,7 @@ declare module 'vscode' { * @param selector A selector that defines the documents this provider applies to. * @param provider A drop provider. * - * @return A {@link Disposable} that unregisters this provider when disposed of. + * @returns A {@link Disposable} that unregisters this provider when disposed of. */ export function registerDocumentDropEditProvider(selector: DocumentSelector, provider: DocumentDropEditProvider): Disposable; @@ -13430,7 +14176,7 @@ declare module 'vscode' { * * @param language A language identifier like `typescript`. * @param configuration Language configuration. - * @return A {@link Disposable} that unsets this configuration. + * @returns A {@link Disposable} that unsets this configuration. */ export function setLanguageConfiguration(language: string, configuration: LanguageConfiguration): Disposable; } @@ -13512,7 +14258,13 @@ declare module 'vscode' { * An event that fires when a message is received from a renderer. */ readonly onDidReceiveMessage: Event<{ + /** + * The {@link NotebookEditor editor} that sent the message. + */ readonly editor: NotebookEditor; + /** + * The actual message. + */ readonly message: any; }>; @@ -13648,7 +14400,7 @@ declare module 'vscode' { * Return the cell at the specified index. The index will be adjusted to the notebook. * * @param index - The index of the cell to retrieve. - * @return A {@link NotebookCell cell}. + * @returns A {@link NotebookCell cell}. */ cellAt(index: number): NotebookCell; @@ -13664,7 +14416,7 @@ declare module 'vscode' { /** * Save the document. The saving will be handled by the corresponding {@link NotebookSerializer serializer}. * - * @return A promise that will resolve to true when the document + * @returns A promise that will resolve to true when the document * has been saved. Will return false if the file was not dirty or when save failed. */ save(): Thenable; @@ -13831,7 +14583,16 @@ declare module 'vscode' { /** * The times at which execution started and ended, as unix timestamps */ - readonly timing?: { readonly startTime: number; readonly endTime: number }; + readonly timing?: { + /** + * Execution start time. + */ + readonly startTime: number; + /** + * Execution end time. + */ + readonly endTime: number; + }; } /** @@ -13868,10 +14629,19 @@ declare module 'vscode' { * Derive a new range for this range. * * @param change An object that describes a change to this range. - * @return A range that reflects the given change. Will return `this` range if the change + * @returns A range that reflects the given change. Will return `this` range if the change * is not changing anything. */ - with(change: { start?: number; end?: number }): NotebookRange; + with(change: { + /** + * New start index, defaults to `this.start`. + */ + start?: number; + /** + * New end index, defaults to `this.end`. + */ + end?: number; + }): NotebookRange; } /** @@ -14079,7 +14849,7 @@ declare module 'vscode' { * * @param content Contents of a notebook file. * @param token A cancellation token. - * @return Notebook data or a thenable that resolves to such. + * @returns Notebook data or a thenable that resolves to such. */ deserializeNotebook(content: Uint8Array, token: CancellationToken): NotebookData | Thenable; @@ -14251,7 +15021,16 @@ declare module 'vscode' { * _Note_ that controller selection is persisted (by the controllers {@link NotebookController.id id}) and restored as soon as a * controller is re-created or as a notebook is {@link workspace.onDidOpenNotebookDocument opened}. */ - readonly onDidChangeSelectedNotebooks: Event<{ readonly notebook: NotebookDocument; readonly selected: boolean }>; + readonly onDidChangeSelectedNotebooks: Event<{ + /** + * The notebook for which the controller has been selected or un-selected. + */ + readonly notebook: NotebookDocument; + /** + * Whether the controller has been selected or un-selected. + */ + readonly selected: boolean; + }>; /** * A controller can set affinities for specific notebook documents. This allows a controller @@ -14320,7 +15099,7 @@ declare module 'vscode' { * * @param cell Cell for which output is cleared. Defaults to the {@link NotebookCellExecution.cell cell} of * this execution. - * @return A thenable that resolves when the operation finished. + * @returns A thenable that resolves when the operation finished. */ clearOutput(cell?: NotebookCell): Thenable; @@ -14330,7 +15109,7 @@ declare module 'vscode' { * @param out Output that replaces the current output. * @param cell Cell for which output is cleared. Defaults to the {@link NotebookCellExecution.cell cell} of * this execution. - * @return A thenable that resolves when the operation finished. + * @returns A thenable that resolves when the operation finished. */ replaceOutput(out: NotebookCellOutput | readonly NotebookCellOutput[], cell?: NotebookCell): Thenable; @@ -14340,7 +15119,7 @@ declare module 'vscode' { * @param out Output that is appended to the current output. * @param cell Cell for which output is cleared. Defaults to the {@link NotebookCellExecution.cell cell} of * this execution. - * @return A thenable that resolves when the operation finished. + * @returns A thenable that resolves when the operation finished. */ appendOutput(out: NotebookCellOutput | readonly NotebookCellOutput[], cell?: NotebookCell): Thenable; @@ -14349,7 +15128,7 @@ declare module 'vscode' { * * @param items Output items that replace the items of existing output. * @param output Output object that already exists. - * @return A thenable that resolves when the operation finished. + * @returns A thenable that resolves when the operation finished. */ replaceOutputItems(items: NotebookCellOutputItem | readonly NotebookCellOutputItem[], output: NotebookCellOutput): Thenable; @@ -14358,7 +15137,7 @@ declare module 'vscode' { * * @param items Output items that are append to existing output. * @param output Output object that already exists. - * @return A thenable that resolves when the operation finished. + * @returns A thenable that resolves when the operation finished. */ appendOutputItems(items: NotebookCellOutputItem | readonly NotebookCellOutputItem[], output: NotebookCellOutput): Thenable; } @@ -14439,7 +15218,7 @@ declare module 'vscode' { * The provider will be called when the cell scrolls into view, when its content, outputs, language, or metadata change, and when it changes execution state. * @param cell The cell for which to return items. * @param token A token triggered if this request should be cancelled. - * @return One or more {@link NotebookCellStatusBarItem cell statusbar items} + * @returns One or more {@link NotebookCellStatusBarItem cell statusbar items} */ provideCellStatusBarItems(cell: NotebookCell, token: CancellationToken): ProviderResult; } @@ -14462,6 +15241,7 @@ declare module 'vscode' { * @param notebookType A notebook type for which this controller is for. * @param label The label of the controller. * @param handler The execute-handler of the controller. + * @returns A new notebook controller. */ export function createNotebookController(id: string, notebookType: string, label: string, handler?: (cells: NotebookCell[], notebook: NotebookDocument, controller: NotebookController) => void | Thenable): NotebookController; @@ -14470,7 +15250,7 @@ declare module 'vscode' { * * @param notebookType The notebook type to register for. * @param provider A cell status bar provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerNotebookCellStatusBarItemProvider(notebookType: string, provider: NotebookCellStatusBarItemProvider): Disposable; @@ -14513,14 +15293,19 @@ declare module 'vscode' { visible: boolean; } - interface QuickDiffProvider { + /** + * A quick diff provider provides a {@link Uri uri} to the original state of a + * modified resource. The editor will use this information to render ad'hoc diffs + * within the text. + */ + export interface QuickDiffProvider { /** * Provide a {@link Uri} to the original resource of any given resource uri. * * @param uri The uri of the resource open in a text editor. * @param token A cancellation token. - * @return A thenable that resolves to uri of the matching original resource. + * @returns A thenable that resolves to uri of the matching original resource. */ provideOriginalResource?(uri: Uri, token: CancellationToken): ProviderResult; } @@ -14726,6 +15511,9 @@ declare module 'vscode' { dispose(): void; } + /** + * Namespace for source control mangement. + */ export namespace scm { /** @@ -14742,7 +15530,7 @@ declare module 'vscode' { * @param id An `id` for the source control. Something short, e.g.: `git`. * @param label A human-readable string for the source control. E.g.: `Git`. * @param rootUri An optional Uri of the root of the source control. E.g.: `Uri.parse(workspaceRoot)`. - * @return An instance of {@link SourceControl source control}. + * @returns An instance of {@link SourceControl source control}. */ export function createSourceControl(id: string, label: string, rootUri?: Uri): SourceControl; } @@ -14843,7 +15631,7 @@ declare module 'vscode' { * If no DAP breakpoint exists (either because the editor breakpoint was not yet registered or because the debug adapter is not interested in the breakpoint), the value `undefined` is returned. * * @param breakpoint A {@link Breakpoint} in the editor. - * @return A promise that resolves to the Debug Adapter Protocol breakpoint or `undefined`. + * @returns A promise that resolves to the Debug Adapter Protocol breakpoint or `undefined`. */ getDebugProtocolBreakpoint(breakpoint: Breakpoint): Thenable; } @@ -14880,7 +15668,7 @@ declare module 'vscode' { * * @param folder The workspace folder for which the configurations are used or `undefined` for a folderless setup. * @param token A cancellation token. - * @return An array of {@link DebugConfiguration debug configurations}. + * @returns An array of {@link DebugConfiguration debug configurations}. */ provideDebugConfigurations?(folder: WorkspaceFolder | undefined, token?: CancellationToken): ProviderResult; @@ -14894,7 +15682,7 @@ declare module 'vscode' { * @param folder The workspace folder from which the configuration originates from or `undefined` for a folderless setup. * @param debugConfiguration The {@link DebugConfiguration debug configuration} to resolve. * @param token A cancellation token. - * @return The resolved debug configuration or undefined or null. + * @returns The resolved debug configuration or undefined or null. */ resolveDebugConfiguration?(folder: WorkspaceFolder | undefined, debugConfiguration: DebugConfiguration, token?: CancellationToken): ProviderResult; @@ -14909,7 +15697,7 @@ declare module 'vscode' { * @param folder The workspace folder from which the configuration originates from or `undefined` for a folderless setup. * @param debugConfiguration The {@link DebugConfiguration debug configuration} to resolve. * @param token A cancellation token. - * @return The resolved debug configuration or undefined or null. + * @returns The resolved debug configuration or undefined or null. */ resolveDebugConfigurationWithSubstitutedVariables?(folder: WorkspaceFolder | undefined, debugConfiguration: DebugConfiguration, token?: CancellationToken): ProviderResult; } @@ -15032,8 +15820,14 @@ declare module 'vscode' { constructor(implementation: DebugAdapter); } + /** + * Represents the different types of debug adapters + */ export type DebugAdapterDescriptor = DebugAdapterExecutable | DebugAdapterServer | DebugAdapterNamedPipeServer | DebugAdapterInlineImplementation; + /** + * A debug adaper factory that creates {@link DebugAdapterDescriptor debug adapter descriptors}. + */ export interface DebugAdapterDescriptorFactory { /** * 'createDebugAdapterDescriptor' is called at the start of a debug session to provide details about the debug adapter to use. @@ -15050,7 +15844,7 @@ declare module 'vscode' { * } * @param session The {@link DebugSession debug session} for which the debug adapter will be used. * @param executable The debug adapter's executable information as specified in the package.json (or undefined if no such information exists). - * @return a {@link DebugAdapterDescriptor debug adapter descriptor} or undefined. + * @returns a {@link DebugAdapterDescriptor debug adapter descriptor} or undefined. */ createDebugAdapterDescriptor(session: DebugSession, executable: DebugAdapterExecutable | undefined): ProviderResult; } @@ -15085,13 +15879,16 @@ declare module 'vscode' { onExit?(code: number | undefined, signal: string | undefined): void; } + /** + * A debug adaper factory that creates {@link DebugAdapterTracker debug adapter trackers}. + */ export interface DebugAdapterTrackerFactory { /** * The method 'createDebugAdapterTracker' is called at the start of a debug session in order * to return a "tracker" object that provides read-access to the communication between the editor and a debug adapter. * * @param session The {@link DebugSession debug session} for which the debug adapter tracker will be used. - * @return A {@link DebugAdapterTracker debug adapter tracker} or undefined. + * @returns A {@link DebugAdapterTracker debug adapter tracker} or undefined. */ createDebugAdapterTracker(session: DebugSession): ProviderResult; } @@ -15161,6 +15958,14 @@ declare module 'vscode' { */ readonly logMessage?: string | undefined; + /** + * Creates a new breakpoint + * + * @param enabled Is breakpoint enabled. + * @param condition Expression for conditional breakpoints + * @param hitCondition Expression that controls how many hits of the breakpoint are ignored + * @param logMessage Log message to display when breakpoint is hit + */ protected constructor(enabled?: boolean, condition?: string, hitCondition?: string, logMessage?: string); } @@ -15348,7 +16153,7 @@ declare module 'vscode' { * @param debugType The debug type for which the provider is registered. * @param provider The {@link DebugConfigurationProvider debug configuration provider} to register. * @param triggerKind The {@link DebugConfigurationProviderTriggerKind trigger} for which the 'provideDebugConfiguration' method of the provider is registered. If `triggerKind` is missing, the value `DebugConfigurationProviderTriggerKind.Initial` is assumed. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerDebugConfigurationProvider(debugType: string, provider: DebugConfigurationProvider, triggerKind?: DebugConfigurationProviderTriggerKind): Disposable; @@ -15359,7 +16164,7 @@ declare module 'vscode' { * * @param debugType The debug type for which the factory is registered. * @param factory The {@link DebugAdapterDescriptorFactory debug adapter descriptor factory} to register. - * @return A {@link Disposable} that unregisters this factory when being disposed. + * @returns A {@link Disposable} that unregisters this factory when being disposed. */ export function registerDebugAdapterDescriptorFactory(debugType: string, factory: DebugAdapterDescriptorFactory): Disposable; @@ -15368,7 +16173,7 @@ declare module 'vscode' { * * @param debugType The debug type for which the factory is registered or '*' for matching all debug types. * @param factory The {@link DebugAdapterTrackerFactory debug adapter tracker factory} to register. - * @return A {@link Disposable} that unregisters this factory when being disposed. + * @returns A {@link Disposable} that unregisters this factory when being disposed. */ export function registerDebugAdapterTrackerFactory(debugType: string, factory: DebugAdapterTrackerFactory): Disposable; @@ -15381,13 +16186,15 @@ declare module 'vscode' { * @param folder The {@link WorkspaceFolder workspace folder} for looking up named configurations and resolving variables or `undefined` for a non-folder setup. * @param nameOrConfiguration Either the name of a debug or compound configuration or a {@link DebugConfiguration} object. * @param parentSessionOrOptions Debug session options. When passed a parent {@link DebugSession debug session}, assumes options with just this parent session. - * @return A thenable that resolves when debugging could be successfully started. + * @returns A thenable that resolves when debugging could be successfully started. */ export function startDebugging(folder: WorkspaceFolder | undefined, nameOrConfiguration: string | DebugConfiguration, parentSessionOrOptions?: DebugSession | DebugSessionOptions): Thenable; /** * Stop the given debug session or stop all debug sessions if session is omitted. + * * @param session The {@link DebugSession debug session} to stop; if omitted all sessions are stopped. + * @returns A thenable that resolves when the session(s) have been stopped. */ export function stopDebugging(session?: DebugSession): Thenable; @@ -15412,7 +16219,7 @@ declare module 'vscode' { * * @param source An object conforming to the [Source](https://microsoft.github.io/debug-adapter-protocol/specification#Types_Source) type defined in the Debug Adapter Protocol. * @param session An optional debug session that will be used when the source descriptor uses a reference number to load the contents from an active debug session. - * @return A uri that can be used to load the contents of the source. + * @returns A uri that can be used to load the contents of the source. */ export function asDebugSourceUri(source: DebugProtocolSource, session?: DebugSession): Uri; } @@ -15455,7 +16262,7 @@ declare module 'vscode' { * Get an extension by its full identifier in the form of: `publisher.name`. * * @param extensionId An extension identifier. - * @return An extension or `undefined`. + * @returns An extension or `undefined`. */ export function getExtension(extensionId: string): Extension | undefined; @@ -15505,7 +16312,13 @@ declare module 'vscode' { * The state of a comment thread. */ export enum CommentThreadState { + /** + * Unresolved thread state + */ Unresolved = 0, + /** + * Resolved thread state + */ Resolved = 1 } @@ -15773,7 +16586,7 @@ declare module 'vscode' { * * @param id An `id` for the comment controller. * @param label A human-readable string for the comment controller. - * @return An instance of {@link CommentController comment controller}. + * @returns An instance of {@link CommentController comment controller}. */ export function createCommentController(id: string, label: string): CommentController; } @@ -16014,7 +16827,7 @@ declare module 'vscode' { * @param options The {@link AuthenticationGetSessionOptions} to use * @returns A thenable that resolves to an authentication session */ - export function getSession(providerId: string, scopes: readonly string[], options: AuthenticationGetSessionOptions & { createIfNone: true }): Thenable; + export function getSession(providerId: string, scopes: readonly string[], options: AuthenticationGetSessionOptions & { /** */createIfNone: true }): Thenable; /** * Get an authentication session matching the desired scopes. Rejects if a provider with providerId is not @@ -16029,7 +16842,7 @@ declare module 'vscode' { * @param options The {@link AuthenticationGetSessionOptions} to use * @returns A thenable that resolves to an authentication session */ - export function getSession(providerId: string, scopes: readonly string[], options: AuthenticationGetSessionOptions & { forceNewSession: true | AuthenticationForceNewSessionOptions }): Thenable; + export function getSession(providerId: string, scopes: readonly string[], options: AuthenticationGetSessionOptions & { /** literal-type defines return type */forceNewSession: true | AuthenticationForceNewSessionOptions }): Thenable; /** * Get an authentication session matching the desired scopes. Rejects if a provider with providerId is not @@ -16062,7 +16875,7 @@ declare module 'vscode' { * @param label The human-readable name of the provider. * @param provider The authentication provider provider. * @param options Additional options for the provider. - * @return A {@link Disposable} that unregisters this provider when being disposed. + * @returns A {@link Disposable} that unregisters this provider when being disposed. */ export function registerAuthenticationProvider(id: string, label: string, provider: AuthenticationProvider, options?: AuthenticationProviderOptions): Disposable; } @@ -16171,8 +16984,17 @@ declare module 'vscode' { * The kind of executions that {@link TestRunProfile TestRunProfiles} control. */ export enum TestRunProfileKind { + /** + * The `Run` test profile kind. + */ Run = 1, + /** + * The `Debug` test profile kind. + */ Debug = 2, + /** + * The `Coverage` test profile kind. + */ Coverage = 3, } @@ -17020,8 +17842,17 @@ declare module 'vscode' { * This is to be used when you can guarantee no identifiable information is contained in the value and the cleaning is improperly redacting it. */ export class TelemetryTrustedValue { + + /** + * The value that is trusted to not contain PII. + */ readonly value: T; + /** + * Creates a new telementry trusted value. + * + * @param value A value to trust + */ constructor(value: T); } @@ -17168,5 +17999,11 @@ interface Thenable { * @returns A Promise for the completion of which ever callback is executed. */ then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; } From e1430e432895252e7cba410898e89d0337c564d1 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 1 Sep 2023 13:41:45 +0200 Subject: [PATCH 179/198] Sets up hot reloading of css and code (requires vscode-diagnostic-tools extension to be installed) --- .vscode/launch.json | 6 +- scripts/debugger-scripts-api.d.ts | 22 ++ scripts/hot-reload-injected-script.js | 267 ++++++++++++++++++ src/vs/base/common/hotReload.ts | 59 ++++ .../browser/widget/diffEditorWidget2/utils.ts | 36 +-- 5 files changed, 368 insertions(+), 22 deletions(-) create mode 100644 scripts/debugger-scripts-api.d.ts create mode 100644 scripts/hot-reload-injected-script.js create mode 100644 src/vs/base/common/hotReload.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index 3bea8e7c076..b2e25927a8a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -256,7 +256,11 @@ "browserLaunchLocation": "workspace", "presentation": { "hidden": true, - } + }, + // This is read by the vscode-diagnostic-tools extension + "vscode-diagnostic-tools.debuggerScripts": [ + "${workspaceFolder}/scripts/hot-reload-injected-script.js" + ] }, { "type": "node", diff --git a/scripts/debugger-scripts-api.d.ts b/scripts/debugger-scripts-api.d.ts new file mode 100644 index 00000000000..149912bc04f --- /dev/null +++ b/scripts/debugger-scripts-api.d.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +type RunFunction = ((debugSession: IDebugSession) => IDisposable) | ((debugSession: IDebugSession) => Promise); + +interface IDebugSession { + name: string; + eval(expression: string): Promise; + evalJs(bodyFn: (...args: T) => void, ...args: T): Promise; +} + +interface IDisposable { + dispose(): void; +} + +interface GlobalThisAddition extends globalThis { + $hotReload_applyNewExports?(oldExports: Record): AcceptNewExportsFn | undefined; +} + +type AcceptNewExportsFn = (newExports: Record) => boolean; diff --git a/scripts/hot-reload-injected-script.js b/scripts/hot-reload-injected-script.js new file mode 100644 index 00000000000..c6311f3b9c9 --- /dev/null +++ b/scripts/hot-reload-injected-script.js @@ -0,0 +1,267 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// @ts-check +/// + +const path = require('path'); +const fsPromise = require('fs/promises'); +const parcelWatcher = require('@parcel/watcher'); + +// This file is loaded by the vscode-diagnostic-tools extension and injected into the debugger. + +/** @type {RunFunction} */ +module.exports.run = async function (debugSession) { + const watcher = await DirWatcher.watchRecursively(path.join(__dirname, '../out/')); + + const sub = watcher.onDidChange(changes => { + const supportedChanges = changes.filter(c => c.path.endsWith('.js') || c.path.endsWith('.css')); + debugSession.evalJs(function (changes, debugSessionName) { + // This function is stringified and injected into the debuggee. + + /** @type {{ count: number; originalWindowTitle: any; timeout: any; shouldReload: boolean }} */ + const hotReloadData = globalThis.$hotReloadData || (globalThis.$hotReloadData = { count: 0, messageHideTimeout: undefined, shouldReload: false }); + + /** + * @param {string} path + * @param {string} newSrc + */ + function handleChange(path, newSrc) { + const relativePath = path.replace(/\\/g, '/').split('/out/')[1]; + if (relativePath.endsWith('.css')) { + handleCssChange(relativePath); + } else if (relativePath.endsWith('.js')) { + handleJsChange(relativePath, newSrc); + } + } + + /** + * @param {string} relativePath + */ + function handleCssChange(relativePath) { + if (typeof document === 'undefined') { + return; + } + + const styleSheet = (/** @type {HTMLLinkElement[]} */ ([...document.querySelectorAll(`link[rel='stylesheet']`)])) + .find(l => new URL(l.href, document.location.href).pathname.endsWith(relativePath)); + if (styleSheet) { + setMessage(`reload ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`); + console.log(debugSessionName, 'css reloaded', relativePath); + styleSheet.href = styleSheet.href.replace(/\?.*/, '') + '?' + Date.now(); + } else { + setMessage(`could not reload ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`); + console.log(debugSessionName, 'ignoring css change, as stylesheet is not loaded', relativePath); + } + } + + /** + * @param {string} relativePath + * @param {string} newSrc + */ + function handleJsChange(relativePath, newSrc) { + const moduleIdStr = trimEnd(relativePath, '.js'); + + /** @type {any} */ + const requireFn = globalThis.require; + const moduleManager = requireFn.moduleManager; + if (!moduleManager) { + console.log(debugSessionName, 'ignoring js change, as moduleManager is not available', relativePath); + return; + } + + const moduleId = moduleManager._moduleIdProvider.getModuleId(moduleIdStr); + const oldModule = moduleManager._modules2[moduleId]; + + if (!oldModule) { + console.log(debugSessionName, 'ignoring js change, as module is not loaded', relativePath); + return; + } + + // Check if we can reload + const g = /** @type {GlobalThisAddition} */ (globalThis); + + // A frozen copy of the previous exports + const oldExports = Object.freeze({ ...oldModule.exports }); + const reloadFn = g.$hotReload_applyNewExports?.(oldExports); + + if (!reloadFn) { + console.log(debugSessionName, 'ignoring js change, as module does not support hot-reload', relativePath); + hotReloadData.shouldReload = true; + setMessage(`hot reload not supported for ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`); + return; + } + + const newScript = new Function('define', newSrc); // CodeQL [SM01632] This code is only executed during development. It is required for the hot-reload functionality. + + newScript(/* define */ function (deps, callback) { + // Evaluating the new code was successful. + + // Redefine the module + delete moduleManager._modules2[moduleId]; + moduleManager.defineModule(moduleIdStr, deps, callback); + const newModule = moduleManager._modules2[moduleId]; + + + // Patch the exports of the old module, so that modules using the old module get the new exports + Object.assign(oldModule.exports, newModule.exports); + // We override the exports so that future reloads still patch the initial exports. + newModule.exports = oldModule.exports; + + const successful = reloadFn(newModule.exports); + if (!successful) { + hotReloadData.shouldReload = true; + setMessage(`hot reload failed ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`); + console.log(debugSessionName, 'hot reload was not successful', relativePath); + return; + } + + console.log(debugSessionName, 'hot reloaded', moduleIdStr); + setMessage(`successfully reloaded ${formatPath(relativePath)} - ${new Date().toLocaleTimeString()}`); + }); + } + + /** + * @param {string} message + */ + function setMessage(message) { + const domElem = /** @type {HTMLDivElement | undefined} */ (document.querySelector('.titlebar-center .window-title')); + if (!domElem) { return; } + if (!hotReloadData.timeout) { + hotReloadData.originalWindowTitle = domElem.innerText; + } else { + clearTimeout(hotReloadData.timeout); + } + if (hotReloadData.shouldReload) { + message += ' (manual reload required)'; + } + + domElem.innerText = message; + hotReloadData.timeout = setTimeout(() => { + hotReloadData.timeout = undefined; + // If wanted, we can restore the previous title message + // domElem.replaceChildren(hotReloadData.originalWindowTitle); + }, 5000); + } + + /** + * @param {string} path + * @returns {string} + */ + function formatPath(path) { + const parts = path.split('/'); + parts.reverse(); + let result = parts[0]; + parts.shift(); + for (const p of parts) { + if (result.length + p.length > 40) { + break; + } + result = p + '/' + result; + if (result.length > 20) { + break; + } + } + return result; + } + + function trimEnd(str, suffix) { + if (str.endsWith(suffix)) { + return str.substring(0, str.length - suffix.length); + } + return str; + } + + for (const change of changes) { + handleChange(change.path, change.newContent); + } + + }, supportedChanges, debugSession.name.substring(0, 25)); + }); + + return { + dispose() { + sub.dispose(); + watcher.dispose(); + } + }; +}; + +class DirWatcher { + /** + * + * @param {string} dir + * @returns {Promise} + */ + static async watchRecursively(dir) { + /** @type {((changes: { path: string, newContent: string }[]) => void)[]} */ + const listeners = []; + /** @type {Map } */ + const fileContents = new Map(); + /** @type {Map} */ + const changes = new Map(); + /** @type {(handler: (changes: { path: string, newContent: string }[]) => void) => IDisposable} */ + const event = (handler) => { + listeners.push(handler); + return { + dispose: () => { + const idx = listeners.indexOf(handler); + if (idx >= 0) { + listeners.splice(idx, 1); + } + } + }; + }; + const r = parcelWatcher.subscribe(dir, async (err, events) => { + for (const e of events) { + if (e.type === 'update') { + const newContent = await fsPromise.readFile(e.path, 'utf8'); + if (fileContents.get(e.path) !== newContent) { + fileContents.set(e.path, newContent); + changes.set(e.path, { path: e.path, newContent }); + } + } + } + if (changes.size > 0) { + debounce(() => { + const uniqueChanges = Array.from(changes.values()); + changes.clear(); + listeners.forEach(l => l(uniqueChanges)); + })(); + } + }); + const result = await r; + return new DirWatcher(event, () => result.unsubscribe()); + } + + /** + * @param {(handler: (changes: { path: string, newContent: string }[]) => void) => IDisposable} onDidChange + * @param {() => void} unsub + */ + constructor(onDidChange, unsub) { + this.onDidChange = onDidChange; + this.unsub = unsub; + } + + dispose() { + this.unsub(); + } +} + +/** + * Debounce function calls + * @param {() => void} fn + * @param {number} delay + */ +function debounce(fn, delay = 50) { + let timeoutId; + return function (...args) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + fn.apply(this, args); + }, delay); + }; +} + diff --git a/src/vs/base/common/hotReload.ts b/src/vs/base/common/hotReload.ts new file mode 100644 index 00000000000..17724907937 --- /dev/null +++ b/src/vs/base/common/hotReload.ts @@ -0,0 +1,59 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IDisposable } from 'vs/base/common/lifecycle'; +import { env } from 'vs/base/common/process'; + +export function isHotReloadEnabled(): boolean { + return !!env['VSCODE_DEV']; +} +export function registerHotReloadHandler(handler: HotReloadHandler): IDisposable { + if (!isHotReloadEnabled()) { + return { dispose() { } }; + } else { + const handlers = registerGlobalHotReloadHandler(); + + handlers.add(handler); + return { + dispose() { handlers.delete(handler); } + }; + } +} + +/** + * Takes the old exports of the module to reload and returns a function to apply the new exports. + * If `undefined` is returned, this handler is not able to handle the module. + * + * If no handler can apply the new exports, the module will not be reloaded. + */ +export type HotReloadHandler = (oldExports: Record) => AcceptNewExportsHandler | undefined; +export type AcceptNewExportsHandler = (newExports: Record) => boolean; + +function registerGlobalHotReloadHandler() { + if (!hotReloadHandlers) { + hotReloadHandlers = new Set(); + } + + const g = globalThis as unknown as GlobalThisAddition; + if (!g.$hotReload_applyNewExports) { + g.$hotReload_applyNewExports = oldExports => { + for (const h of hotReloadHandlers!) { + const result = h(oldExports); + if (result) { return result; } + } + return undefined; + }; + } + + return hotReloadHandlers; +} + +let hotReloadHandlers: Set<(oldExports: Record) => AcceptNewExportsFn | undefined> | undefined = undefined; + +interface GlobalThisAddition { + $hotReload_applyNewExports?(oldExports: Record): AcceptNewExportsFn | undefined; +} + +type AcceptNewExportsFn = (newExports: Record) => boolean; diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts index 8460b24326e..e2326b84447 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/utils.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { IDimension } from 'vs/base/browser/dom'; +import { isHotReloadEnabled, registerHotReloadHandler } from 'vs/base/common/hotReload'; import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { IObservable, IReader, ISettableObservable, autorun, autorunHandleChanges, autorunOpts, observableFromEvent, observableSignalFromEvent, observableValue, transaction } from 'vs/base/common/observable'; import { ElementSizeObserver } from 'vs/editor/browser/config/elementSizeObserver'; @@ -294,28 +295,21 @@ export function readHotReloadableExport(value: T, reader: IReader | undefined } export function observeHotReloadableExports(values: any[], reader: IReader | undefined): void { - const hotReload_deprecateExports = (globalThis as unknown as { - // This property it defined by the monaco editor playground server - $hotReload_deprecateExports: Set<(oldExports: Record, newExports: Record) => boolean>; - }).$hotReload_deprecateExports; - if (!hotReload_deprecateExports) { - return; + if (isHotReloadEnabled()) { + const o = observableSignalFromEvent( + 'reload', + event => registerHotReloadHandler(oldExports => { + if (![...Object.values(oldExports)].some(v => values.includes(v))) { + return undefined; + } + return (_newExports) => { + event(undefined); + return true; + }; + }) + ); + o.read(reader); } - - const o = observableSignalFromEvent('reload', e => { - function handleExports(oldExports: Record, _newExports: Record) { - if ([...Object.values(oldExports)].some(v => values.includes(v))) { - e(undefined); - return true; - } - return false; - } - hotReload_deprecateExports.add(handleExports); - return { - dispose() { hotReload_deprecateExports.delete(handleExports); } - }; - }); - o.read(reader); } export function applyViewZones(editor: ICodeEditor, viewZones: IObservable, setIsUpdating?: (isUpdatingViewZones: boolean) => void): IDisposable { From e424e83820568bd3a954182020a730fc2972da7a Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 1 Sep 2023 12:23:31 +0200 Subject: [PATCH 180/198] Diff Algorithm Cleanup --- src/vs/base/common/arrays.ts | 24 + src/vs/base/common/arraysFind.ts | 109 ++++ src/vs/base/test/common/arraysFind.test.ts | 58 +++ .../browser/services/editorWorkerService.ts | 9 +- .../editor/browser/widget/diffEditorWidget.ts | 16 +- .../diffEditorWidget2/accessibleDiffViewer.ts | 40 +- .../diffEditorDecorations.ts | 30 +- .../diffEditorWidget2/diffEditorViewModel.ts | 15 +- .../diffEditorWidget2/diffEditorWidget2.ts | 58 +-- .../inlineDiffDeletedCodeMargin.ts | 20 +- .../widget/diffEditorWidget2/lineAlignment.ts | 20 +- .../diffEditorWidget2/overviewRulerPart.ts | 4 +- .../widget/workerBasedDocumentDiffProvider.ts | 4 +- src/vs/editor/common/core/lineRange.ts | 222 ++++++--- src/vs/editor/common/core/offsetRange.ts | 8 + .../common/diff/advancedLinesDiffComputer.ts | 465 ++++++------------ .../common/diff/documentDiffProvider.ts | 5 +- .../common/diff/legacyLinesDiffComputer.ts | 27 +- .../editor/common/diff/linesDiffComputer.ts | 142 +----- src/vs/editor/common/diff/rangeMapping.ts | 133 +++++ .../common/services/editorSimpleWorker.ts | 7 +- .../standalone/browser/standaloneEditor.ts | 7 +- .../browser/widget/diffEditorWidget2.test.ts | 8 +- .../editor/test/common/core/lineRange.test.ts | 58 +++ .../diffing/advancedLinesDiffComputer.test.ts | 100 ++++ .../test/node/diffing/diffingFixture.test.ts | 8 +- .../node/diffing/lineRangeMapping.test.ts | 54 -- .../browser/inlineChatLivePreviewWidget.ts | 18 +- .../inlineChat/browser/inlineChatSession.ts | 10 +- .../browser/inlineChatStrategies.ts | 2 +- .../inlineChat/browser/inlineChatWidget.ts | 12 +- .../mergeEditor/browser/model/diffComputer.ts | 6 +- .../mergeEditor/test/browser/model.test.ts | 4 +- 33 files changed, 965 insertions(+), 738 deletions(-) create mode 100644 src/vs/base/common/arraysFind.ts create mode 100644 src/vs/base/test/common/arraysFind.test.ts create mode 100644 src/vs/editor/common/diff/rangeMapping.ts create mode 100644 src/vs/editor/test/common/core/lineRange.test.ts create mode 100644 src/vs/editor/test/node/diffing/advancedLinesDiffComputer.test.ts delete mode 100644 src/vs/editor/test/node/diffing/lineRangeMapping.test.ts diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index 94966dc1b6f..71bedc3a440 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -177,6 +177,30 @@ export function groupBy(data: ReadonlyArray, compare: (a: T, b: T) => numb return result; } +/** + * Splits the given items into a list of (non-empty) groups. + * `shouldBeGrouped` is used to decide if two consecutive items should be in the same group. + * The order of the items is preserved. + */ +export function* groupAdjacentBy(items: Iterable, shouldBeGrouped: (item1: T, item2: T) => boolean): Iterable { + let currentGroup: T[] | undefined; + let last: T | undefined; + for (const item of items) { + if (last !== undefined && shouldBeGrouped(last, item)) { + currentGroup!.push(item); + } else { + if (currentGroup) { + yield currentGroup; + } + currentGroup = [item]; + } + last = item; + } + if (currentGroup) { + yield currentGroup; + } +} + interface IMutableSplice extends ISplice { readonly toInsert: T[]; deleteCount: number; diff --git a/src/vs/base/common/arraysFind.ts b/src/vs/base/common/arraysFind.ts new file mode 100644 index 00000000000..91a1b710823 --- /dev/null +++ b/src/vs/base/common/arraysFind.ts @@ -0,0 +1,109 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/** + * Finds the last item where predicate is true using binary search. + * `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`! + * + * @returns `undefined` if no item matches, otherwise the last item that matches the predicate. + */ +export function findLastMonotonous(arr: T[], predicate: (item: T) => boolean): T | undefined { + const idx = findLastIdxMonotonous(arr, predicate); + return idx === -1 ? undefined : arr[idx]; +} + +/** + * Finds the last item where predicate is true using binary search. + * `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`! + * + * @returns `startIdx - 1` if predicate is false for all items, otherwise the index of the last item that matches the predicate. + */ +export function findLastIdxMonotonous(arr: T[], predicate: (item: T) => boolean, startIdx = 0, endIdxEx = arr.length): number { + let i = startIdx; + let j = endIdxEx; + while (i < j) { + const k = Math.floor((i + j) / 2); + if (predicate(arr[k])) { + i = k + 1; + } else { + j = k; + } + } + return i - 1; +} + + +/** + * Finds the first item where predicate is true using binary search. + * `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[false, ..., false, true, ..., true]`! + * + * @returns `undefined` if no item matches, otherwise the first item that matches the predicate. + */ +export function findFirstMonotonous(arr: T[], predicate: (item: T) => boolean): T | undefined { + const idx = findFirstIdxMonotonousOrArrLen(arr, predicate); + return idx === arr.length ? undefined : arr[idx]; +} + +/** + * Finds the first item where predicate is true using binary search. + * `predicate` must be monotonous, i.e. `arr.map(predicate)` must be like `[false, ..., false, true, ..., true]`! + * + * @returns `endIdxEx` if predicate is false for all items, otherwise the index of the first item that matches the predicate. + */ +export function findFirstIdxMonotonousOrArrLen(arr: T[], predicate: (item: T) => boolean, startIdx = 0, endIdxEx = arr.length): number { + let i = startIdx; + let j = endIdxEx; + while (i < j) { + const k = Math.floor((i + j) / 2); + if (predicate(arr[k])) { + j = k; + } else { + i = k + 1; + } + } + return i; +} + +export function findFirstIdxMonotonous(arr: T[], predicate: (item: T) => boolean, startIdx = 0, endIdxEx = arr.length): number { + const idx = findFirstIdxMonotonousOrArrLen(arr, predicate, startIdx, endIdxEx); + return idx === arr.length ? -1 : idx; +} + +/** + * Use this when + * * You have a sorted array + * * You query this array with a monotonous predicate to find the last item that has a certain property. + * * You query this array multiple times with monotonous predicates that get weaker and weaker. + */ +export class MonotonousArray { + public static assertInvariants = false; + + private _findLastMonotonousLastIdx = 0; + private _lastPredicate: ((item: T) => boolean) | undefined; + + constructor(private readonly _items: T[]) { + } + + /** + * The predicate must be monotonous, i.e. `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`! + * For subsequent calls, current predicate must be weaker than (or equal to) the previous predicate, i.e. more entries must be `true`. + */ + findLastMonotonous(predicate: (item: T) => boolean): T | undefined { + if (MonotonousArray.assertInvariants) { + if (this._lastPredicate) { + for (const item of this._items) { + if (this._lastPredicate(item) && !predicate(item)) { + throw new Error('MonotonousArray: current predicate must be weaker than (or equal to) the previous predicate.'); + } + } + } + this._lastPredicate = predicate; + } + + const idx = findLastIdxMonotonous(this._items, predicate, this._findLastMonotonousLastIdx); + this._findLastMonotonousLastIdx = idx + 1; + return idx === -1 ? undefined : this._items[idx]; + } +} diff --git a/src/vs/base/test/common/arraysFind.test.ts b/src/vs/base/test/common/arraysFind.test.ts new file mode 100644 index 00000000000..db9fcc44b82 --- /dev/null +++ b/src/vs/base/test/common/arraysFind.test.ts @@ -0,0 +1,58 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert = require('assert'); +import { MonotonousArray, findFirstMonotonous, findLastMonotonous } from 'vs/base/common/arraysFind'; + +suite('Arrays', () => { + test('findLastMonotonous', () => { + const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69]; + + const result = findLastMonotonous(array, n => n <= 60); + assert.strictEqual(result, 60); + + const result2 = findLastMonotonous(array, n => n <= 62); + assert.strictEqual(result2, 61); + + const result3 = findLastMonotonous(array, n => n <= 1); + assert.strictEqual(result3, 1); + + const result4 = findLastMonotonous(array, n => n <= 70); + assert.strictEqual(result4, 69); + + const result5 = findLastMonotonous(array, n => n <= 0); + assert.strictEqual(result5, undefined); + }); + + test('findFirstMonotonous', () => { + const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69]; + + const result = findFirstMonotonous(array, n => n >= 60); + assert.strictEqual(result, 60); + + const result2 = findFirstMonotonous(array, n => n >= 62); + assert.strictEqual(result2, 64); + + const result3 = findFirstMonotonous(array, n => n >= 1); + assert.strictEqual(result3, 1); + + const result4 = findFirstMonotonous(array, n => n >= 70); + assert.strictEqual(result4, undefined); + + const result5 = findFirstMonotonous(array, n => n >= 0); + assert.strictEqual(result5, 1); + }); + + test('MonotonousArray', () => { + const arr = new MonotonousArray([1, 4, 5, 7, 55, 59, 60, 61, 64, 69]); + assert.strictEqual(arr.findLastMonotonous(n => n <= 0), undefined); + assert.strictEqual(arr.findLastMonotonous(n => n <= 0), undefined); + assert.strictEqual(arr.findLastMonotonous(n => n <= 5), 5); + assert.strictEqual(arr.findLastMonotonous(n => n <= 6), 5); + assert.strictEqual(arr.findLastMonotonous(n => n <= 55), 55); + assert.strictEqual(arr.findLastMonotonous(n => n <= 60), 60); + assert.strictEqual(arr.findLastMonotonous(n => n <= 80), 69); + }); +}); diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index 993fe8e813c..5b411eeec3c 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -26,7 +26,8 @@ import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { IDocumentDiff, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { ILinesDiffComputerOptions, LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputerOptions, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping, RangeMapping, LineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { LineRange } from 'vs/editor/common/core/lineRange'; /** @@ -107,15 +108,15 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ quitEarly: result.quitEarly, changes: toLineRangeMappings(result.changes), moves: result.moves.map(m => new MovedText( - new SimpleLineRangeMapping(new LineRange(m[0], m[1]), new LineRange(m[2], m[3])), + new LineRangeMapping(new LineRange(m[0], m[1]), new LineRange(m[2], m[3])), toLineRangeMappings(m[4]) )) }; return diff; - function toLineRangeMappings(changes: readonly ILineChange[]): readonly LineRangeMapping[] { + function toLineRangeMappings(changes: readonly ILineChange[]): readonly DetailedLineRangeMapping[] { return changes.map( - (c) => new LineRangeMapping( + (c) => new DetailedLineRangeMapping( new LineRange(c[0], c[1]), new LineRange(c[2], c[3]), c[4]?.map( diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 62d42cee6aa..47dba6865b7 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -1212,24 +1212,24 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE let modifiedEndLineNumber: number; let innerChanges = m.innerChanges; - if (m.originalRange.isEmpty) { + if (m.original.isEmpty) { // Insertion - originalStartLineNumber = m.originalRange.startLineNumber - 1; + originalStartLineNumber = m.original.startLineNumber - 1; originalEndLineNumber = 0; innerChanges = undefined; } else { - originalStartLineNumber = m.originalRange.startLineNumber; - originalEndLineNumber = m.originalRange.endLineNumberExclusive - 1; + originalStartLineNumber = m.original.startLineNumber; + originalEndLineNumber = m.original.endLineNumberExclusive - 1; } - if (m.modifiedRange.isEmpty) { + if (m.modified.isEmpty) { // Deletion - modifiedStartLineNumber = m.modifiedRange.startLineNumber - 1; + modifiedStartLineNumber = m.modified.startLineNumber - 1; modifiedEndLineNumber = 0; innerChanges = undefined; } else { - modifiedStartLineNumber = m.modifiedRange.startLineNumber; - modifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive - 1; + modifiedStartLineNumber = m.modified.startLineNumber; + modifiedEndLineNumber = m.modified.endLineNumberExclusive - 1; } return { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts index 32f45d85186..ce188250447 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/accessibleDiffViewer.ts @@ -21,7 +21,7 @@ import { LineRange } from 'vs/editor/common/core/lineRange'; import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; -import { LineRangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping, LineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { ILanguageIdCodec } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; import { ITextModel, TextModelResolvedOptions } from 'vs/editor/common/model'; @@ -45,7 +45,7 @@ export class AccessibleDiffViewer extends Disposable { private readonly _canClose: IObservable, private readonly _width: IObservable, private readonly _height: IObservable, - private readonly _diffs: IObservable, + private readonly _diffs: IObservable, private readonly _editors: DiffEditorEditors, @IInstantiationService private readonly _instantiationService: IInstantiationService, ) { @@ -105,7 +105,7 @@ class ViewModel extends Disposable { = this._currentElementIdx.map((idx, r) => this.currentGroup.read(r)?.lines[idx]); constructor( - private readonly _diffs: IObservable, + private readonly _diffs: IObservable, private readonly _editors: DiffEditorEditors, private readonly _setVisible: (visible: boolean, tx: ITransaction | undefined) => void, public readonly canClose: IObservable, @@ -154,7 +154,7 @@ class ViewModel extends Disposable { // This ensures editor commands (like revert/stage) work const currentViewItem = this.currentElement.read(reader); if (currentViewItem && currentViewItem.type !== LineType.Header) { - const lineNumber = currentViewItem.modifiedLineNumber ?? currentViewItem.diff.modifiedRange.startLineNumber; + const lineNumber = currentViewItem.modifiedLineNumber ?? currentViewItem.diff.modified.startLineNumber; this._editors.modified.setSelection(Range.fromPositions(new Position(lineNumber, 1))); } })); @@ -221,44 +221,44 @@ class ViewModel extends Disposable { const viewElementGroupLineMargin = 3; -function computeViewElementGroups(diffs: LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): ViewElementGroup[] { +function computeViewElementGroups(diffs: DetailedLineRangeMapping[], originalLineCount: number, modifiedLineCount: number): ViewElementGroup[] { const result: ViewElementGroup[] = []; - for (const g of group(diffs, (a, b) => (b.modifiedRange.startLineNumber - a.modifiedRange.endLineNumberExclusive < 2 * viewElementGroupLineMargin))) { + for (const g of group(diffs, (a, b) => (b.modified.startLineNumber - a.modified.endLineNumberExclusive < 2 * viewElementGroupLineMargin))) { const viewElements: ViewElement[] = []; viewElements.push(new HeaderViewElement()); const origFullRange = new LineRange( - Math.max(1, g[0].originalRange.startLineNumber - viewElementGroupLineMargin), - Math.min(g[g.length - 1].originalRange.endLineNumberExclusive + viewElementGroupLineMargin, originalLineCount + 1) + Math.max(1, g[0].original.startLineNumber - viewElementGroupLineMargin), + Math.min(g[g.length - 1].original.endLineNumberExclusive + viewElementGroupLineMargin, originalLineCount + 1) ); const modifiedFullRange = new LineRange( - Math.max(1, g[0].modifiedRange.startLineNumber - viewElementGroupLineMargin), - Math.min(g[g.length - 1].modifiedRange.endLineNumberExclusive + viewElementGroupLineMargin, modifiedLineCount + 1) + Math.max(1, g[0].modified.startLineNumber - viewElementGroupLineMargin), + Math.min(g[g.length - 1].modified.endLineNumberExclusive + viewElementGroupLineMargin, modifiedLineCount + 1) ); forEachAdjacentItems(g, (a, b) => { - const origRange = new LineRange(a ? a.originalRange.endLineNumberExclusive : origFullRange.startLineNumber, b ? b.originalRange.startLineNumber : origFullRange.endLineNumberExclusive); - const modifiedRange = new LineRange(a ? a.modifiedRange.endLineNumberExclusive : modifiedFullRange.startLineNumber, b ? b.modifiedRange.startLineNumber : modifiedFullRange.endLineNumberExclusive); + const origRange = new LineRange(a ? a.original.endLineNumberExclusive : origFullRange.startLineNumber, b ? b.original.startLineNumber : origFullRange.endLineNumberExclusive); + const modifiedRange = new LineRange(a ? a.modified.endLineNumberExclusive : modifiedFullRange.startLineNumber, b ? b.modified.startLineNumber : modifiedFullRange.endLineNumberExclusive); origRange.forEach(origLineNumber => { viewElements.push(new UnchangedLineViewElement(origLineNumber, modifiedRange.startLineNumber + (origLineNumber - origRange.startLineNumber))); }); if (b) { - b.originalRange.forEach(origLineNumber => { + b.original.forEach(origLineNumber => { viewElements.push(new DeletedLineViewElement(b, origLineNumber)); }); - b.modifiedRange.forEach(modifiedLineNumber => { + b.modified.forEach(modifiedLineNumber => { viewElements.push(new AddedLineViewElement(b, modifiedLineNumber)); }); } }); - const modifiedRange = g[0].modifiedRange.join(g[g.length - 1].modifiedRange); - const originalRange = g[0].originalRange.join(g[g.length - 1].originalRange); + const modifiedRange = g[0].modified.join(g[g.length - 1].modified); + const originalRange = g[0].original.join(g[g.length - 1].original); - result.push(new ViewElementGroup(new SimpleLineRangeMapping(modifiedRange, originalRange), viewElements)); + result.push(new ViewElementGroup(new LineRangeMapping(modifiedRange, originalRange), viewElements)); } return result; } @@ -272,7 +272,7 @@ enum LineType { class ViewElementGroup { constructor( - public readonly range: SimpleLineRangeMapping, + public readonly range: LineRangeMapping, public readonly lines: readonly ViewElement[], ) { } } @@ -289,7 +289,7 @@ class DeletedLineViewElement { public readonly modifiedLineNumber = undefined; constructor( - public readonly diff: LineRangeMapping, + public readonly diff: DetailedLineRangeMapping, public readonly originalLineNumber: number, ) { } @@ -301,7 +301,7 @@ class AddedLineViewElement { public readonly originalLineNumber = undefined; constructor( - public readonly diff: LineRangeMapping, + public readonly diff: DetailedLineRangeMapping, public readonly modifiedLineNumber: number, ) { } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts index 9a4b5bcf094..504bfe8a12c 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorDecorations.ts @@ -42,45 +42,45 @@ export class DiffEditorDecorations extends Disposable { const modifiedDecorations: IModelDeltaDecoration[] = []; if (!movedTextToCompare) { for (const m of diff.mappings) { - if (!m.lineRangeMapping.originalRange.isEmpty) { - originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); + if (!m.lineRangeMapping.original.isEmpty) { + originalDecorations.push({ range: m.lineRangeMapping.original.toInclusiveRange()!, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); } - if (!m.lineRangeMapping.modifiedRange.isEmpty) { - modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); + if (!m.lineRangeMapping.modified.isEmpty) { + modifiedDecorations.push({ range: m.lineRangeMapping.modified.toInclusiveRange()!, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); } - if (m.lineRangeMapping.modifiedRange.isEmpty || m.lineRangeMapping.originalRange.isEmpty) { - if (!m.lineRangeMapping.originalRange.isEmpty) { - originalDecorations.push({ range: m.lineRangeMapping.originalRange.toInclusiveRange()!, options: diffWholeLineDeleteDecoration }); + if (m.lineRangeMapping.modified.isEmpty || m.lineRangeMapping.original.isEmpty) { + if (!m.lineRangeMapping.original.isEmpty) { + originalDecorations.push({ range: m.lineRangeMapping.original.toInclusiveRange()!, options: diffWholeLineDeleteDecoration }); } - if (!m.lineRangeMapping.modifiedRange.isEmpty) { - modifiedDecorations.push({ range: m.lineRangeMapping.modifiedRange.toInclusiveRange()!, options: diffWholeLineAddDecoration }); + if (!m.lineRangeMapping.modified.isEmpty) { + modifiedDecorations.push({ range: m.lineRangeMapping.modified.toInclusiveRange()!, options: diffWholeLineAddDecoration }); } } else { for (const i of m.lineRangeMapping.innerChanges || []) { // Don't show empty markers outside the line range - if (m.lineRangeMapping.originalRange.contains(i.originalRange.startLineNumber)) { + if (m.lineRangeMapping.original.contains(i.originalRange.startLineNumber)) { originalDecorations.push({ range: i.originalRange, options: (i.originalRange.isEmpty() && showEmptyDecorations) ? diffDeleteDecorationEmpty : diffDeleteDecoration }); } - if (m.lineRangeMapping.modifiedRange.contains(i.modifiedRange.startLineNumber)) { + if (m.lineRangeMapping.modified.contains(i.modifiedRange.startLineNumber)) { modifiedDecorations.push({ range: i.modifiedRange, options: (i.modifiedRange.isEmpty() && showEmptyDecorations) ? diffAddDecorationEmpty : diffAddDecoration }); } } } - if (!m.lineRangeMapping.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !movedTextToCompare) { - modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modifiedRange.startLineNumber, 1)), options: arrowRevertChange }); + if (!m.lineRangeMapping.modified.isEmpty && this._options.shouldRenderRevertArrows.read(reader) && !movedTextToCompare) { + modifiedDecorations.push({ range: Range.fromPositions(new Position(m.lineRangeMapping.modified.startLineNumber, 1)), options: arrowRevertChange }); } } } if (movedTextToCompare) { for (const m of movedTextToCompare.changes) { - const fullRangeOriginal = m.originalRange.toInclusiveRange(); + const fullRangeOriginal = m.original.toInclusiveRange(); if (fullRangeOriginal) { originalDecorations.push({ range: fullRangeOriginal, options: renderIndicators ? diffLineDeleteDecorationBackgroundWithIndicator : diffLineDeleteDecorationBackground }); } - const fullRangeModified = m.modifiedRange.toInclusiveRange(); + const fullRangeModified = m.modified.toInclusiveRange(); if (fullRangeModified) { modifiedDecorations.push({ range: fullRangeModified, options: renderIndicators ? diffLineAddDecorationBackgroundWithIndicator : diffLineAddDecorationBackground }); } diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts index 860afa96659..143b1834b66 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel.ts @@ -11,7 +11,8 @@ import { readHotReloadableExport } from 'vs/editor/browser/widget/diffEditorWidg import { ISerializedLineRange, LineRange } from 'vs/editor/common/core/lineRange'; import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; import { IDocumentDiff, IDocumentDiffProvider } from 'vs/editor/common/diff/documentDiffProvider'; -import { LineRangeMapping, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { IDiffEditorModel, IDiffEditorViewModel } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { TextEditInfo } from 'vs/editor/common/model/bracketPairsTextModelPart/bracketPairsTree/beforeEditPositionMapper'; @@ -293,7 +294,7 @@ export class DiffState { export class DiffMapping { constructor( - readonly lineRangeMapping: LineRangeMapping, + readonly lineRangeMapping: DetailedLineRangeMapping, ) { /* readonly movedTo: MovedText | undefined, @@ -318,19 +319,19 @@ export class DiffMapping { export class UnchangedRegion { public static fromDiffs( - changes: readonly LineRangeMapping[], + changes: readonly DetailedLineRangeMapping[], originalLineCount: number, modifiedLineCount: number, minHiddenLineCount: number, minContext: number, ): UnchangedRegion[] { - const inversedMappings = LineRangeMapping.inverse(changes, originalLineCount, modifiedLineCount); + const inversedMappings = DetailedLineRangeMapping.inverse(changes, originalLineCount, modifiedLineCount); const result: UnchangedRegion[] = []; for (const mapping of inversedMappings) { - let origStart = mapping.originalRange.startLineNumber; - let modStart = mapping.modifiedRange.startLineNumber; - let length = mapping.originalRange.length; + let origStart = mapping.original.startLineNumber; + let modStart = mapping.modified.startLineNumber; + let length = mapping.original.length; const atStart = origStart === 1 && modStart === 1; const atEnd = origStart + length === originalLineCount + 1 && modStart + length === modifiedLineCount + 1; diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts index 9d5047da806..94af3098934 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2.ts @@ -29,7 +29,7 @@ import { IDimension } from 'vs/editor/common/core/dimension'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; import { CursorChangeReason } from 'vs/editor/common/cursorEvents'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { EditorType, IDiffEditorModel, IDiffEditorViewModel, IDiffEditorViewState } from 'vs/editor/common/editorCommon'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; @@ -248,8 +248,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { const diffs = model.diff.get()?.mappings; if (!diffs) { return; } const diff = diffs.find(d => - viewZone?.detail.afterLineNumber === d.lineRangeMapping.modifiedRange.startLineNumber - 1 || - d.lineRangeMapping.modifiedRange.startLineNumber === lineNumber + viewZone?.detail.afterLineNumber === d.lineRangeMapping.modified.startLineNumber - 1 || + d.lineRangeMapping.modified.startLineNumber === lineNumber ); if (!diff) { return; } this.revert(diff.lineRangeMapping); @@ -260,10 +260,10 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { this._register(Event.runAndSubscribe(this._editors.modified.onDidChangeCursorPosition, (e) => { if (e?.reason === CursorChangeReason.Explicit) { - const diff = this._diffModel.get()?.diff.get()?.mappings.find(m => m.lineRangeMapping.modifiedRange.contains(e.position.lineNumber)); - if (diff?.lineRangeMapping.modifiedRange.isEmpty) { + const diff = this._diffModel.get()?.diff.get()?.mappings.find(m => m.lineRangeMapping.modified.contains(e.position.lineNumber)); + if (diff?.lineRangeMapping.modified.isEmpty) { this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { source: 'diffEditor.cursorPositionChanged' }); - } else if (diff?.lineRangeMapping.originalRange.isEmpty) { + } else if (diff?.lineRangeMapping.original.isEmpty) { this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { source: 'diffEditor.cursorPositionChanged' }); } else if (diff) { this._audioCueService.playAudioCue(AudioCue.diffLineModified, { source: 'diffEditor.cursorPositionChanged' }); @@ -436,7 +436,7 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { }; } - revert(diff: LineRangeMapping): void { + revert(diff: DetailedLineRangeMapping): void { const model = this._diffModel.get()?.model; if (!model) { return; } @@ -447,8 +447,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { })) : [ { - range: diff.modifiedRange.toExclusiveRange(), - text: model.original.getValueInRange(diff.originalRange.toExclusiveRange()) + range: diff.modified.toExclusiveRange(), + text: model.original.getValueInRange(diff.original.toExclusiveRange()) } ]; @@ -456,8 +456,8 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { } private _goTo(diff: DiffMapping): void { - this._editors.modified.setPosition(new Position(diff.lineRangeMapping.modifiedRange.startLineNumber, 1)); - this._editors.modified.revealRangeInCenter(diff.lineRangeMapping.modifiedRange.toExclusiveRange()); + this._editors.modified.setPosition(new Position(diff.lineRangeMapping.modified.startLineNumber, 1)); + this._editors.modified.revealRangeInCenter(diff.lineRangeMapping.modified.toExclusiveRange()); } goToDiff(target: 'previous' | 'next'): void { @@ -470,15 +470,15 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { let diff: DiffMapping | undefined; if (target === 'next') { - diff = diffs.find(d => d.lineRangeMapping.modifiedRange.startLineNumber > curLineNumber) ?? diffs[0]; + diff = diffs.find(d => d.lineRangeMapping.modified.startLineNumber > curLineNumber) ?? diffs[0]; } else { - diff = findLast(diffs, d => d.lineRangeMapping.modifiedRange.startLineNumber < curLineNumber) ?? diffs[diffs.length - 1]; + diff = findLast(diffs, d => d.lineRangeMapping.modified.startLineNumber < curLineNumber) ?? diffs[diffs.length - 1]; } this._goTo(diff); - if (diff.lineRangeMapping.modifiedRange.isEmpty) { + if (diff.lineRangeMapping.modified.isEmpty) { this._audioCueService.playAudioCue(AudioCue.diffLineDeleted, { source: 'diffEditor.goToDiff' }); - } else if (diff.lineRangeMapping.originalRange.isEmpty) { + } else if (diff.lineRangeMapping.original.isEmpty) { this._audioCueService.playAudioCue(AudioCue.diffLineInserted, { source: 'diffEditor.goToDiff' }); } else if (diff) { this._audioCueService.playAudioCue(AudioCue.diffLineModified, { source: 'diffEditor.goToDiff' }); @@ -564,26 +564,26 @@ export class DiffEditorWidget2 extends DelegatingEditor implements IDiffEditor { } } -function translatePosition(posInOriginal: Position, mappings: LineRangeMapping[]): Range { - const mapping = findLast(mappings, m => m.originalRange.startLineNumber <= posInOriginal.lineNumber); +function translatePosition(posInOriginal: Position, mappings: DetailedLineRangeMapping[]): Range { + const mapping = findLast(mappings, m => m.original.startLineNumber <= posInOriginal.lineNumber); if (!mapping) { // No changes before the position return Range.fromPositions(posInOriginal); } - if (mapping.originalRange.endLineNumberExclusive <= posInOriginal.lineNumber) { - const newLineNumber = posInOriginal.lineNumber - mapping.originalRange.endLineNumberExclusive + mapping.modifiedRange.endLineNumberExclusive; + if (mapping.original.endLineNumberExclusive <= posInOriginal.lineNumber) { + const newLineNumber = posInOriginal.lineNumber - mapping.original.endLineNumberExclusive + mapping.modified.endLineNumberExclusive; return Range.fromPositions(new Position(newLineNumber, posInOriginal.column)); } if (!mapping.innerChanges) { // Only for legacy algorithm - return Range.fromPositions(new Position(mapping.modifiedRange.startLineNumber, 1)); + return Range.fromPositions(new Position(mapping.modified.startLineNumber, 1)); } const innerMapping = findLast(mapping.innerChanges, m => m.originalRange.getStartPosition().isBeforeOrEqual(posInOriginal)); if (!innerMapping) { - const newLineNumber = posInOriginal.lineNumber - mapping.originalRange.startLineNumber + mapping.modifiedRange.startLineNumber; + const newLineNumber = posInOriginal.lineNumber - mapping.original.startLineNumber + mapping.modified.startLineNumber; return Range.fromPositions(new Position(newLineNumber, posInOriginal.column)); } @@ -620,24 +620,24 @@ function toLineChanges(state: DiffState): ILineChange[] { let modifiedEndLineNumber: number; let innerChanges = m.innerChanges; - if (m.originalRange.isEmpty) { + if (m.original.isEmpty) { // Insertion - originalStartLineNumber = m.originalRange.startLineNumber - 1; + originalStartLineNumber = m.original.startLineNumber - 1; originalEndLineNumber = 0; innerChanges = undefined; } else { - originalStartLineNumber = m.originalRange.startLineNumber; - originalEndLineNumber = m.originalRange.endLineNumberExclusive - 1; + originalStartLineNumber = m.original.startLineNumber; + originalEndLineNumber = m.original.endLineNumberExclusive - 1; } - if (m.modifiedRange.isEmpty) { + if (m.modified.isEmpty) { // Deletion - modifiedStartLineNumber = m.modifiedRange.startLineNumber - 1; + modifiedStartLineNumber = m.modified.startLineNumber - 1; modifiedEndLineNumber = 0; innerChanges = undefined; } else { - modifiedStartLineNumber = m.modifiedRange.startLineNumber; - modifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive - 1; + modifiedStartLineNumber = m.modified.startLineNumber; + modifiedEndLineNumber = m.modified.endLineNumberExclusive - 1; } return { diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/inlineDiffDeletedCodeMargin.ts b/src/vs/editor/browser/widget/diffEditorWidget2/inlineDiffDeletedCodeMargin.ts index 5aca1405d41..f5b3ff67e26 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/inlineDiffDeletedCodeMargin.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/inlineDiffDeletedCodeMargin.ts @@ -13,7 +13,7 @@ import { IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrow import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { DiffEditorWidget2 } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorWidget2'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { EndOfLineSequence, ITextModel } from 'vs/editor/common/model'; import { localize } from 'vs/nls'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; @@ -39,7 +39,7 @@ export class InlineDiffDeletedCodeMargin extends Disposable { private readonly _getViewZoneId: () => string, private readonly _marginDomNode: HTMLElement, private readonly _modifiedEditor: CodeEditorWidget, - private readonly _diff: LineRangeMapping, + private readonly _diff: DetailedLineRangeMapping, private readonly _editor: DiffEditorWidget2, private readonly _viewLineCounts: number[], private readonly _originalTextModel: ITextModel, @@ -70,38 +70,38 @@ export class InlineDiffDeletedCodeMargin extends Disposable { getAnchor: () => ({ x, y }), getActions: () => { const actions: Action[] = []; - const isDeletion = _diff.modifiedRange.isEmpty; + const isDeletion = _diff.modified.isEmpty; // default action actions.push(new Action( 'diff.clipboard.copyDeletedContent', isDeletion - ? (_diff.originalRange.length > 1 + ? (_diff.original.length > 1 ? localize('diff.clipboard.copyDeletedLinesContent.label', "Copy deleted lines") : localize('diff.clipboard.copyDeletedLinesContent.single.label', "Copy deleted line")) - : (_diff.originalRange.length > 1 + : (_diff.original.length > 1 ? localize('diff.clipboard.copyChangedLinesContent.label', "Copy changed lines") : localize('diff.clipboard.copyChangedLinesContent.single.label', "Copy changed line")), undefined, true, async () => { - const originalText = this._originalTextModel.getValueInRange(_diff.originalRange.toExclusiveRange()); + const originalText = this._originalTextModel.getValueInRange(_diff.original.toExclusiveRange()); await this._clipboardService.writeText(originalText); } )); - if (_diff.originalRange.length > 1) { + if (_diff.original.length > 1) { actions.push(new Action( 'diff.clipboard.copyDeletedLineContent', isDeletion ? localize('diff.clipboard.copyDeletedLineContent.label', "Copy deleted line ({0})", - _diff.originalRange.startLineNumber + currentLineNumberOffset) + _diff.original.startLineNumber + currentLineNumberOffset) : localize('diff.clipboard.copyChangedLineContent.label', "Copy changed line ({0})", - _diff.originalRange.startLineNumber + currentLineNumberOffset), + _diff.original.startLineNumber + currentLineNumberOffset), undefined, true, async () => { - let lineContent = this._originalTextModel.getLineContent(_diff.originalRange.startLineNumber + currentLineNumberOffset); + let lineContent = this._originalTextModel.getLineContent(_diff.original.startLineNumber + currentLineNumberOffset); if (lineContent === '') { // empty line -> new line const eof = this._originalTextModel.getEndOfLineSequence(); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts index 56357753f62..32d34563d46 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/lineAlignment.ts @@ -25,7 +25,7 @@ import { animatedObservable, joinCombine } from 'vs/editor/browser/widget/diffEd import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { Position } from 'vs/editor/common/core/position'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { BackgroundTokenizationState } from 'vs/editor/common/tokenizationTextModelPart'; import { InlineDecoration, InlineDecorationType } from 'vs/editor/common/viewModel'; @@ -193,7 +193,7 @@ export class ViewZoneManager extends Disposable { const decorations: InlineDecoration[] = []; for (const i of a.diff.innerChanges || []) { decorations.push(new InlineDecoration( - i.originalRange.delta(-(a.diff.originalRange.startLineNumber - 1)), + i.originalRange.delta(-(a.diff.original.startLineNumber - 1)), diffDeleteDecoration.className!, InlineDecorationType.Regular )); @@ -287,7 +287,7 @@ export class ViewZoneManager extends Disposable { } let marginDomNode: HTMLElement | undefined = undefined; - if (a.diff && a.diff.modifiedRange.isEmpty && this._options.shouldRenderRevertArrows.read(reader)) { + if (a.diff && a.diff.modified.isEmpty && this._options.shouldRenderRevertArrows.read(reader)) { marginDomNode = createViewZoneMarginArrow(); } @@ -472,7 +472,7 @@ interface ILineRangeAlignment { * If this range alignment is a direct result of a diff, then this is the diff's line mapping. * Only used for inline-view. */ - diff?: LineRangeMapping; + diff?: DetailedLineRangeMapping; } function computeRangeAlignment( @@ -540,11 +540,11 @@ function computeRangeAlignment( for (const m of diffs) { const c = m.lineRangeMapping; - handleAlignmentsOutsideOfDiffs(c.originalRange.startLineNumber, c.modifiedRange.startLineNumber); + handleAlignmentsOutsideOfDiffs(c.original.startLineNumber, c.modified.startLineNumber); let first = true; - let lastModLineNumber = c.modifiedRange.startLineNumber; - let lastOrigLineNumber = c.originalRange.startLineNumber; + let lastModLineNumber = c.modified.startLineNumber; + let lastOrigLineNumber = c.original.startLineNumber; function emitAlignment(origLineNumberExclusive: number, modLineNumberExclusive: number) { if (origLineNumberExclusive < lastOrigLineNumber || modLineNumberExclusive < lastModLineNumber) { @@ -593,10 +593,10 @@ function computeRangeAlignment( } } - emitAlignment(c.originalRange.endLineNumberExclusive, c.modifiedRange.endLineNumberExclusive); + emitAlignment(c.original.endLineNumberExclusive, c.modified.endLineNumberExclusive); - lastOriginalLineNumber = c.originalRange.endLineNumberExclusive; - lastModifiedLineNumber = c.modifiedRange.endLineNumberExclusive; + lastOriginalLineNumber = c.original.endLineNumberExclusive; + lastModifiedLineNumber = c.modified.endLineNumberExclusive; } handleAlignmentsOutsideOfDiffs(Number.MAX_VALUE, Number.MAX_VALUE); diff --git a/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts b/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts index 8996560b36a..bd93df81567 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget2/overviewRulerPart.ts @@ -127,8 +127,8 @@ export class OverviewRulerPart extends Disposable { }); } - const originalZones = createZones((diff || []).map(d => d.lineRangeMapping.originalRange), colors.removeColor, this._editors.original); - const modifiedZones = createZones((diff || []).map(d => d.lineRangeMapping.modifiedRange), colors.insertColor, this._editors.modified); + const originalZones = createZones((diff || []).map(d => d.lineRangeMapping.original), colors.removeColor, this._editors.original); + const modifiedZones = createZones((diff || []).map(d => d.lineRangeMapping.modified), colors.insertColor, this._editors.modified); originalOverviewRuler?.setZones(originalZones); modifiedOverviewRuler?.setZones(modifiedZones); })); diff --git a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts index 02d3c157aa6..79d7bacac9f 100644 --- a/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts +++ b/src/vs/editor/browser/widget/workerBasedDocumentDiffProvider.ts @@ -9,7 +9,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { StopWatch } from 'vs/base/common/stopwatch'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { IDocumentDiff, IDocumentDiffProvider, IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; -import { LineRangeMapping, RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping, RangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { ITextModel } from 'vs/editor/common/model'; import { DiffAlgorithmName, IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -53,7 +53,7 @@ export class WorkerBasedDocumentDiffProvider implements IDocumentDiffProvider, I return { changes: [ - new LineRangeMapping( + new DetailedLineRangeMapping( new LineRange(1, 2), new LineRange(1, modified.getLineCount() + 1), [ diff --git a/src/vs/editor/common/core/lineRange.ts b/src/vs/editor/common/core/lineRange.ts index 70acb0476d6..3bf932cac4d 100644 --- a/src/vs/editor/common/core/lineRange.ts +++ b/src/vs/editor/common/core/lineRange.ts @@ -6,6 +6,7 @@ import { BugIndicatingError } from 'vs/base/common/errors'; import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Range } from 'vs/editor/common/core/range'; +import { findFirstIdxMonotonousOrArrLen, findLastIdxMonotonous, findLastMonotonous } from 'vs/base/common/arraysFind'; /** * A range of lines (1-based). @@ -40,66 +41,11 @@ export class LineRange { if (lineRanges.length === 0) { return []; } - let result = lineRanges[0]; + let result = new LineRangeSet(lineRanges[0].slice()); for (let i = 1; i < lineRanges.length; i++) { - result = this.join(result, lineRanges[i]); + result = result.getUnion(new LineRangeSet(lineRanges[i].slice())); } - return result; - } - - /** - * @param lineRanges1 Must be sorted. - * @param lineRanges2 Must be sorted. - */ - public static join(lineRanges1: readonly LineRange[], lineRanges2: readonly LineRange[]): readonly LineRange[] { - if (lineRanges1.length === 0) { - return lineRanges2; - } - if (lineRanges2.length === 0) { - return lineRanges1; - } - - const result: LineRange[] = []; - let i1 = 0; - let i2 = 0; - let current: LineRange | null = null; - while (i1 < lineRanges1.length || i2 < lineRanges2.length) { - let next: LineRange | null = null; - if (i1 < lineRanges1.length && i2 < lineRanges2.length) { - const lineRange1 = lineRanges1[i1]; - const lineRange2 = lineRanges2[i2]; - if (lineRange1.startLineNumber < lineRange2.startLineNumber) { - next = lineRange1; - i1++; - } else { - next = lineRange2; - i2++; - } - } else if (i1 < lineRanges1.length) { - next = lineRanges1[i1]; - i1++; - } else { - next = lineRanges2[i2]; - i2++; - } - - if (current === null) { - current = next; - } else { - if (current.endLineNumberExclusive >= next.startLineNumber) { - // merge - current = new LineRange(current.startLineNumber, Math.max(current.endLineNumberExclusive, next.endLineNumberExclusive)); - } else { - // push - result.push(current); - current = next; - } - } - } - if (current !== null) { - result.push(current); - } - return result; + return result.ranges; } public static ofLength(startLineNumber: number, length: number): LineRange { @@ -251,3 +197,163 @@ export class LineRange { } export type ISerializedLineRange = [startLineNumber: number, endLineNumberExclusive: number]; + + +export class LineRangeSet { + constructor( + /** + * Sorted by start line number. + * No two line ranges are touching or intersecting. + */ + private readonly _normalizedRanges: LineRange[] = [] + ) { + } + + get ranges(): readonly LineRange[] { + return this._normalizedRanges; + } + + addRange(range: LineRange): void { + if (range.length === 0) { + return; + } + + // Idea: Find joinRange such that: + // replaceRange = _normalizedRanges.replaceRange(joinRange, range.joinAll(joinRange.map(idx => this._normalizedRanges[idx]))) + + // idx of first element that touches range or that is after range + const joinRangeStartIdx = findFirstIdxMonotonousOrArrLen(this._normalizedRanges, r => r.endLineNumberExclusive >= range.startLineNumber); + // idx of element after { last element that touches range or that is before range } + const joinRangeEndIdxExclusive = findLastIdxMonotonous(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1; + + if (joinRangeStartIdx === joinRangeEndIdxExclusive) { + // If there is no element that touches range, then joinRangeStartIdx === joinRangeEndIdxExclusive and that value is the index of the element after range + this._normalizedRanges.splice(joinRangeStartIdx, 0, range); + } else if (joinRangeStartIdx === joinRangeEndIdxExclusive - 1) { + // Else, there is an element that touches range and in this case it is both the first and last element. Thus we can replace it + const joinRange = this._normalizedRanges[joinRangeStartIdx]; + this._normalizedRanges[joinRangeStartIdx] = joinRange.join(range); + } else { + // First and last element are different - we need to replace the entire range + const joinRange = this._normalizedRanges[joinRangeStartIdx].join(this._normalizedRanges[joinRangeEndIdxExclusive - 1]).join(range); + this._normalizedRanges.splice(joinRangeStartIdx, joinRangeEndIdxExclusive - joinRangeStartIdx, joinRange); + } + } + + intersects(range: LineRange): boolean { + const rangeThatStartsBeforeEnd = findLastMonotonous(this._normalizedRanges, r => r.startLineNumber < range.endLineNumberExclusive); + return !!rangeThatStartsBeforeEnd && rangeThatStartsBeforeEnd.endLineNumberExclusive > range.startLineNumber; + } + + getUnion(other: LineRangeSet): LineRangeSet { + if (this._normalizedRanges.length === 0) { + return other; + } + if (other._normalizedRanges.length === 0) { + return this; + } + + const result: LineRange[] = []; + let i1 = 0; + let i2 = 0; + let current: LineRange | null = null; + while (i1 < this._normalizedRanges.length || i2 < other._normalizedRanges.length) { + let next: LineRange | null = null; + if (i1 < this._normalizedRanges.length && i2 < other._normalizedRanges.length) { + const lineRange1 = this._normalizedRanges[i1]; + const lineRange2 = other._normalizedRanges[i2]; + if (lineRange1.startLineNumber < lineRange2.startLineNumber) { + next = lineRange1; + i1++; + } else { + next = lineRange2; + i2++; + } + } else if (i1 < this._normalizedRanges.length) { + next = this._normalizedRanges[i1]; + i1++; + } else { + next = other._normalizedRanges[i2]; + i2++; + } + + if (current === null) { + current = next; + } else { + if (current.endLineNumberExclusive >= next.startLineNumber) { + // merge + current = new LineRange(current.startLineNumber, Math.max(current.endLineNumberExclusive, next.endLineNumberExclusive)); + } else { + // push + result.push(current); + current = next; + } + } + } + if (current !== null) { + result.push(current); + } + return new LineRangeSet(result); + } + + /** + * Subtracts all ranges in this set from `range` and returns the result. + */ + subtractFrom(range: LineRange): LineRangeSet { + // idx of first element that touches range or that is after range + const joinRangeStartIdx = findFirstIdxMonotonousOrArrLen(this._normalizedRanges, r => r.endLineNumberExclusive >= range.startLineNumber); + // idx of element after { last element that touches range or that is before range } + const joinRangeEndIdxExclusive = findLastIdxMonotonous(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1; + + if (joinRangeStartIdx === joinRangeEndIdxExclusive) { + return new LineRangeSet([range]); + } + + const result: LineRange[] = []; + let startLineNumber = range.startLineNumber; + for (let i = joinRangeStartIdx; i < joinRangeEndIdxExclusive; i++) { + const r = this._normalizedRanges[i]; + if (r.startLineNumber > startLineNumber) { + result.push(new LineRange(startLineNumber, r.startLineNumber)); + } + startLineNumber = r.endLineNumberExclusive; + } + if (startLineNumber < range.endLineNumberExclusive) { + result.push(new LineRange(startLineNumber, range.endLineNumberExclusive)); + } + + return new LineRangeSet(result); + } + + toString() { + return this._normalizedRanges.map(r => r.toString()).join(', '); + } + + getIntersection(other: LineRangeSet): LineRangeSet { + const result: LineRange[] = []; + + let i1 = 0; + let i2 = 0; + while (i1 < this._normalizedRanges.length && i2 < other._normalizedRanges.length) { + const r1 = this._normalizedRanges[i1]; + const r2 = other._normalizedRanges[i2]; + + const i = r1.intersect(r2); + if (i && !i.isEmpty) { + result.push(i); + } + + if (r1.endLineNumberExclusive < r2.endLineNumberExclusive) { + i1++; + } else { + i2++; + } + } + + return new LineRangeSet(result); + } + + getWithDelta(value: number): LineRangeSet { + return new LineRangeSet(this._normalizedRanges.map(r => r.delta(value))); + } +} diff --git a/src/vs/editor/common/core/offsetRange.ts b/src/vs/editor/common/core/offsetRange.ts index 27e60bca2df..9173e5339bb 100644 --- a/src/vs/editor/common/core/offsetRange.ts +++ b/src/vs/editor/common/core/offsetRange.ts @@ -136,6 +136,14 @@ export class OffsetRange { } return value; } + + public map(f: (offset: number) => T): T[] { + const result: T[] = []; + for (let i = this.start; i < this.endExclusive; i++) { + result.push(f(i)); + } + return result; + } } export class OffsetRangeSet { diff --git a/src/vs/editor/common/diff/advancedLinesDiffComputer.ts b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts index 55166f1ad82..8720d8524ba 100644 --- a/src/vs/editor/common/diff/advancedLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/advancedLinesDiffComputer.ts @@ -3,12 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Comparator, CompareResult, compareBy, equals, findLastIndex, numberComparator, reverseOrder } from 'vs/base/common/arrays'; +import { compareBy, equals, groupAdjacentBy, numberComparator, pushMany, reverseOrder } from 'vs/base/common/arrays'; import { assertFn, checkAdjacentItems } from 'vs/base/common/assert'; import { CharCode } from 'vs/base/common/charCode'; import { SetMap } from 'vs/base/common/collections'; -import { BugIndicatingError } from 'vs/base/common/errors'; -import { LineRange } from 'vs/editor/common/core/lineRange'; +import { LineRange, LineRangeSet } from 'vs/editor/common/core/lineRange'; import { OffsetRange } from 'vs/editor/common/core/offsetRange'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; @@ -16,7 +15,9 @@ import { DateTimeout, ISequence, ITimeout, InfiniteTimeout, SequenceDiff } from import { DynamicProgrammingDiffing } from 'vs/editor/common/diff/algorithms/dynamicProgrammingDiffing'; import { optimizeSequenceDiffs, removeRandomLineMatches, removeRandomMatches, smoothenSequenceDiffs } from 'vs/editor/common/diff/algorithms/joinSequenceDiffs'; import { MyersDiffAlgorithm } from 'vs/editor/common/diff/algorithms/myersDiffAlgorithm'; -import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping, LinesDiff, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputer, ILinesDiffComputerOptions, LinesDiff, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping, LineRangeMapping, RangeMapping } from './rangeMapping'; +import { MonotonousArray, findLastIdxMonotonous, findLastMonotonous, findFirstMonotonous } from 'vs/base/common/arraysFind'; export class AdvancedLinesDiffComputer implements ILinesDiffComputer { private readonly dynamicProgrammingDiffing = new DynamicProgrammingDiffing(); @@ -29,7 +30,7 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { if (originalLines.length === 1 && originalLines[0].length === 0 || modifiedLines.length === 1 && modifiedLines[0].length === 0) { return new LinesDiff([ - new LineRangeMapping( + new DetailedLineRangeMapping( new LineRange(1, originalLines.length + 1), new LineRange(1, modifiedLines.length + 1), [ @@ -167,7 +168,7 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { validatePosition(ic.originalRange.getStartPosition(), originalLines) && validatePosition(ic.originalRange.getEndPosition(), originalLines); if (!valid) { return false; } } - if (!validateRange(c.modifiedRange, modifiedLines) || !validateRange(c.originalRange, originalLines)) { + if (!validateRange(c.modified, modifiedLines) || !validateRange(c.original, originalLines)) { return false; } } @@ -177,16 +178,94 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { return new LinesDiff(changes, moves, hitTimeout); } - private computeMoves(changes: LineRangeMapping[], originalLines: string[], modifiedLines: string[], hashedOriginalLines: number[], hashedModifiedLines: number[], timeout: ITimeout, considerWhitespaceChanges: boolean): MovedText[] { - const moves: SimpleLineRangeMapping[] = []; - const deletions = changes - .filter(c => c.modifiedRange.isEmpty && c.originalRange.length >= 3) - .map(d => new LineRangeFragment(d.originalRange, originalLines, d)); - const insertions = new Set(changes - .filter(c => c.originalRange.isEmpty && c.modifiedRange.length >= 3) - .map(d => new LineRangeFragment(d.modifiedRange, modifiedLines, d))); + private computeMoves( + changes: DetailedLineRangeMapping[], + originalLines: string[], + modifiedLines: string[], + hashedOriginalLines: number[], + hashedModifiedLines: number[], + timeout: ITimeout, + considerWhitespaceChanges: boolean, + ): MovedText[] { + const { moves, excludedChanges } = this.computeMovesFromSimpleDeletionsToSimpleInsertions(changes, originalLines, modifiedLines, timeout); - const excludedChanges = new Set(); + if (!timeout.isValid()) { return []; } + + const unchangedMoves = this.computeUnchangedMoves( + changes.filter(c => !excludedChanges.has(c)), + hashedOriginalLines, + hashedModifiedLines, + timeout + ); + pushMany(moves, unchangedMoves); + + // join moves + moves.sort(compareBy(m => m.original.startLineNumber, numberComparator)); + if (moves.length === 0) { + return []; + } + let joinedMoves = [moves[0]]; + for (let i = 1; i < moves.length; i++) { + const last = joinedMoves[joinedMoves.length - 1]; + const current = moves[i]; + + const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive; + const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive; + const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0; + + if (currentMoveAfterLast && originalDist + modifiedDist <= 2) { + joinedMoves[joinedMoves.length - 1] = last.join(current); + continue; + } + + const originalText = current.original.toOffsetRange().slice(originalLines).map(l => l.trim()).join('\n'); + if (originalText.length <= 10) { + // Ignore small moves + continue; + } + joinedMoves.push(current); + } + + // Ignore non moves + const changesMonotonous = new MonotonousArray(changes); + joinedMoves = joinedMoves.filter(m => { + const diffBeforeOriginalMove = changesMonotonous.findLastMonotonous(c => c.original.endLineNumberExclusive <= m.original.startLineNumber) + || new LineRangeMapping(new LineRange(1, 1), new LineRange(1, 1)); + + const modifiedDistToPrevDiff = m.modified.startLineNumber - diffBeforeOriginalMove.modified.endLineNumberExclusive; + const originalDistToPrevDiff = m.original.startLineNumber - diffBeforeOriginalMove.original.endLineNumberExclusive; + + const differentDistances = modifiedDistToPrevDiff !== originalDistToPrevDiff; + return differentDistances; + }); + + const movesWithDiffs = joinedMoves.map(m => { + const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( + m.original.toOffsetRange(), + m.modified.toOffsetRange(), + ), timeout, considerWhitespaceChanges); + const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true); + return new MovedText(m, mappings); + }); + return movesWithDiffs; + } + + private computeMovesFromSimpleDeletionsToSimpleInsertions( + changes: DetailedLineRangeMapping[], + originalLines: string[], + modifiedLines: string[], + timeout: ITimeout, + ) { + const moves: LineRangeMapping[] = []; + + const deletions = changes + .filter(c => c.modified.isEmpty && c.original.length >= 3) + .map(d => new LineRangeFragment(d.original, originalLines, d)); + const insertions = new Set(changes + .filter(c => c.original.isEmpty && c.modified.length >= 3) + .map(d => new LineRangeFragment(d.modified, modifiedLines, d))); + + const excludedChanges = new Set(); for (const deletion of deletions) { let highestSimilarity = -1; @@ -201,24 +280,31 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { if (highestSimilarity > 0.90 && best) { insertions.delete(best); - moves.push(new SimpleLineRangeMapping(deletion.range, best.range)); + moves.push(new LineRangeMapping(deletion.range, best.range)); excludedChanges.add(deletion.source); excludedChanges.add(best.source); } if (!timeout.isValid()) { - return []; + return { moves, excludedChanges }; } } + return { moves, excludedChanges }; + } + + private computeUnchangedMoves( + changes: DetailedLineRangeMapping[], + hashedOriginalLines: number[], + hashedModifiedLines: number[], + timeout: ITimeout, + ) { + const moves: LineRangeMapping[] = []; + const original3LineHashes = new SetMap(); for (const change of changes) { - if (excludedChanges.has(change)) { - continue; - } - - for (let i = change.originalRange.startLineNumber; i < change.originalRange.endLineNumberExclusive - 2; i++) { + for (let i = change.original.startLineNumber; i < change.original.endLineNumberExclusive - 2; i++) { const key = `${hashedOriginalLines[i - 1]}:${hashedOriginalLines[i + 1 - 1]}:${hashedOriginalLines[i + 2 - 1]}`; original3LineHashes.add(key, { range: new LineRange(i, i + 3) }); } @@ -231,15 +317,11 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { const possibleMappings: PossibleMapping[] = []; - changes.sort(compareBy(c => c.modifiedRange.startLineNumber, numberComparator)); + changes.sort(compareBy(c => c.modified.startLineNumber, numberComparator)); for (const change of changes) { - if (excludedChanges.has(change)) { - continue; - } - let lastMappings: PossibleMapping[] = []; - for (let i = change.modifiedRange.startLineNumber; i < change.modifiedRange.endLineNumberExclusive - 2; i++) { + for (let i = change.modified.startLineNumber; i < change.modified.endLineNumberExclusive - 2; i++) { const key = `${hashedModifiedLines[i - 1]}:${hashedModifiedLines[i + 1 - 1]}:${hashedModifiedLines[i + 2 - 1]}`; const currentModifiedRange = new LineRange(i, i + 3); @@ -280,73 +362,25 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { const diffOrigToMod = mapping.modifiedLineRange.startLineNumber - mapping.originalLineRange.startLineNumber; const modifiedSections = modifiedSet.subtractFrom(mapping.modifiedLineRange); - const originalTranslatedSections = originalSet.subtractFrom(mapping.originalLineRange).map(r => r.delta(diffOrigToMod)); + const originalTranslatedSections = originalSet.subtractFrom(mapping.originalLineRange).getWithDelta(diffOrigToMod); - const modifiedIntersectedSections = intersectRanges(modifiedSections, originalTranslatedSections); + const modifiedIntersectedSections = modifiedSections.getIntersection(originalTranslatedSections); - for (const s of modifiedIntersectedSections) { + for (const s of modifiedIntersectedSections.ranges) { if (s.length < 3) { continue; } const modifiedLineRange = s; const originalLineRange = s.delta(-diffOrigToMod); - moves.push(new SimpleLineRangeMapping(originalLineRange, modifiedLineRange)); + moves.push(new LineRangeMapping(originalLineRange, modifiedLineRange)); modifiedSet.addRange(modifiedLineRange); originalSet.addRange(originalLineRange); } } - // join moves - moves.sort(compareBy(m => m.original.startLineNumber, numberComparator)); - if (moves.length === 0) { - return []; - } - let joinedMoves = [moves[0]]; - for (let i = 1; i < moves.length; i++) { - const last = joinedMoves[joinedMoves.length - 1]; - const current = moves[i]; - - const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive; - const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive; - const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0; - - if (currentMoveAfterLast && originalDist + modifiedDist <= 2) { - joinedMoves[joinedMoves.length - 1] = last.join(current); - continue; - } - - const originalText = current.original.toOffsetRange().slice(originalLines).map(l => l.trim()).join('\n'); - if (originalText.length <= 10) { - // Ignore small moves - continue; - } - joinedMoves.push(current); - } - - // Ignore non moves - const originalChanges = MonotonousFinder.createOfSorted(changes, c => c.originalRange.endLineNumberExclusive, numberComparator); - joinedMoves = joinedMoves.filter(m => { - const diffBeforeOriginalMove = originalChanges.findLastItemBeforeOrEqual(m.original.startLineNumber) - || new LineRangeMapping(new LineRange(1, 1), new LineRange(1, 1), []); - - const modifiedDistToPrevDiff = m.modified.startLineNumber - diffBeforeOriginalMove.modifiedRange.endLineNumberExclusive; - const originalDistToPrevDiff = m.original.startLineNumber - diffBeforeOriginalMove.originalRange.endLineNumberExclusive; - - const differentDistances = modifiedDistToPrevDiff !== originalDistToPrevDiff; - return differentDistances; - }); - - const fullMoves = joinedMoves.map(m => { - const moveChanges = this.refineDiff(originalLines, modifiedLines, new SequenceDiff( - m.original.toOffsetRange(), - m.modified.toOffsetRange(), - ), timeout, considerWhitespaceChanges); - const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true); - return new MovedText(m, mappings); - }); - return fullMoves; + return moves; } private refineDiff(originalLines: string[], modifiedLines: string[], diff: SequenceDiff, timeout: ITimeout, considerWhitespaceChanges: boolean): { mappings: RangeMapping[]; hitTimeout: boolean } { @@ -380,154 +414,6 @@ export class AdvancedLinesDiffComputer implements ILinesDiffComputer { } } -class MonotonousFinder { - public static create( - items: TItem[], - itemToDomain: (item: TItem) => TDomain, - domainComparator: Comparator, - ): MonotonousFinder { - items.sort((a, b) => domainComparator(itemToDomain(a), itemToDomain(b))); - return new MonotonousFinder(items, itemToDomain, domainComparator); - } - - public static createOfSorted( - items: TItem[], - itemToDomain: (item: TItem) => TDomain, - domainComparator: Comparator, - ): MonotonousFinder { - return new MonotonousFinder(items, itemToDomain, domainComparator); - } - - private _currentIdx = 0; // All values with index lower than this are smaller than or equal to _lastValue and vice versa. - private _lastValue: TDomain | undefined = undefined; // Represents a smallest value. - private _hasLastValue = false; - - private constructor( - private readonly _items: TItem[], - private readonly _itemToDomain: (item: TItem) => TDomain, - private readonly _domainComparator: Comparator, - ) { - } - - /** - * Assumes the values are monotonously increasing. - */ - findLastItemBeforeOrEqual(value: TDomain): TItem | undefined { - if (this._hasLastValue && CompareResult.isLessThan(this._domainComparator(value, this._lastValue!))) { - // Values must be monotonously increasing - throw new BugIndicatingError(); - } - this._lastValue = value; - this._hasLastValue = true; - - while ( - this._currentIdx < this._items.length - && CompareResult.isLessThanOrEqual(this._domainComparator( - this._itemToDomain(this._items[this._currentIdx]), - value - )) - ) { - this._currentIdx++; - } - - return this._currentIdx === 0 ? undefined : this._items[this._currentIdx - 1]; - } -} - -function intersectRanges(ranges1: LineRange[], ranges2: LineRange[]): LineRange[] { - const result: LineRange[] = []; - - let i1 = 0; - let i2 = 0; - while (i1 < ranges1.length && i2 < ranges2.length) { - const r1 = ranges1[i1]; - const r2 = ranges2[i2]; - - const i = r1.intersect(r2); - if (i && !i.isEmpty) { - result.push(i); - } - - if (r1.endLineNumberExclusive < r2.endLineNumberExclusive) { - i1++; - } else { - i2++; - } - } - - return result; -} - -// TODO make this fast -class LineRangeSet { - private readonly _normalizedRanges: LineRange[] = []; - - addRange(range: LineRange): void { - // Idea: Find joinRange such that: - // replaceRange = _normalizedRanges.replaceRange(joinRange, range.joinAll(joinRange.map(idx => this._normalizedRanges[idx]))) - - // idx of first element that touches range or that is after range - const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length); - // idx of element after { last element that touches range or that is before range } - const joinRangeEndIdxExclusive = findLastIndex(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1; - - if (joinRangeStartIdx === joinRangeEndIdxExclusive) { - // If there is no element that touches range, then joinRangeStartIdx === joinRangeEndIdxExclusive and that value is the index of the element after range - this._normalizedRanges.splice(joinRangeStartIdx, 0, range); - } else if (joinRangeStartIdx === joinRangeEndIdxExclusive - 1) { - // Else, there is an element that touches range and in this case it is both the first and last element. Thus we can replace it - const joinRange = this._normalizedRanges[joinRangeStartIdx]; - this._normalizedRanges[joinRangeStartIdx] = joinRange.join(range); - } else { - // First and last element are different - we need to replace the entire range - const joinRange = this._normalizedRanges[joinRangeStartIdx].join(this._normalizedRanges[joinRangeEndIdxExclusive - 1]).join(range); - this._normalizedRanges.splice(joinRangeStartIdx, joinRangeEndIdxExclusive - joinRangeStartIdx, joinRange); - } - } - - intersects(range: LineRange): boolean { - for (const r of this._normalizedRanges) { - if (r.intersectsStrict(range)) { - return true; - } - } - return false; - } - - /** - * Subtracts all ranges in this set from `range` and returns the result. - */ - subtractFrom(range: LineRange): LineRange[] { - // idx of first element that touches range or that is after range - const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length); - // idx of element after { last element that touches range or that is before range } - const joinRangeEndIdxExclusive = findLastIndex(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1; - - if (joinRangeStartIdx === joinRangeEndIdxExclusive) { - return [range]; - } - - const result: LineRange[] = []; - let startLineNumber = range.startLineNumber; - for (let i = joinRangeStartIdx; i < joinRangeEndIdxExclusive; i++) { - const r = this._normalizedRanges[i]; - if (r.startLineNumber > startLineNumber) { - result.push(new LineRange(startLineNumber, r.startLineNumber)); - } - startLineNumber = r.endLineNumberExclusive; - } - if (startLineNumber < range.endLineNumberExclusive) { - result.push(new LineRange(startLineNumber, range.endLineNumberExclusive)); - } - - return result; - } -} - -function mapMinusOne(idx: number, mapTo: number): number { - return idx === -1 ? mapTo : idx; -} - function coverFullWords(sequence1: LinesSliceCharSequence, sequence2: LinesSliceCharSequence, sequenceDiffs: SequenceDiff[]): SequenceDiff[] { const additional: SequenceDiff[] = []; @@ -623,42 +509,42 @@ function mergeSequenceDiffs(sequenceDiffs1: SequenceDiff[], sequenceDiffs2: Sequ return result; } -export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[], dontAssertStartLine: boolean = false): LineRangeMapping[] { - const changes: LineRangeMapping[] = []; - for (const g of group( +export function lineRangeMappingFromRangeMappings(alignments: RangeMapping[], originalLines: string[], modifiedLines: string[], dontAssertStartLine: boolean = false): DetailedLineRangeMapping[] { + const changes: DetailedLineRangeMapping[] = []; + for (const g of groupAdjacentBy( alignments.map(a => getLineRangeMapping(a, originalLines, modifiedLines)), (a1, a2) => - a1.originalRange.overlapOrTouch(a2.originalRange) - || a1.modifiedRange.overlapOrTouch(a2.modifiedRange) + a1.original.overlapOrTouch(a2.original) + || a1.modified.overlapOrTouch(a2.modified) )) { const first = g[0]; const last = g[g.length - 1]; - changes.push(new LineRangeMapping( - first.originalRange.join(last.originalRange), - first.modifiedRange.join(last.modifiedRange), + changes.push(new DetailedLineRangeMapping( + first.original.join(last.original), + first.modified.join(last.modified), g.map(a => a.innerChanges![0]), )); } assertFn(() => { if (!dontAssertStartLine) { - if (changes.length > 0 && changes[0].originalRange.startLineNumber !== changes[0].modifiedRange.startLineNumber) { + if (changes.length > 0 && changes[0].original.startLineNumber !== changes[0].modified.startLineNumber) { return false; } } return checkAdjacentItems(changes, - (m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive && + (m1, m2) => m2.original.startLineNumber - m1.original.endLineNumberExclusive === m2.modified.startLineNumber - m1.modified.endLineNumberExclusive && // There has to be an unchanged line in between (otherwise both diffs should have been joined) - m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber && - m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber, + m1.original.endLineNumberExclusive < m2.original.startLineNumber && + m1.modified.endLineNumberExclusive < m2.modified.startLineNumber, ); }); return changes; } -export function getLineRangeMapping(rangeMapping: RangeMapping, originalLines: string[], modifiedLines: string[]): LineRangeMapping { +export function getLineRangeMapping(rangeMapping: RangeMapping, originalLines: string[], modifiedLines: string[]): DetailedLineRangeMapping { let lineStartDelta = 0; let lineEndDelta = 0; @@ -692,26 +578,7 @@ export function getLineRangeMapping(rangeMapping: RangeMapping, originalLines: s rangeMapping.modifiedRange.endLineNumber + 1 + lineEndDelta ); - return new LineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]); -} - -function* group(items: Iterable, shouldBeGrouped: (item1: T, item2: T) => boolean): Iterable { - let currentGroup: T[] | undefined; - let last: T | undefined; - for (const item of items) { - if (last !== undefined && shouldBeGrouped(last, item)) { - currentGroup!.push(item); - } else { - if (currentGroup) { - yield currentGroup; - } - currentGroup = [item]; - } - last = item; - } - if (currentGroup) { - yield currentGroup; - } + return new DetailedLineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]); } export class LineSequence implements ISequence { @@ -753,7 +620,7 @@ function getIndentation(str: string): number { export class LinesSliceCharSequence implements ISequence { private readonly elements: number[] = []; - private readonly firstCharOffsetByLineMinusOne: number[] = []; + private readonly firstCharOffsetByLine: number[] = []; public readonly lineRange: OffsetRange; // To account for trimming private readonly additionalOffsetByLine: number[] = []; @@ -771,6 +638,7 @@ export class LinesSliceCharSequence implements ISequence { this.lineRange = lineRange; + this.firstCharOffsetByLine[0] = 0; for (let i = this.lineRange.start; i < this.lineRange.endExclusive; i++) { let line = lines[i]; let offset = 0; @@ -793,7 +661,7 @@ export class LinesSliceCharSequence implements ISequence { // Don't add an \n that does not exist in the document. if (i < lines.length - 1) { this.elements.push('\n'.charCodeAt(0)); - this.firstCharOffsetByLineMinusOne[i - this.lineRange.start] = this.elements.length; + this.firstCharOffsetByLine[i - this.lineRange.start + 1] = this.elements.length; } } // To account for the last line @@ -852,19 +720,8 @@ export class LinesSliceCharSequence implements ISequence { return new Position(this.lineRange.start + 1, 1); } - let i = 0; - let j = this.firstCharOffsetByLineMinusOne.length; - while (i < j) { - const k = Math.floor((i + j) / 2); - if (this.firstCharOffsetByLineMinusOne[k] > offset) { - j = k; - } else { - i = k + 1; - } - } - - const offsetOfFirstCharInLine = i === 0 ? 0 : this.firstCharOffsetByLineMinusOne[i - 1]; - return new Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.additionalOffsetByLine[i]); + const i = findLastIdxMonotonous(this.firstCharOffsetByLine, (value) => value <= offset); + return new Position(this.lineRange.start + i + 1, offset - this.firstCharOffsetByLine[i] + this.additionalOffsetByLine[i] + 1); } public translateRange(range: OffsetRange): Range { @@ -907,60 +764,12 @@ export class LinesSliceCharSequence implements ISequence { } public extendToFullLines(range: OffsetRange): OffsetRange { - const start = findLastMonotonous(this.firstCharOffsetByLineMinusOne, x => x <= range.start) ?? 0; - const end = findFirstMonotonous(this.firstCharOffsetByLineMinusOne, x => range.endExclusive <= x) ?? this.elements.length; + const start = findLastMonotonous(this.firstCharOffsetByLine, x => x <= range.start) ?? 0; + const end = findFirstMonotonous(this.firstCharOffsetByLine, x => range.endExclusive <= x) ?? this.elements.length; return new OffsetRange(start, end); } } -/** - * `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`! - * - * @returns -1 if predicate is false for all items - */ -function findLastIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { - let i = 0; - let j = arr.length; - while (i < j) { - const k = Math.floor((i + j) / 2); - if (predicate(arr[k])) { - i = k + 1; - } else { - j = k; - } - } - return i - 1; -} - -export function findLastMonotonous(arr: T[], predicate: (item: T) => boolean): T | undefined { - const idx = findLastIdxMonotonous(arr, predicate); - return idx === -1 ? undefined : arr[idx]; -} - -/** - * `arr.map(predicate)` must be like `[false, ..., false, true, ..., true]`! - * - * @returns arr.length if predicate is false for all items - */ -function findFirstIdxMonotonous(arr: T[], predicate: (item: T) => boolean): number { - let i = 0; - let j = arr.length; - while (i < j) { - const k = Math.floor((i + j) / 2); - if (predicate(arr[k])) { - j = k; - } else { - i = k + 1; - } - } - return i; -} - -export function findFirstMonotonous(arr: T[], predicate: (item: T) => boolean): T | undefined { - const idx = findFirstIdxMonotonous(arr, predicate); - return idx === arr.length ? undefined : arr[idx]; -} - function isWordChar(charCode: number): boolean { return charCode >= CharCode.a && charCode <= CharCode.z || charCode >= CharCode.A && charCode <= CharCode.Z @@ -1033,7 +842,7 @@ class LineRangeFragment { constructor( public readonly range: LineRange, public readonly lines: string[], - public readonly source: LineRangeMapping, + public readonly source: DetailedLineRangeMapping, ) { let counter = 0; for (let i = range.startLineNumber - 1; i < range.endLineNumberExclusive - 1; i++) { diff --git a/src/vs/editor/common/diff/documentDiffProvider.ts b/src/vs/editor/common/diff/documentDiffProvider.ts index 02907dddca3..44accf9e604 100644 --- a/src/vs/editor/common/diff/documentDiffProvider.ts +++ b/src/vs/editor/common/diff/documentDiffProvider.ts @@ -5,7 +5,8 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Event } from 'vs/base/common/event'; -import { LineRangeMapping, MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from './rangeMapping'; import { ITextModel } from 'vs/editor/common/model'; /** @@ -61,7 +62,7 @@ export interface IDocumentDiff { /** * Maps all modified line ranges in the original to the corresponding line ranges in the modified text model. */ - readonly changes: readonly LineRangeMapping[]; + readonly changes: readonly DetailedLineRangeMapping[]; /** * Sorted by original line ranges. diff --git a/src/vs/editor/common/diff/legacyLinesDiffComputer.ts b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts index 5ea6524a41e..8d7e05e0308 100644 --- a/src/vs/editor/common/diff/legacyLinesDiffComputer.ts +++ b/src/vs/editor/common/diff/legacyLinesDiffComputer.ts @@ -5,7 +5,8 @@ import { CharCode } from 'vs/base/common/charCode'; import { IDiffChange, ISequence, LcsDiff, IDiffResult } from 'vs/base/common/diff/diff'; -import { ILinesDiffComputer, ILinesDiffComputerOptions, RangeMapping, LineRangeMapping, LinesDiff } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputer, ILinesDiffComputerOptions, LinesDiff } from 'vs/editor/common/diff/linesDiffComputer'; +import { RangeMapping, DetailedLineRangeMapping } from './rangeMapping'; import * as strings from 'vs/base/common/strings'; import { Range } from 'vs/editor/common/core/range'; import { assertFn, checkAdjacentItems } from 'vs/base/common/assert'; @@ -23,8 +24,8 @@ export class LegacyLinesDiffComputer implements ILinesDiffComputer { shouldPostProcessCharChanges: true, }); const result = diffComputer.computeDiff(); - const changes: LineRangeMapping[] = []; - let lastChange: LineRangeMapping | null = null; + const changes: DetailedLineRangeMapping[] = []; + let lastChange: DetailedLineRangeMapping | null = null; for (const c of result.changes) { @@ -44,17 +45,17 @@ export class LegacyLinesDiffComputer implements ILinesDiffComputer { modifiedRange = new LineRange(c.modifiedStartLineNumber, c.modifiedEndLineNumber + 1); } - let change = new LineRangeMapping(originalRange, modifiedRange, c.charChanges?.map(c => new RangeMapping( + let change = new DetailedLineRangeMapping(originalRange, modifiedRange, c.charChanges?.map(c => new RangeMapping( new Range(c.originalStartLineNumber, c.originalStartColumn, c.originalEndLineNumber, c.originalEndColumn), new Range(c.modifiedStartLineNumber, c.modifiedStartColumn, c.modifiedEndLineNumber, c.modifiedEndColumn), ))); if (lastChange) { - if (lastChange.modifiedRange.endLineNumberExclusive === change.modifiedRange.startLineNumber - || lastChange.originalRange.endLineNumberExclusive === change.originalRange.startLineNumber) { + if (lastChange.modified.endLineNumberExclusive === change.modified.startLineNumber + || lastChange.original.endLineNumberExclusive === change.original.startLineNumber) { // join touching diffs. Probably moving diffs up/down in the algorithm causes touching diffs. - change = new LineRangeMapping( - lastChange.originalRange.join(change.originalRange), - lastChange.modifiedRange.join(change.modifiedRange), + change = new DetailedLineRangeMapping( + lastChange.original.join(change.original), + lastChange.modified.join(change.modified), lastChange.innerChanges && change.innerChanges ? lastChange.innerChanges.concat(change.innerChanges) : undefined ); @@ -68,10 +69,10 @@ export class LegacyLinesDiffComputer implements ILinesDiffComputer { assertFn(() => { return checkAdjacentItems(changes, - (m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive && + (m1, m2) => m2.original.startLineNumber - m1.original.endLineNumberExclusive === m2.modified.startLineNumber - m1.modified.endLineNumberExclusive && // There has to be an unchanged line in between (otherwise both diffs should have been joined) - m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber && - m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber, + m1.original.endLineNumberExclusive < m2.original.startLineNumber && + m1.modified.endLineNumberExclusive < m2.modified.startLineNumber, ); }); @@ -92,7 +93,7 @@ export interface IDiffComputationResult { /** * The changes as (modern) line range mapping array. */ - changes2: readonly LineRangeMapping[]; + changes2: readonly DetailedLineRangeMapping[]; } /** diff --git a/src/vs/editor/common/diff/linesDiffComputer.ts b/src/vs/editor/common/diff/linesDiffComputer.ts index d10888cb93f..a11674f0127 100644 --- a/src/vs/editor/common/diff/linesDiffComputer.ts +++ b/src/vs/editor/common/diff/linesDiffComputer.ts @@ -3,8 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { LineRange } from 'vs/editor/common/core/lineRange'; -import { Range } from 'vs/editor/common/core/range'; +import { DetailedLineRangeMapping, LineRangeMapping } from './rangeMapping'; export interface ILinesDiffComputer { computeDiff(originalLines: string[], modifiedLines: string[], options: ILinesDiffComputerOptions): LinesDiff; @@ -18,7 +17,7 @@ export interface ILinesDiffComputerOptions { export class LinesDiff { constructor( - readonly changes: readonly LineRangeMapping[], + readonly changes: readonly DetailedLineRangeMapping[], /** * Sorted by original line ranges. @@ -35,148 +34,19 @@ export class LinesDiff { } } -/** - * Maps a line range in the original text model to a line range in the modified text model. - */ -export class LineRangeMapping { - public static inverse(mapping: readonly LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): LineRangeMapping[] { - const result: LineRangeMapping[] = []; - let lastOriginalEndLineNumber = 1; - let lastModifiedEndLineNumber = 1; - - for (const m of mapping) { - const r = new LineRangeMapping( - new LineRange(lastOriginalEndLineNumber, m.originalRange.startLineNumber), - new LineRange(lastModifiedEndLineNumber, m.modifiedRange.startLineNumber), - undefined - ); - if (!r.modifiedRange.isEmpty) { - result.push(r); - } - lastOriginalEndLineNumber = m.originalRange.endLineNumberExclusive; - lastModifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive; - } - const r = new LineRangeMapping( - new LineRange(lastOriginalEndLineNumber, originalLineCount + 1), - new LineRange(lastModifiedEndLineNumber, modifiedLineCount + 1), - undefined - ); - if (!r.modifiedRange.isEmpty) { - result.push(r); - } - return result; - } - - /** - * The line range in the original text model. - */ - public readonly originalRange: LineRange; - - /** - * The line range in the modified text model. - */ - public readonly modifiedRange: LineRange; - - /** - * If inner changes have not been computed, this is set to undefined. - * Otherwise, it represents the character-level diff in this line range. - * The original range of each range mapping should be contained in the original line range (same for modified), exceptions are new-lines. - * Must not be an empty array. - */ - public readonly innerChanges: RangeMapping[] | undefined; - - constructor( - originalRange: LineRange, - modifiedRange: LineRange, - innerChanges: RangeMapping[] | undefined, - ) { - this.originalRange = originalRange; - this.modifiedRange = modifiedRange; - this.innerChanges = innerChanges; - } - - public toString(): string { - return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`; - } - - public get changedLineCount() { - return Math.max(this.originalRange.length, this.modifiedRange.length); - } - - public flip(): LineRangeMapping { - return new LineRangeMapping(this.modifiedRange, this.originalRange, this.innerChanges?.map(c => c.flip())); - } -} - -/** - * Maps a range in the original text model to a range in the modified text model. - */ -export class RangeMapping { - /** - * The original range. - */ - readonly originalRange: Range; - - /** - * The modified range. - */ - readonly modifiedRange: Range; - - constructor( - originalRange: Range, - - modifiedRange: Range, - ) { - this.originalRange = originalRange; - this.modifiedRange = modifiedRange; - } - - public toString(): string { - return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`; - } - - public flip(): RangeMapping { - return new RangeMapping(this.modifiedRange, this.originalRange); - } -} - -// TODO@hediet: Make LineRangeMapping extend from this! -export class SimpleLineRangeMapping { - constructor( - public readonly original: LineRange, - public readonly modified: LineRange, - ) { - } - - public toString(): string { - return `{${this.original.toString()}->${this.modified.toString()}}`; - } - - public flip(): SimpleLineRangeMapping { - return new SimpleLineRangeMapping(this.modified, this.original); - } - - public join(other: SimpleLineRangeMapping): SimpleLineRangeMapping { - return new SimpleLineRangeMapping( - this.original.join(other.original), - this.modified.join(other.modified), - ); - } -} - export class MovedText { - public readonly lineRangeMapping: SimpleLineRangeMapping; + public readonly lineRangeMapping: LineRangeMapping; /** * The diff from the original text to the moved text. * Must be contained in the original/modified line range. * Can be empty if the text didn't change (only moved). */ - public readonly changes: readonly LineRangeMapping[]; + public readonly changes: readonly DetailedLineRangeMapping[]; constructor( - lineRangeMapping: SimpleLineRangeMapping, - changes: readonly LineRangeMapping[], + lineRangeMapping: LineRangeMapping, + changes: readonly DetailedLineRangeMapping[], ) { this.lineRangeMapping = lineRangeMapping; this.changes = changes; diff --git a/src/vs/editor/common/diff/rangeMapping.ts b/src/vs/editor/common/diff/rangeMapping.ts new file mode 100644 index 00000000000..12ac2a362e9 --- /dev/null +++ b/src/vs/editor/common/diff/rangeMapping.ts @@ -0,0 +1,133 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { LineRange } from 'vs/editor/common/core/lineRange'; +import { Range } from 'vs/editor/common/core/range'; + +export class LineRangeMapping { + public static inverse(mapping: readonly DetailedLineRangeMapping[], originalLineCount: number, modifiedLineCount: number): DetailedLineRangeMapping[] { + const result: DetailedLineRangeMapping[] = []; + let lastOriginalEndLineNumber = 1; + let lastModifiedEndLineNumber = 1; + + for (const m of mapping) { + const r = new DetailedLineRangeMapping( + new LineRange(lastOriginalEndLineNumber, m.original.startLineNumber), + new LineRange(lastModifiedEndLineNumber, m.modified.startLineNumber), + undefined + ); + if (!r.modified.isEmpty) { + result.push(r); + } + lastOriginalEndLineNumber = m.original.endLineNumberExclusive; + lastModifiedEndLineNumber = m.modified.endLineNumberExclusive; + } + const r = new DetailedLineRangeMapping( + new LineRange(lastOriginalEndLineNumber, originalLineCount + 1), + new LineRange(lastModifiedEndLineNumber, modifiedLineCount + 1), + undefined + ); + if (!r.modified.isEmpty) { + result.push(r); + } + return result; + } + + /** + * The line range in the original text model. + */ + public readonly original: LineRange; + + /** + * The line range in the modified text model. + */ + public readonly modified: LineRange; + + constructor( + originalRange: LineRange, + modifiedRange: LineRange + ) { + this.original = originalRange; + this.modified = modifiedRange; + } + + + public toString(): string { + return `{${this.original.toString()}->${this.modified.toString()}}`; + } + + public flip(): LineRangeMapping { + return new LineRangeMapping(this.modified, this.original); + } + + public join(other: LineRangeMapping): LineRangeMapping { + return new LineRangeMapping( + this.original.join(other.original), + this.modified.join(other.modified) + ); + } + + public get changedLineCount() { + return Math.max(this.original.length, this.modified.length); + } +} + +/** + * Maps a line range in the original text model to a line range in the modified text model. + */ +export class DetailedLineRangeMapping extends LineRangeMapping { + /** + * If inner changes have not been computed, this is set to undefined. + * Otherwise, it represents the character-level diff in this line range. + * The original range of each range mapping should be contained in the original line range (same for modified), exceptions are new-lines. + * Must not be an empty array. + */ + public readonly innerChanges: RangeMapping[] | undefined; + + constructor( + originalRange: LineRange, + modifiedRange: LineRange, + innerChanges: RangeMapping[] | undefined + ) { + super(originalRange, modifiedRange); + this.innerChanges = innerChanges; + } + + public override flip(): DetailedLineRangeMapping { + return new DetailedLineRangeMapping(this.modified, this.original, this.innerChanges?.map(c => c.flip())); + } +} + +/** + * Maps a range in the original text model to a range in the modified text model. + */ +export class RangeMapping { + /** + * The original range. + */ + readonly originalRange: Range; + + /** + * The modified range. + */ + readonly modifiedRange: Range; + + constructor( + originalRange: Range, + + modifiedRange: Range + ) { + this.originalRange = originalRange; + this.modifiedRange = modifiedRange; + } + + public toString(): string { + return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`; + } + + public flip(): RangeMapping { + return new RangeMapping(this.modifiedRange, this.originalRange); + } +} diff --git a/src/vs/editor/common/services/editorSimpleWorker.ts b/src/vs/editor/common/services/editorSimpleWorker.ts index ca8364f62d3..335e6b5c883 100644 --- a/src/vs/editor/common/services/editorSimpleWorker.ts +++ b/src/vs/editor/common/services/editorSimpleWorker.ts @@ -21,7 +21,8 @@ import { IEditorWorkerHost } from 'vs/editor/common/services/editorWorkerHost'; import { StopWatch } from 'vs/base/common/stopwatch'; import { UnicodeTextModelHighlighter, UnicodeHighlighterOptions } from 'vs/editor/common/services/unicodeTextModelHighlighter'; import { DiffComputer, IChange } from 'vs/editor/common/diff/legacyLinesDiffComputer'; -import { ILinesDiffComputer, ILinesDiffComputerOptions, LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { ILinesDiffComputer, ILinesDiffComputerOptions } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from '../diff/rangeMapping'; import { linesDiffComputers } from 'vs/editor/common/diff/linesDiffComputers'; import { createProxyObject, getAllMethodNames } from 'vs/base/common/objects'; import { IDocumentDiffProviderOptions } from 'vs/editor/common/diff/documentDiffProvider'; @@ -422,8 +423,8 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable { const identical = (result.changes.length > 0 ? false : this._modelsAreIdentical(originalTextModel, modifiedTextModel)); - function getLineChanges(changes: readonly LineRangeMapping[]): ILineChange[] { - return changes.map(m => ([m.originalRange.startLineNumber, m.originalRange.endLineNumberExclusive, m.modifiedRange.startLineNumber, m.modifiedRange.endLineNumberExclusive, m.innerChanges?.map(m => [ + function getLineChanges(changes: readonly DetailedLineRangeMapping[]): ILineChange[] { + return changes.map(m => ([m.original.startLineNumber, m.original.endLineNumberExclusive, m.modified.startLineNumber, m.modified.endLineNumberExclusive, m.innerChanges?.map(m => [ m.originalRange.startLineNumber, m.originalRange.startColumn, m.originalRange.endLineNumber, diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index 005e48ad530..bf010adb6ab 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -34,7 +34,8 @@ import { EditorCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensi import { IMenuItem, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry'; -import { LineRangeMapping, MovedText, RangeMapping, SimpleLineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { MovedText } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping, RangeMapping, LineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { LineRange } from 'vs/editor/common/core/lineRange'; import { EditorZoom } from 'vs/editor/common/config/editorZoom'; import { IOpenerService } from 'vs/platform/opener/common/opener'; @@ -584,11 +585,11 @@ export function createMonacoEditorAPI(): typeof monaco.editor { FindMatch: FindMatch, ApplyUpdateResult: ApplyUpdateResult, LineRange: LineRange, - LineRangeMapping: LineRangeMapping, + LineRangeMapping: DetailedLineRangeMapping, RangeMapping: RangeMapping, EditorZoom: EditorZoom, MovedText: MovedText, - SimpleLineRangeMapping: SimpleLineRangeMapping, + SimpleLineRangeMapping: LineRangeMapping, // vars EditorType: EditorType, diff --git a/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts b/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts index c9980e34a08..6adb654d142 100644 --- a/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts +++ b/src/vs/editor/test/browser/widget/diffEditorWidget2.test.ts @@ -6,7 +6,7 @@ import assert = require('assert'); import { UnchangedRegion } from 'vs/editor/browser/widget/diffEditorWidget2/diffEditorViewModel'; import { LineRange } from 'vs/editor/common/core/lineRange'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; suite('DiffEditorWidget2', () => { suite('UnchangedRegion', () => { @@ -16,7 +16,7 @@ suite('DiffEditorWidget2', () => { test('Everything changed', () => { assert.deepStrictEqual(serialize(UnchangedRegion.fromDiffs( - [new LineRangeMapping(new LineRange(1, 10), new LineRange(1, 10), [])], + [new DetailedLineRangeMapping(new LineRange(1, 10), new LineRange(1, 10), [])], 10, 10, 3, @@ -38,7 +38,7 @@ suite('DiffEditorWidget2', () => { test('Change in the middle', () => { assert.deepStrictEqual(serialize(UnchangedRegion.fromDiffs( - [new LineRangeMapping(new LineRange(50, 60), new LineRange(50, 60), [])], + [new DetailedLineRangeMapping(new LineRange(50, 60), new LineRange(50, 60), [])], 100, 100, 3, @@ -51,7 +51,7 @@ suite('DiffEditorWidget2', () => { test('Change at the end', () => { assert.deepStrictEqual(serialize(UnchangedRegion.fromDiffs( - [new LineRangeMapping(new LineRange(99, 100), new LineRange(100, 100), [])], + [new DetailedLineRangeMapping(new LineRange(99, 100), new LineRange(100, 100), [])], 100, 100, 3, diff --git a/src/vs/editor/test/common/core/lineRange.test.ts b/src/vs/editor/test/common/core/lineRange.test.ts new file mode 100644 index 00000000000..08aa57bae8d --- /dev/null +++ b/src/vs/editor/test/common/core/lineRange.test.ts @@ -0,0 +1,58 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import assert = require('assert'); +import { LineRange, LineRangeSet } from 'vs/editor/common/core/lineRange'; + +suite('LineRange', () => { + test('contains', () => { + const r = new LineRange(2, 3); + assert.deepStrictEqual(r.contains(1), false); + assert.deepStrictEqual(r.contains(2), true); + assert.deepStrictEqual(r.contains(3), true); + assert.deepStrictEqual(r.contains(4), false); + }); +}); + +suite('LineRangeSet', () => { + test('addRange', () => { + const set = new LineRangeSet(); + set.addRange(new LineRange(2, 3)); + set.addRange(new LineRange(3, 4)); + set.addRange(new LineRange(10, 20)); + assert.deepStrictEqual(set.toString(), '[2,4), [10,20)'); + + set.addRange(new LineRange(3, 21)); + assert.deepStrictEqual(set.toString(), '[2,21)'); + }); + + test('getUnion', () => { + const set1 = new LineRangeSet([ + new LineRange(2, 3), + new LineRange(5, 7), + new LineRange(10, 20) + ]); + const set2 = new LineRangeSet([ + new LineRange(3, 4), + new LineRange(6, 8), + new LineRange(9, 11) + ]); + + const union = set1.getUnion(set2); + assert.deepStrictEqual(union.toString(), '[2,4), [5,8), [9,20)'); + }); + + test('intersects', () => { + const set1 = new LineRangeSet([ + new LineRange(2, 3), + new LineRange(5, 7), + new LineRange(10, 20) + ]); + + assert.deepStrictEqual(set1.intersects(new LineRange(1, 2)), false); + assert.deepStrictEqual(set1.intersects(new LineRange(1, 3)), true); + assert.deepStrictEqual(set1.intersects(new LineRange(3, 5)), false); + }); +}); diff --git a/src/vs/editor/test/node/diffing/advancedLinesDiffComputer.test.ts b/src/vs/editor/test/node/diffing/advancedLinesDiffComputer.test.ts new file mode 100644 index 00000000000..f5e4bbacdbc --- /dev/null +++ b/src/vs/editor/test/node/diffing/advancedLinesDiffComputer.test.ts @@ -0,0 +1,100 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { Range } from 'vs/editor/common/core/range'; +import { RangeMapping } from 'vs/editor/common/diff/rangeMapping'; +import { LinesSliceCharSequence, getLineRangeMapping } from 'vs/editor/common/diff/advancedLinesDiffComputer'; +import { OffsetRange } from 'vs/editor/common/core/offsetRange'; + +suite('lineRangeMapping', () => { + test('1', () => { + assert.deepStrictEqual( + getLineRangeMapping( + new RangeMapping( + new Range(2, 1, 3, 1), + new Range(2, 1, 2, 1) + ), + [ + 'const abc = "helloworld".split("");', + '', + '' + ], + [ + 'const asciiLower = "helloworld".split("");', + '' + ] + ).toString(), + "{[2,3)->[2,2)}" + ); + }); + + test('2', () => { + assert.deepStrictEqual( + getLineRangeMapping( + new RangeMapping( + new Range(2, 1, 2, 1), + new Range(2, 1, 4, 1), + ), + [ + '', + '', + ], + [ + '', + '', + '', + '', + ] + ).toString(), + "{[2,2)->[2,4)}" + ); + }); +}); + +suite('LinesSliceCharSequence', () => { + // Create tests for translateOffset + + const sequence = new LinesSliceCharSequence( + [ + 'line1: foo', + 'line2: fizzbuzz', + 'line3: barr', + 'line4: hello world', + 'line5: bazz', + ], + new OffsetRange(1, 4), true + ); + + test('translateOffset', () => { + assert.deepStrictEqual( + { result: OffsetRange.ofLength(sequence.length).map(offset => sequence.translateOffset(offset).toString()) }, + ({ + result: [ + "(2,1)", "(2,2)", "(2,3)", "(2,4)", "(2,5)", "(2,6)", "(2,7)", "(2,8)", "(2,9)", "(2,10)", "(2,11)", + "(2,12)", "(2,13)", "(2,14)", "(2,15)", "(2,16)", + + "(3,1)", "(3,2)", "(3,3)", "(3,4)", "(3,5)", "(3,6)", "(3,7)", "(3,8)", "(3,9)", "(3,10)", "(3,11)", "(3,12)", + + "(4,1)", "(4,2)", "(4,3)", "(4,4)", "(4,5)", "(4,6)", "(4,7)", "(4,8)", "(4,9)", + "(4,10)", "(4,11)", "(4,12)", "(4,13)", "(4,14)", "(4,15)", "(4,16)", "(4,17)", + "(4,18)", "(4,19)" + ] + }) + ); + }); + + test('extendToFullLines', () => { + assert.deepStrictEqual( + { result: sequence.getText(sequence.extendToFullLines(new OffsetRange(20, 25))) }, + ({ result: "line3: barr\n" }) + ); + + assert.deepStrictEqual( + { result: sequence.getText(sequence.extendToFullLines(new OffsetRange(20, 45))) }, + ({ result: "line3: barr\nline4: hello world\n" }) + ); + }); +}); diff --git a/src/vs/editor/test/node/diffing/diffingFixture.test.ts b/src/vs/editor/test/node/diffing/diffingFixture.test.ts index a04f2edf9d8..89490813b78 100644 --- a/src/vs/editor/test/node/diffing/diffingFixture.test.ts +++ b/src/vs/editor/test/node/diffing/diffingFixture.test.ts @@ -8,7 +8,7 @@ import { existsSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'fs import { join, resolve } from 'path'; import { setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { FileAccess } from 'vs/base/common/network'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { LegacyLinesDiffComputer } from 'vs/editor/common/diff/legacyLinesDiffComputer'; import { AdvancedLinesDiffComputer } from 'vs/editor/common/diff/advancedLinesDiffComputer'; @@ -43,10 +43,10 @@ suite('diff fixtures', () => { const ignoreTrimWhitespace = folder.indexOf('trimws') >= 0; const diff = diffingAlgo.computeDiff(firstContentLines, secondContentLines, { ignoreTrimWhitespace, maxComputationTimeMs: Number.MAX_SAFE_INTEGER, computeMoves: false }); - function getDiffs(changes: readonly LineRangeMapping[]): IDetailedDiff[] { + function getDiffs(changes: readonly DetailedLineRangeMapping[]): IDetailedDiff[] { return changes.map(c => ({ - originalRange: c.originalRange.toString(), - modifiedRange: c.modifiedRange.toString(), + originalRange: c.original.toString(), + modifiedRange: c.modified.toString(), innerChanges: c.innerChanges?.map(c => ({ originalRange: c.originalRange.toString(), modifiedRange: c.modifiedRange.toString(), diff --git a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts b/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts deleted file mode 100644 index f0d0802912d..00000000000 --- a/src/vs/editor/test/node/diffing/lineRangeMapping.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { Range } from 'vs/editor/common/core/range'; -import { RangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; -import { getLineRangeMapping } from 'vs/editor/common/diff/advancedLinesDiffComputer'; - -suite('lineRangeMapping', () => { - test('1', () => { - assert.deepStrictEqual( - getLineRangeMapping( - new RangeMapping( - new Range(2, 1, 3, 1), - new Range(2, 1, 2, 1) - ), - [ - 'const abc = "helloworld".split("");', - '', - '' - ], - [ - 'const asciiLower = "helloworld".split("");', - '' - ] - ).toString(), - "{[2,3)->[2,2)}" - ); - }); - - test('2', () => { - assert.deepStrictEqual( - getLineRangeMapping( - new RangeMapping( - new Range(2, 1, 2, 1), - new Range(2, 1, 4, 1), - ), - [ - '', - '', - ], - [ - '', - '', - '', - '', - ] - ).toString(), - "{[2,2)->[2,4)}" - ); - }); -}); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts index 1374da20090..a9b339e7ae5 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatLivePreviewWidget.ts @@ -18,7 +18,7 @@ import * as editorColorRegistry from 'vs/editor/common/core/editorColorRegistry' import { IThemeService } from 'vs/platform/theme/common/themeService'; import { INLINE_CHAT_ID, inlineChatDiffInserted, inlineChatDiffRemoved, inlineChatRegionHighlight } from 'vs/workbench/contrib/inlineChat/common/inlineChat'; import { LineRange } from 'vs/editor/common/core/lineRange'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { Position } from 'vs/editor/common/core/position'; import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions'; import { ScrollType } from 'vs/editor/common/editorCommon'; @@ -163,7 +163,7 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { this._isDiffLocked = true; } - private _updateFromChanges(range: Range, changes: readonly LineRangeMapping[]): void { + private _updateFromChanges(range: Range, changes: readonly DetailedLineRangeMapping[]): void { assertType(this.editor.hasModel()); if (this._isDiffLocked) { @@ -177,7 +177,7 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { // --- full diff - private _renderChangesWithFullDiff(changes: readonly LineRangeMapping[], range: Range) { + private _renderChangesWithFullDiff(changes: readonly DetailedLineRangeMapping[], range: Range) { const modified = this.editor.getModel()!; const ranges = this._computeHiddenRanges(modified, range, changes); @@ -206,16 +206,16 @@ export class InlineChatLivePreviewWidget extends ZoneWidget { super.hide(); } - private _computeHiddenRanges(model: ITextModel, range: Range, changes: readonly LineRangeMapping[]) { + private _computeHiddenRanges(model: ITextModel, range: Range, changes: readonly DetailedLineRangeMapping[]) { if (changes.length === 0) { - changes = [new LineRangeMapping(LineRange.fromRange(range), LineRange.fromRange(range), undefined)]; + changes = [new DetailedLineRangeMapping(LineRange.fromRange(range), LineRange.fromRange(range), undefined)]; } - let originalLineRange = changes[0].originalRange; - let modifiedLineRange = changes[0].modifiedRange; + let originalLineRange = changes[0].original; + let modifiedLineRange = changes[0].modified; for (let i = 1; i < changes.length; i++) { - originalLineRange = originalLineRange.join(changes[i].originalRange); - modifiedLineRange = modifiedLineRange.join(changes[i].modifiedRange); + originalLineRange = originalLineRange.join(changes[i].original); + modifiedLineRange = modifiedLineRange.join(changes[i].modified); } const startDelta = modifiedLineRange.startLineNumber - range.startLineNumber; diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts index fcbb998dc79..8de79727cea 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatSession.ts @@ -23,7 +23,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { Iterable } from 'vs/base/common/iterator'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { isCancellationError } from 'vs/base/common/errors'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { ISingleEditOperation } from 'vs/editor/common/core/editOperation'; import { raceCancellation } from 'vs/base/common/async'; @@ -112,7 +112,7 @@ export class Session { private _lastInput: SessionPrompt | undefined; private _lastExpansionState: ExpansionState | undefined; - private _lastTextModelChanges: readonly LineRangeMapping[] | undefined; + private _lastTextModelChanges: readonly DetailedLineRangeMapping[] | undefined; private _isUnstashed: boolean = false; private readonly _exchange: SessionExchange[] = []; private readonly _startTime = new Date(); @@ -191,7 +191,7 @@ export class Session { return this._lastTextModelChanges ?? []; } - set lastTextModelChanges(changes: readonly LineRangeMapping[]) { + set lastTextModelChanges(changes: readonly DetailedLineRangeMapping[]) { this._lastTextModelChanges = changes; } @@ -207,8 +207,8 @@ export class Session { let startLine = Number.MAX_VALUE; let endLine = Number.MIN_VALUE; for (const change of this._lastTextModelChanges) { - startLine = Math.min(startLine, change.modifiedRange.startLineNumber); - endLine = Math.max(endLine, change.modifiedRange.endLineNumberExclusive); + startLine = Math.min(startLine, change.modified.startLineNumber); + endLine = Math.max(endLine, change.modified.endLineNumberExclusive); } return this.textModelN.getValueInRange(new Range(startLine, 1, endLine, Number.MAX_VALUE)); diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts index c3a08e55ce9..76944f5b38e 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts @@ -354,7 +354,7 @@ export class LiveStrategy extends EditModeStrategy { const lastTextModelChanges = this._session.lastTextModelChanges; let lastLineOfLocalEdits: number | undefined; for (const change of lastTextModelChanges) { - const changeEndLineNumber = change.modifiedRange.endLineNumberExclusive - 1; + const changeEndLineNumber = change.modified.endLineNumberExclusive - 1; if (typeof lastLineOfLocalEdits === 'undefined' || lastLineOfLocalEdits < changeEndLineNumber) { lastLineOfLocalEdits = changeEndLineNumber; } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts index 343749ce5c6..9703af6a00a 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.ts @@ -36,7 +36,7 @@ import { FileKind } from 'vs/platform/files/common/files'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { LanguageSelector } from 'vs/editor/common/languageSelector'; import { createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel'; -import { LineRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { DetailedLineRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { invertLineRange, lineRangeAsRange } from 'vs/workbench/contrib/inlineChat/browser/utils'; import { ICodeEditorViewState, ScrollType } from 'vs/editor/common/editorCommon'; import { LineRange } from 'vs/editor/common/core/lineRange'; @@ -612,7 +612,7 @@ export class InlineChatWidget { // --- preview - showEditsPreview(textModelv0: ITextModel, allEdits: ISingleEditOperation[][], changes: readonly LineRangeMapping[]) { + showEditsPreview(textModelv0: ITextModel, allEdits: ISingleEditOperation[][], changes: readonly DetailedLineRangeMapping[]) { if (changes.length === 0) { this.hideEditsPreview(); return; @@ -628,11 +628,11 @@ export class InlineChatWidget { this._previewDiffEditor.value.setModel({ original: textModelv0, modified }); // joined ranges - let originalLineRange = changes[0].originalRange; - let modifiedLineRange = changes[0].modifiedRange; + let originalLineRange = changes[0].original; + let modifiedLineRange = changes[0].modified; for (let i = 1; i < changes.length; i++) { - originalLineRange = originalLineRange.join(changes[i].originalRange); - modifiedLineRange = modifiedLineRange.join(changes[i].modifiedRange); + originalLineRange = originalLineRange.join(changes[i].original); + modifiedLineRange = modifiedLineRange.join(changes[i].modified); } // apply extra padding diff --git a/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts b/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts index cc1be27460f..334479df903 100644 --- a/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts +++ b/src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts @@ -5,7 +5,7 @@ import { assertFn, checkAdjacentItems } from 'vs/base/common/assert'; import { IReader } from 'vs/base/common/observable'; -import { RangeMapping as DiffRangeMapping } from 'vs/editor/common/diff/linesDiffComputer'; +import { RangeMapping as DiffRangeMapping } from 'vs/editor/common/diff/rangeMapping'; import { ITextModel } from 'vs/editor/common/model'; import { IEditorWorkerService } from 'vs/editor/common/services/editorWorker'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -56,9 +56,9 @@ export class MergeDiffComputer implements IMergeDiffComputer { const changes = result.changes.map(c => new DetailedLineRangeMapping( - toLineRange(c.originalRange), + toLineRange(c.original), textModel1, - toLineRange(c.modifiedRange), + toLineRange(c.modified), textModel2, c.innerChanges?.map(ic => toRangeMapping(ic)) ) diff --git a/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts b/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts index d411e9a4c1f..0441e4483d3 100644 --- a/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts +++ b/src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts @@ -290,9 +290,9 @@ class MergeModelInterface extends Disposable { ); const changes = result.changes.map(c => new DetailedLineRangeMapping( - toLineRange(c.originalRange), + toLineRange(c.original), textModel1, - toLineRange(c.modifiedRange), + toLineRange(c.modified), textModel2, c.innerChanges?.map(ic => toRangeMapping(ic)).filter(isDefined) ) From 4d53e0a13649b3a49e4ee2f2d15577aa581b70bb Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 1 Sep 2023 13:32:21 +0200 Subject: [PATCH 181/198] Fixes CI --- build/monaco/monaco.d.ts.recipe | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index 89c884f18a0..3af07387f51 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -110,7 +110,7 @@ export interface ICommandHandler { #include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/diff/documentDiffProvider): IDocumentDiffProvider, IDocumentDiffProviderOptions, IDocumentDiff #include(vs/editor/common/core/lineRange): LineRange -#include(vs/editor/common/diff/linesDiffComputer): LineRangeMapping, RangeMapping, MovedText, SimpleLineRangeMapping +#include(vs/editor/common/diff/linesDiffComputer): DetailedLineRangeMapping, RangeMapping, MovedText, LineRangeMapping #include(vs/editor/common/core/dimension): IDimension #includeAll(vs/editor/common/editorCommon): IScrollEvent #includeAll(vs/editor/common/textModelEvents): From fe25a72de8ea3cefcf95946bb9f3c82bef001b6d Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 1 Sep 2023 14:01:32 +0200 Subject: [PATCH 182/198] Fixes CI --- build/monaco/monaco.d.ts.recipe | 3 +- .../standalone/browser/standaloneEditor.ts | 4 +- src/vs/monaco.d.ts | 58 ++++++++----------- 3 files changed, 29 insertions(+), 36 deletions(-) diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index 3af07387f51..4f064aeb6f1 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -110,7 +110,8 @@ export interface ICommandHandler { #include(vs/editor/common/diff/legacyLinesDiffComputer): IChange, ICharChange, ILineChange #include(vs/editor/common/diff/documentDiffProvider): IDocumentDiffProvider, IDocumentDiffProviderOptions, IDocumentDiff #include(vs/editor/common/core/lineRange): LineRange -#include(vs/editor/common/diff/linesDiffComputer): DetailedLineRangeMapping, RangeMapping, MovedText, LineRangeMapping +#include(vs/editor/common/diff/linesDiffComputer): MovedText +#include(vs/editor/common/diff/rangeMapping): DetailedLineRangeMapping, RangeMapping, LineRangeMapping #include(vs/editor/common/core/dimension): IDimension #includeAll(vs/editor/common/editorCommon): IScrollEvent #includeAll(vs/editor/common/textModelEvents): diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index bf010adb6ab..9d529b71049 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -585,11 +585,11 @@ export function createMonacoEditorAPI(): typeof monaco.editor { FindMatch: FindMatch, ApplyUpdateResult: ApplyUpdateResult, LineRange: LineRange, - LineRangeMapping: DetailedLineRangeMapping, + DetailedLineRangeMapping: DetailedLineRangeMapping, RangeMapping: RangeMapping, EditorZoom: EditorZoom, MovedText: MovedText, - SimpleLineRangeMapping: LineRangeMapping, + LineRangeMapping: LineRangeMapping, // vars EditorType: EditorType, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 3a49dbf4aa5..51ce58011f8 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2415,7 +2415,7 @@ declare namespace monaco.editor { /** * Maps all modified line ranges in the original to the corresponding line ranges in the modified text model. */ - readonly changes: readonly LineRangeMapping[]; + readonly changes: readonly DetailedLineRangeMapping[]; /** * Sorted by original line ranges. * The original line ranges and the modified line ranges must be disjoint (but can be touching). @@ -2433,11 +2433,6 @@ declare namespace monaco.editor { * @param lineRanges An array of sorted line ranges. */ static joinMany(lineRanges: readonly (readonly LineRange[])[]): readonly LineRange[]; - /** - * @param lineRanges1 Must be sorted. - * @param lineRanges2 Must be sorted. - */ - static join(lineRanges1: readonly LineRange[], lineRanges2: readonly LineRange[]): readonly LineRange[]; static ofLength(startLineNumber: number, length: number): LineRange; /** * The start line number. @@ -2485,19 +2480,22 @@ declare namespace monaco.editor { includes(lineNumber: number): boolean; } + export class MovedText { + readonly lineRangeMapping: LineRangeMapping; + /** + * The diff from the original text to the moved text. + * Must be contained in the original/modified line range. + * Can be empty if the text didn't change (only moved). + */ + readonly changes: readonly DetailedLineRangeMapping[]; + constructor(lineRangeMapping: LineRangeMapping, changes: readonly DetailedLineRangeMapping[]); + flip(): MovedText; + } + /** * Maps a line range in the original text model to a line range in the modified text model. */ - export class LineRangeMapping { - static inverse(mapping: readonly LineRangeMapping[], originalLineCount: number, modifiedLineCount: number): LineRangeMapping[]; - /** - * The line range in the original text model. - */ - readonly originalRange: LineRange; - /** - * The line range in the modified text model. - */ - readonly modifiedRange: LineRange; + export class DetailedLineRangeMapping extends LineRangeMapping { /** * If inner changes have not been computed, this is set to undefined. * Otherwise, it represents the character-level diff in this line range. @@ -2506,9 +2504,7 @@ declare namespace monaco.editor { */ readonly innerChanges: RangeMapping[] | undefined; constructor(originalRange: LineRange, modifiedRange: LineRange, innerChanges: RangeMapping[] | undefined); - toString(): string; - get changedLineCount(): any; - flip(): LineRangeMapping; + flip(): DetailedLineRangeMapping; } /** @@ -2528,25 +2524,21 @@ declare namespace monaco.editor { flip(): RangeMapping; } - export class MovedText { - readonly lineRangeMapping: SimpleLineRangeMapping; + export class LineRangeMapping { + static inverse(mapping: readonly DetailedLineRangeMapping[], originalLineCount: number, modifiedLineCount: number): DetailedLineRangeMapping[]; /** - * The diff from the original text to the moved text. - * Must be contained in the original/modified line range. - * Can be empty if the text didn't change (only moved). + * The line range in the original text model. */ - readonly changes: readonly LineRangeMapping[]; - constructor(lineRangeMapping: SimpleLineRangeMapping, changes: readonly LineRangeMapping[]); - flip(): MovedText; - } - - export class SimpleLineRangeMapping { readonly original: LineRange; + /** + * The line range in the modified text model. + */ readonly modified: LineRange; - constructor(original: LineRange, modified: LineRange); + constructor(originalRange: LineRange, modifiedRange: LineRange); toString(): string; - flip(): SimpleLineRangeMapping; - join(other: SimpleLineRangeMapping): SimpleLineRangeMapping; + flip(): LineRangeMapping; + join(other: LineRangeMapping): LineRangeMapping; + get changedLineCount(): any; } export interface IDimension { width: number; From 0ae7b5b1c5aef9c195c1b6366b7a4e19fdecb314 Mon Sep 17 00:00:00 2001 From: Henning Dieterichs Date: Fri, 1 Sep 2023 14:21:24 +0200 Subject: [PATCH 183/198] Fixes tests --- src/vs/editor/test/common/core/lineRange.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/test/common/core/lineRange.test.ts b/src/vs/editor/test/common/core/lineRange.test.ts index 08aa57bae8d..535a20607b1 100644 --- a/src/vs/editor/test/common/core/lineRange.test.ts +++ b/src/vs/editor/test/common/core/lineRange.test.ts @@ -11,7 +11,7 @@ suite('LineRange', () => { const r = new LineRange(2, 3); assert.deepStrictEqual(r.contains(1), false); assert.deepStrictEqual(r.contains(2), true); - assert.deepStrictEqual(r.contains(3), true); + assert.deepStrictEqual(r.contains(3), false); assert.deepStrictEqual(r.contains(4), false); }); }); From 660e12b312542b6fc0f6fe5d2fe7c5b749a19af1 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 1 Sep 2023 15:32:38 +0200 Subject: [PATCH 184/198] editors - restore focus also in `addGroup` (#191961) --- src/vs/workbench/browser/parts/editor/editorPart.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index c424f439a4f..8b733caa867 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -515,12 +515,21 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro addGroup(location: IEditorGroupView | GroupIdentifier, direction: GroupDirection, options?: IAddGroupOptions): IEditorGroupView { const locationView = this.assertGroupView(location); + const restoreFocus = this.shouldRestoreFocus(locationView.element); + const group = this.doAddGroup(locationView, direction); if (options?.activate) { this.doSetGroupActive(group); } + // Restore focus if we had it previously after completing the grid + // operation. That operation might cause reparenting of grid views + // which moves focus to the element otherwise. + if (restoreFocus) { + locationView.focus(); + } + return group; } From 4f424db46e05e241a7f3440384bd82b7ea393b17 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 1 Sep 2023 15:33:06 +0200 Subject: [PATCH 185/198] debt - ensure `file` scheme when using `.fsPath` (#191960) --- src/vs/code/electron-main/main.ts | 8 ++++---- src/vs/code/node/cliProcessMain.ts | 2 +- .../node/sharedProcess/contrib/logsDataCleaner.ts | 11 ++++++----- .../node/sharedProcess/contrib/storageDataCleaner.ts | 6 ++++-- .../protocol/electron-main/protocolMainService.ts | 4 ++-- src/vs/platform/storage/common/storageService.ts | 7 ++++--- src/vs/platform/storage/electron-main/storageMain.ts | 7 ++++--- .../storage/electron-main/storageMainService.ts | 3 ++- .../terminal/electron-main/electronPtyHostStarter.ts | 3 ++- src/vs/platform/terminal/node/nodePtyHostStarter.ts | 4 ++-- .../windows/electron-main/windowsMainService.ts | 6 +++--- .../electron-main/workspacesManagementMainService.ts | 4 ++-- src/vs/server/node/serverServices.ts | 2 +- .../contrib/files/electron-sandbox/fileCommands.ts | 2 +- .../electron-sandbox/localHistoryCommands.ts | 2 +- .../contrib/logs/electron-sandbox/logsActions.ts | 5 +++-- .../electron-sandbox/userDataSync.contribution.ts | 3 ++- 17 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 0174a24c3c8..7bdb1e1a459 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -251,10 +251,10 @@ class CodeMain { Promise.all([ environmentMainService.extensionsPath, environmentMainService.codeCachePath, - environmentMainService.logsHome.fsPath, - userDataProfilesMainService.defaultProfile.globalStorageHome.fsPath, - environmentMainService.workspaceStorageHome.fsPath, - environmentMainService.localHistoryHome.fsPath, + environmentMainService.logsHome.with({ scheme: Schemas.file }).fsPath, + userDataProfilesMainService.defaultProfile.globalStorageHome.with({ scheme: Schemas.file }).fsPath, + environmentMainService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath, + environmentMainService.localHistoryHome.with({ scheme: Schemas.file }).fsPath, environmentMainService.backupHome ].map(path => path ? FSPromises.mkdir(path, { recursive: true }) : undefined)), diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index a003267c043..b97aa7a0be8 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -121,7 +121,7 @@ class CliMain extends Disposable { // Init folders await Promise.all([ - environmentService.appSettingsHome.fsPath, + environmentService.appSettingsHome.with({ scheme: Schemas.file }).fsPath, environmentService.extensionsPath ].map(path => path ? Promises.mkdir(path, { recursive: true }) : undefined)); diff --git a/src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts b/src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts index ab5f8a1d87a..60a3652edf0 100644 --- a/src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts +++ b/src/vs/code/node/sharedProcess/contrib/logsDataCleaner.ts @@ -6,7 +6,9 @@ import { RunOnceScheduler } from 'vs/base/common/async'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Disposable } from 'vs/base/common/lifecycle'; -import { basename, dirname, joinPath } from 'vs/base/common/resources'; +import { Schemas } from 'vs/base/common/network'; +import { join } from 'vs/base/common/path'; +import { basename, dirname } from 'vs/base/common/resources'; import { Promises } from 'vs/base/node/pfs'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ILogService } from 'vs/platform/log/common/log'; @@ -30,9 +32,8 @@ export class LogsDataCleaner extends Disposable { try { const currentLog = basename(this.environmentService.logsHome); - const logsRoot = dirname(this.environmentService.logsHome); - - const logFiles = await Promises.readdir(logsRoot.fsPath); + const logsRoot = dirname(this.environmentService.logsHome.with({ scheme: Schemas.file })).fsPath; + const logFiles = await Promises.readdir(logsRoot); const allSessions = logFiles.filter(logFile => /^\d{8}T\d{6}$/.test(logFile)); const oldSessions = allSessions.sort().filter(session => session !== currentLog); @@ -41,7 +42,7 @@ export class LogsDataCleaner extends Disposable { if (sessionsToDelete.length > 0) { this.logService.trace(`[logs cleanup]: Removing log folders '${sessionsToDelete.join(', ')}'`); - await Promise.all(sessionsToDelete.map(sessionToDelete => Promises.rm(joinPath(logsRoot, sessionToDelete).fsPath))); + await Promise.all(sessionsToDelete.map(sessionToDelete => Promises.rm(join(logsRoot, sessionToDelete)))); } } catch (error) { onUnexpectedError(error); diff --git a/src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts b/src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts index fc3f2eb117a..da67be66109 100644 --- a/src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts +++ b/src/vs/code/node/sharedProcess/contrib/storageDataCleaner.ts @@ -15,6 +15,7 @@ import { EXTENSION_DEVELOPMENT_EMPTY_WINDOW_WORKSPACE } from 'vs/platform/worksp import { NON_EMPTY_WORKSPACE_ID_LENGTH } from 'vs/platform/workspaces/node/workspaces'; import { INativeHostService } from 'vs/platform/native/common/native'; import { IMainProcessService } from 'vs/platform/ipc/common/mainProcessService'; +import { Schemas } from 'vs/base/common/network'; export class UnusedWorkspaceStorageDataCleaner extends Disposable { @@ -36,11 +37,12 @@ export class UnusedWorkspaceStorageDataCleaner extends Disposable { this.logService.trace('[storage cleanup]: Starting to clean up workspace storage folders for unused empty workspaces.'); try { - const workspaceStorageFolders = await Promises.readdir(this.environmentService.workspaceStorageHome.fsPath); + const workspaceStorageHome = this.environmentService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath; + const workspaceStorageFolders = await Promises.readdir(workspaceStorageHome); const storageClient = new StorageClient(this.mainProcessService.getChannel('storage')); await Promise.all(workspaceStorageFolders.map(async workspaceStorageFolder => { - const workspaceStoragePath = join(this.environmentService.workspaceStorageHome.fsPath, workspaceStorageFolder); + const workspaceStoragePath = join(workspaceStorageHome, workspaceStorageFolder); if (workspaceStorageFolder.length === NON_EMPTY_WORKSPACE_ID_LENGTH) { return; // keep workspace storage for folders/workspaces that can be accessed still diff --git a/src/vs/platform/protocol/electron-main/protocolMainService.ts b/src/vs/platform/protocol/electron-main/protocolMainService.ts index 79d431b275c..2b0a52627a8 100644 --- a/src/vs/platform/protocol/electron-main/protocolMainService.ts +++ b/src/vs/platform/protocol/electron-main/protocolMainService.ts @@ -39,8 +39,8 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ // - storage : all files in global and workspace storage (https://github.com/microsoft/vscode/issues/116735) this.addValidFileRoot(environmentService.appRoot); this.addValidFileRoot(environmentService.extensionsPath); - this.addValidFileRoot(userDataProfilesService.defaultProfile.globalStorageHome.fsPath); - this.addValidFileRoot(environmentService.workspaceStorageHome.fsPath); + this.addValidFileRoot(userDataProfilesService.defaultProfile.globalStorageHome.with({ scheme: Schemas.file }).fsPath); + this.addValidFileRoot(environmentService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath); // Handle protocols this.handleProtocols(); diff --git a/src/vs/platform/storage/common/storageService.ts b/src/vs/platform/storage/common/storageService.ts index d5231239e0c..4cfe09ec6d4 100644 --- a/src/vs/platform/storage/common/storageService.ts +++ b/src/vs/platform/storage/common/storageService.ts @@ -5,6 +5,7 @@ import { Promises } from 'vs/base/common/async'; import { DisposableStore } from 'vs/base/common/lifecycle'; +import { Schemas } from 'vs/base/common/network'; import { joinPath } from 'vs/base/common/resources'; import { IStorage, Storage } from 'vs/base/parts/storage/common/storage'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; @@ -117,11 +118,11 @@ export class RemoteStorageService extends AbstractStorageService { protected getLogDetails(scope: StorageScope): string | undefined { switch (scope) { case StorageScope.APPLICATION: - return this.applicationStorageProfile.globalStorageHome.fsPath; + return this.applicationStorageProfile.globalStorageHome.with({ scheme: Schemas.file }).fsPath; case StorageScope.PROFILE: - return this.profileStorageProfile?.globalStorageHome.fsPath; + return this.profileStorageProfile?.globalStorageHome.with({ scheme: Schemas.file }).fsPath; default: - return this.workspaceStorageId ? `${joinPath(this.environmentService.workspaceStorageHome, this.workspaceStorageId, 'state.vscdb').fsPath}` : undefined; + return this.workspaceStorageId ? `${joinPath(this.environmentService.workspaceStorageHome, this.workspaceStorageId, 'state.vscdb').with({ scheme: Schemas.file }).fsPath}` : undefined; } } diff --git a/src/vs/platform/storage/electron-main/storageMain.ts b/src/vs/platform/storage/electron-main/storageMain.ts index 6acc9643b91..b993f4cb3cd 100644 --- a/src/vs/platform/storage/electron-main/storageMain.ts +++ b/src/vs/platform/storage/electron-main/storageMain.ts @@ -20,6 +20,7 @@ import { IS_NEW_KEY } from 'vs/platform/storage/common/storage'; import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; import { currentSessionDateStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; import { isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; +import { Schemas } from 'vs/base/common/network'; export interface IStorageMainOptions { @@ -275,7 +276,7 @@ class BaseProfileAwareStorageMain extends BaseStorageMain { get path(): string | undefined { if (!this.options.useInMemoryStorage) { - return join(this.profile.globalStorageHome.fsPath, BaseProfileAwareStorageMain.STORAGE_NAME); + return join(this.profile.globalStorageHome.with({ scheme: Schemas.file }).fsPath, BaseProfileAwareStorageMain.STORAGE_NAME); } return undefined; @@ -352,7 +353,7 @@ export class WorkspaceStorageMain extends BaseStorageMain { get path(): string | undefined { if (!this.options.useInMemoryStorage) { - return join(this.environmentService.workspaceStorageHome.fsPath, this.workspace.id, WorkspaceStorageMain.WORKSPACE_STORAGE_NAME); + return join(this.environmentService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath, this.workspace.id, WorkspaceStorageMain.WORKSPACE_STORAGE_NAME); } return undefined; @@ -384,7 +385,7 @@ export class WorkspaceStorageMain extends BaseStorageMain { } // Otherwise, ensure the storage folder exists on disk - const workspaceStorageFolderPath = join(this.environmentService.workspaceStorageHome.fsPath, this.workspace.id); + const workspaceStorageFolderPath = join(this.environmentService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath, this.workspace.id); const workspaceStorageDatabasePath = join(workspaceStorageFolderPath, WorkspaceStorageMain.WORKSPACE_STORAGE_NAME); const storageExists = await Promises.exists(workspaceStorageFolderPath); diff --git a/src/vs/platform/storage/electron-main/storageMainService.ts b/src/vs/platform/storage/electron-main/storageMainService.ts index dc8b3c51e59..bdfad4eacb6 100644 --- a/src/vs/platform/storage/electron-main/storageMainService.ts +++ b/src/vs/platform/storage/electron-main/storageMainService.ts @@ -19,6 +19,7 @@ import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userData import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile'; import { IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; +import { Schemas } from 'vs/base/common/network'; //#region Storage Main Service (intent: make application, profile and workspace storage accessible to windows from main process) @@ -359,7 +360,7 @@ export class ApplicationStorageMainService extends AbstractStorageService implem protected getLogDetails(scope: StorageScope): string | undefined { if (scope === StorageScope.APPLICATION) { - return this.userDataProfilesService.defaultProfile.globalStorageHome.fsPath; + return this.userDataProfilesService.defaultProfile.globalStorageHome.with({ scheme: Schemas.file }).fsPath; } return undefined; // any other scope is unsupported from main process diff --git a/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts b/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts index a1599f50737..8c74c72b9c9 100644 --- a/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts +++ b/src/vs/platform/terminal/electron-main/electronPtyHostStarter.ts @@ -18,6 +18,7 @@ import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecy import { Emitter } from 'vs/base/common/event'; import { deepClone } from 'vs/base/common/objects'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { Schemas } from 'vs/base/common/network'; export class ElectronPtyHostStarter extends Disposable implements IPtyHostStarter { @@ -58,7 +59,7 @@ export class ElectronPtyHostStarter extends Disposable implements IPtyHostStarte type: 'ptyHost', entryPoint: 'vs/platform/terminal/node/ptyHostMain', execArgv, - args: ['--logsPath', this._environmentMainService.logsHome.fsPath], + args: ['--logsPath', this._environmentMainService.logsHome.with({ scheme: Schemas.file }).fsPath], env: this._createPtyHostConfiguration() }); diff --git a/src/vs/platform/terminal/node/nodePtyHostStarter.ts b/src/vs/platform/terminal/node/nodePtyHostStarter.ts index a1d4e8b7d88..d5a1a43724a 100644 --- a/src/vs/platform/terminal/node/nodePtyHostStarter.ts +++ b/src/vs/platform/terminal/node/nodePtyHostStarter.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { FileAccess } from 'vs/base/common/network'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import { Client, IIPCOptions } from 'vs/base/parts/ipc/node/ipc.cp'; import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; import { parsePtyHostDebugPort } from 'vs/platform/environment/node/environmentService'; @@ -22,7 +22,7 @@ export class NodePtyHostStarter extends Disposable implements IPtyHostStarter { start(): IPtyHostConnection { const opts: IIPCOptions = { serverName: 'Pty Host', - args: ['--type=ptyHost', '--logsPath', this._environmentService.logsHome.fsPath], + args: ['--type=ptyHost', '--logsPath', this._environmentService.logsHome.with({ scheme: Schemas.file }).fsPath], env: { VSCODE_AMD_ENTRYPOINT: 'vs/platform/terminal/node/ptyHostMain', VSCODE_PIPE_LOGGING: 'true', diff --git a/src/vs/platform/windows/electron-main/windowsMainService.ts b/src/vs/platform/windows/electron-main/windowsMainService.ts index 022a20e4ee0..67d7113b000 100644 --- a/src/vs/platform/windows/electron-main/windowsMainService.ts +++ b/src/vs/platform/windows/electron-main/windowsMainService.ts @@ -1401,8 +1401,8 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic profile: defaultProfile }, - homeDir: this.environmentMainService.userHome.fsPath, - tmpDir: this.environmentMainService.tmpDir.fsPath, + homeDir: this.environmentMainService.userHome.with({ scheme: Schemas.file }).fsPath, + tmpDir: this.environmentMainService.tmpDir.with({ scheme: Schemas.file }).fsPath, userDataDir: this.environmentMainService.userDataPath, remoteAuthority: options.remoteAuthority, @@ -1419,7 +1419,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic window: [], global: this.loggerService.getRegisteredLoggers() }, - logsPath: this.environmentMainService.logsHome.fsPath, + logsPath: this.environmentMainService.logsHome.with({ scheme: Schemas.file }).fsPath, product, isInitialStartup: options.initialStartup, diff --git a/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts b/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts index 34913c5ffc5..1d482c3eba4 100644 --- a/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts +++ b/src/vs/platform/workspaces/electron-main/workspacesManagementMainService.ts @@ -84,7 +84,7 @@ export class WorkspacesManagementMainService extends Disposable implements IWork // Resolve untitled workspaces try { - const untitledWorkspacePaths = (await Promises.readdir(this.untitledWorkspacesHome.fsPath)).map(folder => joinPath(this.untitledWorkspacesHome, folder, UNTITLED_WORKSPACE_NAME)); + const untitledWorkspacePaths = (await Promises.readdir(this.untitledWorkspacesHome.with({ scheme: Schemas.file }).fsPath)).map(folder => joinPath(this.untitledWorkspacesHome, folder, UNTITLED_WORKSPACE_NAME));// for (const untitledWorkspacePath of untitledWorkspacePaths) { const workspace = getWorkspaceIdentifier(untitledWorkspacePath); const resolvedWorkspace = await this.resolveLocalWorkspace(untitledWorkspacePath); @@ -227,7 +227,7 @@ export class WorkspacesManagementMainService extends Disposable implements IWork await Promises.rm(dirname(configPath)); // Mark Workspace Storage to be deleted - const workspaceStoragePath = join(this.environmentMainService.workspaceStorageHome.fsPath, workspace.id); + const workspaceStoragePath = join(this.environmentMainService.workspaceStorageHome.with({ scheme: Schemas.file }).fsPath, workspace.id); if (await Promises.exists(workspaceStoragePath)) { await Promises.writeFile(join(workspaceStoragePath, 'obsolete'), ''); } diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index d291af5dd1c..7e568185997 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -100,7 +100,7 @@ export async function setupServerServices(connectionToken: ServerConnectionToken const logger = loggerService.createLogger('remoteagent', { name: localize('remoteExtensionLog', "Server") }); const logService = new LogService(logger, [new ServerLogger(getLogLevel(environmentService))]); services.set(ILogService, logService); - setTimeout(() => cleanupOlderLogs(environmentService.logsHome.fsPath).then(null, err => logService.error(err)), 10000); + setTimeout(() => cleanupOlderLogs(environmentService.logsHome.with({ scheme: Schemas.file }).fsPath).then(null, err => logService.error(err)), 10000); logService.onDidChangeLogLevel(logLevel => log(logService, logLevel, `Log level changed to ${LogLevelToString(logService.getLevel())}`)); logService.trace(`Remote configuration data at ${REMOTE_DATA_FOLDER}`); diff --git a/src/vs/workbench/contrib/files/electron-sandbox/fileCommands.ts b/src/vs/workbench/contrib/files/electron-sandbox/fileCommands.ts index eb3744a25a3..4f62c9c804c 100644 --- a/src/vs/workbench/contrib/files/electron-sandbox/fileCommands.ts +++ b/src/vs/workbench/contrib/files/electron-sandbox/fileCommands.ts @@ -15,7 +15,7 @@ export function revealResourcesInOS(resources: URI[], nativeHostService: INative if (resources.length) { sequence(resources.map(r => async () => { if (r.scheme === Schemas.file || r.scheme === Schemas.vscodeUserData) { - nativeHostService.showItemInFolder(r.fsPath); + nativeHostService.showItemInFolder(r.with({ scheme: Schemas.file }).fsPath); } })); } else if (workspaceContextService.getWorkspace().folders.length) { diff --git a/src/vs/workbench/contrib/localHistory/electron-sandbox/localHistoryCommands.ts b/src/vs/workbench/contrib/localHistory/electron-sandbox/localHistoryCommands.ts index 9ac4e2cd92f..20d20356e6e 100644 --- a/src/vs/workbench/contrib/localHistory/electron-sandbox/localHistoryCommands.ts +++ b/src/vs/workbench/contrib/localHistory/electron-sandbox/localHistoryCommands.ts @@ -39,7 +39,7 @@ registerAction2(class extends Action2 { const { entry } = await findLocalHistoryEntry(workingCopyHistoryService, item); if (entry) { - await nativeHostService.showItemInFolder(entry.location.fsPath); + await nativeHostService.showItemInFolder(entry.location.with({ scheme: Schemas.file }).fsPath); } } }); diff --git a/src/vs/workbench/contrib/logs/electron-sandbox/logsActions.ts b/src/vs/workbench/contrib/logs/electron-sandbox/logsActions.ts index 3a057d2b8b9..cbc2a01dbb5 100644 --- a/src/vs/workbench/contrib/logs/electron-sandbox/logsActions.ts +++ b/src/vs/workbench/contrib/logs/electron-sandbox/logsActions.ts @@ -9,6 +9,7 @@ import { INativeHostService } from 'vs/platform/native/common/native'; import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService'; import { IFileService } from 'vs/platform/files/common/files'; import { joinPath } from 'vs/base/common/resources'; +import { Schemas } from 'vs/base/common/network'; export class OpenLogsFolderAction extends Action { @@ -23,7 +24,7 @@ export class OpenLogsFolderAction extends Action { } override run(): Promise { - return this.nativeHostService.showItemInFolder(joinPath(this.environmentService.logsHome, 'main.log').fsPath); + return this.nativeHostService.showItemInFolder(joinPath(this.environmentService.logsHome, 'main.log').with({ scheme: Schemas.file }).fsPath); } } @@ -43,7 +44,7 @@ export class OpenExtensionLogsFolderAction extends Action { override async run(): Promise { const folderStat = await this.fileService.resolve(this.environmentSerice.extHostLogsPath); if (folderStat.children && folderStat.children[0]) { - return this.nativeHostService.showItemInFolder(folderStat.children[0].resource.fsPath); + return this.nativeHostService.showItemInFolder(folderStat.children[0].resource.with({ scheme: Schemas.file }).fsPath); } } } diff --git a/src/vs/workbench/contrib/userDataSync/electron-sandbox/userDataSync.contribution.ts b/src/vs/workbench/contrib/userDataSync/electron-sandbox/userDataSync.contribution.ts index 644e1ad6dec..abbf3cfc882 100644 --- a/src/vs/workbench/contrib/userDataSync/electron-sandbox/userDataSync.contribution.ts +++ b/src/vs/workbench/contrib/userDataSync/electron-sandbox/userDataSync.contribution.ts @@ -17,6 +17,7 @@ import { IFileService } from 'vs/platform/files/common/files'; import { INativeHostService } from 'vs/platform/native/common/native'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { CONTEXT_SYNC_STATE, SYNC_TITLE } from 'vs/workbench/services/userDataSync/common/userDataSync'; +import { Schemas } from 'vs/base/common/network'; class UserDataSyncServicesContribution implements IWorkbenchContribution { @@ -51,7 +52,7 @@ registerAction2(class OpenSyncBackupsFolder extends Action2 { if (await fileService.exists(syncHome)) { const folderStat = await fileService.resolve(syncHome); const item = folderStat.children && folderStat.children[0] ? folderStat.children[0].resource : syncHome; - return nativeHostService.showItemInFolder(item.fsPath); + return nativeHostService.showItemInFolder(item.with({ scheme: Schemas.file }).fsPath); } else { notificationService.info(localize('no backups', "Local backups folder does not exist")); } From 7545ee2ec46897d2b7ce3c6d591f636962455c9a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 1 Sep 2023 16:31:57 +0200 Subject: [PATCH 186/198] Creating a new empty editor group can leave focus in inactive group (fix #189256) (#191996) --- .../api/browser/mainThreadEditorTabs.ts | 2 +- .../workbench/browser/parts/editor/editor.ts | 4 +- .../browser/parts/editor/editorActions.ts | 24 +++++++-- .../browser/parts/editor/editorPart.ts | 50 +++++++++---------- .../browser/gettingStarted.ts | 3 +- .../editor/common/editorGroupsService.ts | 7 +-- .../test/browser/editorGroupsService.test.ts | 3 +- .../test/browser/workbenchTestServices.ts | 6 +-- 8 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts index f1d2d01597f..3da6c5ed51d 100644 --- a/src/vs/workbench/api/browser/mainThreadEditorTabs.ts +++ b/src/vs/workbench/api/browser/mainThreadEditorTabs.ts @@ -575,7 +575,7 @@ export class MainThreadEditorTabs implements MainThreadEditorTabsShape { if (viewColumn === SIDE_GROUP) { direction = preferredSideBySideGroupDirection(this._configurationService); } - targetGroup = this._editorGroupsService.addGroup(this._editorGroupsService.groups[this._editorGroupsService.groups.length - 1], direction, undefined); + targetGroup = this._editorGroupsService.addGroup(this._editorGroupsService.groups[this._editorGroupsService.groups.length - 1], direction); } else { targetGroup = this._editorGroupsService.getGroup(groupId); } diff --git a/src/vs/workbench/browser/parts/editor/editor.ts b/src/vs/workbench/browser/parts/editor/editor.ts index 68f64a44162..23f3371411a 100644 --- a/src/vs/workbench/browser/parts/editor/editor.ts +++ b/src/vs/workbench/browser/parts/editor/editor.ts @@ -5,7 +5,7 @@ import { GroupIdentifier, IWorkbenchEditorConfiguration, IEditorIdentifier, IEditorCloseEvent, IEditorPartOptions, IEditorPartOptionsChangeEvent, SideBySideEditor, EditorCloseContext } from 'vs/workbench/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; -import { IEditorGroup, GroupDirection, IAddGroupOptions, IMergeGroupOptions, GroupsOrder, GroupsArrangement } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorGroup, GroupDirection, IMergeGroupOptions, GroupsOrder, GroupsArrangement } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IDisposable } from 'vs/base/common/lifecycle'; import { Dimension } from 'vs/base/browser/dom'; import { Event } from 'vs/base/common/event'; @@ -96,7 +96,7 @@ export interface IEditorGroupsAccessor { activateGroup(identifier: IEditorGroupView | GroupIdentifier): IEditorGroupView; restoreGroup(identifier: IEditorGroupView | GroupIdentifier): IEditorGroupView; - addGroup(location: IEditorGroupView | GroupIdentifier, direction: GroupDirection, options?: IAddGroupOptions): IEditorGroupView; + addGroup(location: IEditorGroupView | GroupIdentifier, direction: GroupDirection): IEditorGroupView; mergeGroup(group: IEditorGroupView | GroupIdentifier, target: IEditorGroupView | GroupIdentifier, options?: IMergeGroupOptions): IEditorGroupView; moveGroup(group: IEditorGroupView | GroupIdentifier, location: IEditorGroupView | GroupIdentifier, direction: GroupDirection): IEditorGroupView; diff --git a/src/vs/workbench/browser/parts/editor/editorActions.ts b/src/vs/workbench/browser/parts/editor/editorActions.ts index e13b41e522f..bcb01677992 100644 --- a/src/vs/workbench/browser/parts/editor/editorActions.ts +++ b/src/vs/workbench/browser/parts/editor/editorActions.ts @@ -2263,13 +2263,27 @@ abstract class AbstractCreateEditorGroupAction extends Action2 { override async run(accessor: ServicesAccessor): Promise { const editorGroupService = accessor.get(IEditorGroupsService); + const layoutService = accessor.get(IWorkbenchLayoutService); - // We intentionally do not want the new group to be focussed so that - // a user can have keyboard focus e.g. in a tree/list, open a new - // editor group that is active and then arrow-up/down in the tree/list - // to pick an editor to open in that group + // We are about to create a new empty editor group. We make an opiniated + // decision here whether to focus that new editor group or not based + // on what is currently focused. If focus is outside the editor area not + // in the , we do not focus, with the rationale that a user might + // have focus on a tree/list with the intention to pick an element to + // open in the new group from that tree/list. + // + // If focus is inside the editor area, we want to prevent the situation + // of an editor having keyboard focus in an inactive editor group + // (see https://github.com/microsoft/vscode/issues/189256) - editorGroupService.addGroup(editorGroupService.activeGroup, this.direction, { activate: true }); + const focusNewGroup = layoutService.hasFocus(Parts.EDITOR_PART) || document.activeElement === document.body; + + const group = editorGroupService.addGroup(editorGroupService.activeGroup, this.direction); + editorGroupService.activateGroup(group); + + if (focusNewGroup) { + group.focus(); + } } } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 8b733caa867..af10ae9c109 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -8,7 +8,7 @@ import { Part } from 'vs/workbench/browser/part'; import { Dimension, isAncestor, $, EventHelper, addDisposableGenericMouseDownListener } from 'vs/base/browser/dom'; import { Event, Emitter, Relay } from 'vs/base/common/event'; import { contrastBorder, editorBackground } from 'vs/platform/theme/common/colorRegistry'; -import { GroupDirection, IAddGroupOptions, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, GroupsOrder, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument, IEditorGroupsService, IEditorSideGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { GroupDirection, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, GroupsOrder, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument, IEditorGroupsService, IEditorSideGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IView, orthogonal, LayoutPriority, IViewSize, Direction, SerializableGrid, Sizing, ISerializedGrid, ISerializedNode, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid'; import { GroupIdentifier, EditorInputWithOptions, IEditorPartOptions, IEditorPartOptionsChangeEvent, GroupModelChangeKind } from 'vs/workbench/common/editor'; @@ -328,7 +328,6 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro const groupView = this.assertGroupView(group); this.doSetGroupActive(groupView); - this._onDidActivateGroup.fire(groupView); return groupView; } @@ -512,17 +511,13 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro return false; } - addGroup(location: IEditorGroupView | GroupIdentifier, direction: GroupDirection, options?: IAddGroupOptions): IEditorGroupView { + addGroup(location: IEditorGroupView | GroupIdentifier, direction: GroupDirection): IEditorGroupView { const locationView = this.assertGroupView(location); const restoreFocus = this.shouldRestoreFocus(locationView.element); const group = this.doAddGroup(locationView, direction); - if (options?.activate) { - this.doSetGroupActive(group); - } - // Restore focus if we had it previously after completing the grid // operation. That operation might cause reparenting of grid views // which moves focus to the element otherwise. @@ -622,27 +617,30 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } private doSetGroupActive(group: IEditorGroupView): void { - if (this._activeGroup === group) { - return; // return if this is already the active group + if (this._activeGroup !== group) { + const previousActiveGroup = this._activeGroup; + this._activeGroup = group; + + // Update list of most recently active groups + this.doUpdateMostRecentActive(group, true); + + // Mark previous one as inactive + previousActiveGroup?.setActive(false); + + // Mark group as new active + group.setActive(true); + + // Maximize the group if it is currently minimized + this.doRestoreGroup(group); + + // Event + this._onDidChangeActiveGroup.fire(group); } - const previousActiveGroup = this._activeGroup; - this._activeGroup = group; - - // Update list of most recently active groups - this.doUpdateMostRecentActive(group, true); - - // Mark previous one as inactive - previousActiveGroup?.setActive(false); - - // Mark group as new active - group.setActive(true); - - // Maximize the group if it is currently minimized - this.doRestoreGroup(group); - - // Event - this._onDidChangeActiveGroup.fire(group); + // Always fire the event that a group has been activated + // even if its the same group that is already active to + // signal the intent even when nothing has changed. + this._onDidActivateGroup.fire(group); } private doRestoreGroup(group: IEditorGroupView): void { diff --git a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts index 04283236ddd..d42c329a868 100644 --- a/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts @@ -1229,7 +1229,8 @@ export class GettingStartedPage extends EditorPane { if (toSide && fullSize.width > 700) { if (this.groupsService.count === 1) { - this.groupsService.addGroup(this.groupsService.groups[0], GroupDirection.RIGHT, { activate: true }); + const sideGroup = this.groupsService.addGroup(this.groupsService.groups[0], GroupDirection.RIGHT); + this.groupsService.activateGroup(sideGroup); const gettingStartedSize = Math.floor(fullSize.width / 2); diff --git a/src/vs/workbench/services/editor/common/editorGroupsService.ts b/src/vs/workbench/services/editor/common/editorGroupsService.ts index e2021cc43ad..12a0b1cab6f 100644 --- a/src/vs/workbench/services/editor/common/editorGroupsService.ts +++ b/src/vs/workbench/services/editor/common/editorGroupsService.ts @@ -91,10 +91,6 @@ export interface EditorGroupLayout { groups: GroupLayoutArgument[]; } -export interface IAddGroupOptions { - activate?: boolean; -} - export const enum MergeGroupMode { COPY_EDITORS, MOVE_EDITORS @@ -364,9 +360,8 @@ export interface IEditorGroupsService { * * @param location the group from which to split to add a new group * @param direction the direction of where to split to - * @param options configure the newly group with options */ - addGroup(location: IEditorGroup | GroupIdentifier, direction: GroupDirection, options?: IAddGroupOptions): IEditorGroup; + addGroup(location: IEditorGroup | GroupIdentifier, direction: GroupDirection): IEditorGroup; /** * Remove a group from the editor area. diff --git a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts index 24f173d1c66..e05cee676fc 100644 --- a/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts +++ b/src/vs/workbench/services/editor/test/browser/editorGroupsService.test.ts @@ -320,7 +320,8 @@ suite('EditorGroupsService', () => { const input = new TestFileEditorInput(URI.file('foo/bar'), TEST_EDITOR_INPUT_ID); await rootGroup.openEditor(input, { pinned: true }); - const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT, { activate: true }); + const rightGroup = part.addGroup(rootGroup, GroupDirection.RIGHT); + part.activateGroup(rightGroup); const downGroup = part.copyGroup(rootGroup, rightGroup, GroupDirection.DOWN); assert.strictEqual(groupAddedCounter, 2); assert.strictEqual(downGroup.count, 1); diff --git a/src/vs/workbench/test/browser/workbenchTestServices.ts b/src/vs/workbench/test/browser/workbenchTestServices.ts index c566bc46401..ed87b23c2ba 100644 --- a/src/vs/workbench/test/browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/browser/workbenchTestServices.ts @@ -52,7 +52,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IDecorationsService, IResourceDecorationChangeEvent, IDecoration, IDecorationData, IDecorationsProvider } from 'vs/workbench/services/decorations/common/decorations'; import { IDisposable, toDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IAddGroupOptions, IMergeGroupOptions, IEditorReplacement, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { IEditorGroupsService, IEditorGroup, GroupsOrder, GroupsArrangement, GroupDirection, IMergeGroupOptions, IEditorReplacement, IFindGroupScope, EditorGroupLayout, ICloseEditorOptions, GroupOrientation, ICloseAllEditorsOptions, ICloseEditorsFilter } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorService, ISaveEditorsOptions, IRevertAllEditorsOptions, PreferredGroup, IEditorsChangeEvent, ISaveEditorsResult } from 'vs/workbench/services/editor/common/editorService'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { IEditorPaneRegistry, EditorPaneDescriptor } from 'vs/workbench/browser/editor'; @@ -848,7 +848,7 @@ export class TestEditorGroupsService implements IEditorGroupsService { applyLayout(_layout: EditorGroupLayout): void { } getLayout(): EditorGroupLayout { throw new Error('not implemented'); } setGroupOrientation(_orientation: GroupOrientation): void { } - addGroup(_location: number | IEditorGroup, _direction: GroupDirection, _options?: IAddGroupOptions): IEditorGroup { throw new Error('not implemented'); } + addGroup(_location: number | IEditorGroup, _direction: GroupDirection): IEditorGroup { throw new Error('not implemented'); } removeGroup(_group: number | IEditorGroup): void { } moveGroup(_group: number | IEditorGroup, _location: number | IEditorGroup, _direction: GroupDirection): IEditorGroup { throw new Error('not implemented'); } mergeGroup(_group: number | IEditorGroup, _target: number | IEditorGroup, _options?: IMergeGroupOptions): IEditorGroup { throw new Error('not implemented'); } @@ -946,7 +946,7 @@ export class TestEditorGroupAccessor implements IEditorGroupsAccessor { getGroups(order: GroupsOrder): IEditorGroupView[] { throw new Error('Method not implemented.'); } activateGroup(identifier: number | IEditorGroupView): IEditorGroupView { throw new Error('Method not implemented.'); } restoreGroup(identifier: number | IEditorGroupView): IEditorGroupView { throw new Error('Method not implemented.'); } - addGroup(location: number | IEditorGroupView, direction: GroupDirection, options?: IAddGroupOptions | undefined): IEditorGroupView { throw new Error('Method not implemented.'); } + addGroup(location: number | IEditorGroupView, direction: GroupDirection): IEditorGroupView { throw new Error('Method not implemented.'); } mergeGroup(group: number | IEditorGroupView, target: number | IEditorGroupView, options?: IMergeGroupOptions | undefined): IEditorGroupView { throw new Error('Method not implemented.'); } moveGroup(group: number | IEditorGroupView, location: number | IEditorGroupView, direction: GroupDirection): IEditorGroupView { throw new Error('Method not implemented.'); } copyGroup(group: number | IEditorGroupView, location: number | IEditorGroupView, direction: GroupDirection): IEditorGroupView { throw new Error('Method not implemented.'); } From 9ee5a2123dc1ef1e407c499aac1c296ba03eb1c4 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 1 Sep 2023 16:37:19 +0200 Subject: [PATCH 187/198] [Accessibility] Consider providing the default keybinding for notifications.showList (fix #191784) (#191997) --- .../parts/notifications/notificationsCommands.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts index 52910366b5f..6d02c45b4ca 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationsCommands.ts @@ -6,7 +6,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; -import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; +import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { INotificationViewItem, isNotificationViewItem, NotificationsModel } from 'vs/workbench/common/notifications'; import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { localize } from 'vs/nls'; @@ -90,9 +90,15 @@ export function getNotificationFromContext(listService: IListService, context?: export function registerNotificationCommands(center: INotificationsCenterController, toasts: INotificationsToastController, model: NotificationsModel): void { // Show Notifications Cneter - CommandsRegistry.registerCommand(SHOW_NOTIFICATIONS_CENTER, () => { - toasts.hide(); - center.show(); + KeybindingsRegistry.registerCommandAndKeybindingRule({ + id: SHOW_NOTIFICATIONS_CENTER, + weight: KeybindingWeight.WorkbenchContrib, + when: NotificationsCenterVisibleContext.negate(), + primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyN), + handler: () => { + toasts.hide(); + center.show(); + } }); // Hide Notifications Center From 37390a84c6bf3a7118bb9c9618e5ad402919dc28 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 1 Sep 2023 16:40:31 +0200 Subject: [PATCH 188/198] editors - call `focus` before `activate` to preserve activation (#191991) --- src/vs/workbench/browser/parts/editor/editorPart.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index af10ae9c109..d8250c91f15 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -525,6 +525,10 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro locationView.focus(); } + if (options?.activate) { + this.doSetGroupActive(group); + } + return group; } From 14555a512349eb06555e5ae78384bd1fc46ea2e5 Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Fri, 1 Sep 2023 16:40:42 +0200 Subject: [PATCH 189/198] app - ensure to remove `windowId=_blank` from protocol links (fix #191902) (#191990) --- src/vs/code/electron-main/app.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index c6536298e05..49f3c2703cd 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -774,7 +774,17 @@ export class CodeApplication extends Disposable { if (secondSlash !== -1) { const authority = uri.path.substring(1, secondSlash); const path = uri.path.substring(secondSlash); - const remoteUri = URI.from({ scheme: Schemas.vscodeRemote, authority, path, query: uri.query, fragment: uri.fragment }); + + let query = uri.query; + const params = new URLSearchParams(uri.query); + if (params.get('windowId') === '_blank') { + // Make sure to unset any `windowId=_blank` here + // https://github.com/microsoft/vscode/issues/191902 + params.delete('windowId'); + query = params.toString(); + } + + const remoteUri = URI.from({ scheme: Schemas.vscodeRemote, authority, path, query, fragment: uri.fragment }); if (hasWorkspaceFileExtension(path)) { return { workspaceUri: remoteUri }; From be570fd3de6ecf0935a6d8e188e4a47ae457448d Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Fri, 1 Sep 2023 16:40:56 +0200 Subject: [PATCH 190/198] Git - Bump which package (#191992) --- extensions/git/package.json | 2 +- extensions/git/yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 37212410bfe..9ad1978be0e 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -3012,7 +3012,7 @@ "jschardet": "3.0.0", "picomatch": "2.3.1", "vscode-uri": "^2.0.0", - "which": "3.0.1" + "which": "4.0.0" }, "devDependencies": { "@types/byline": "4.2.31", diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index bb3a09d947c..0b62d7472be 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -516,10 +516,10 @@ is-core-module@^2.13.0: dependencies: has "^1.0.3" -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= +isexe@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" + integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== jschardet@3.0.0: version "3.0.0" @@ -679,12 +679,12 @@ vscode-uri@^2.0.0: resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.0.tgz#2df704222f72b8a71ff266ba0830ed6c51ac1542" integrity sha512-lWXWofDSYD8r/TIyu64MdwB4FaSirQ608PP/TzUyslyOeHGwQ0eTHUZeJrK1ILOmwUHaJtV693m2JoUYroUDpw== -which@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" - integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== +which@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a" + integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg== dependencies: - isexe "^2.0.0" + isexe "^3.1.1" yallist@^4.0.0: version "4.0.0" From 04f02b504323d91a2eed9d827163b713a1a47859 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 Sep 2023 16:53:04 +0200 Subject: [PATCH 191/198] fix https://github.com/microsoft/vscode/issues/191908 --- .../codelens/browser/codelensController.ts | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/codelens/browser/codelensController.ts b/src/vs/editor/contrib/codelens/browser/codelensController.ts index 4fd3619fb51..da810c9a099 100644 --- a/src/vs/editor/contrib/codelens/browser/codelensController.ts +++ b/src/vs/editor/contrib/codelens/browser/codelensController.ts @@ -232,6 +232,9 @@ export class CodeLensContribution implements IEditorContribution { this._localToDispose.add(this._editor.onDidFocusEditorWidget(() => { scheduler.schedule(); })); + this._localToDispose.add(this._editor.onDidBlurEditorText(() => { + scheduler.cancel(); + })); this._localToDispose.add(this._editor.onDidScrollChange(e => { if (e.scrollTopChanged && this._lenses.length > 0) { this._resolveCodeLensesInViewportSoon(); @@ -444,8 +447,12 @@ export class CodeLensContribution implements IEditorContribution { }); } - getModel(): CodeLensModel | undefined { - return this._currentCodeLensModel; + async getModel(): Promise { + await this._getCodeLensModelPromise; + await this._resolveCodeLensesPromise; + return !this._currentCodeLensModel?.isDisposed + ? this._currentCodeLensModel + : undefined; } } @@ -478,7 +485,7 @@ registerEditorAction(class ShowLensesInCurrentLine extends EditorAction { return; } - const model = codelensController.getModel(); + const model = await codelensController.getModel(); if (!model) { // nothing return; @@ -499,19 +506,31 @@ registerEditorAction(class ShowLensesInCurrentLine extends EditorAction { return; } - const item = await quickInputService.pick(items, { canPickMany: false }); + const item = await quickInputService.pick(items, { + canPickMany: false, + placeHolder: localize('placeHolder', "Select a command") + }); if (!item) { // Nothing picked return; } + let command = item.command; + if (model.isDisposed) { - // retry whenever the model has been disposed - return await commandService.executeCommand(this.id); + // try to find the same command again in-case the model has been re-created in the meantime + // this is a best attempt approach which shouldn't be needed because eager model re-creates + // shouldn't happen due to focus in/out anymore + const newModel = await codelensController.getModel(); + const newLens = newModel?.lenses.find(lens => lens.symbol.range.startLineNumber === lineNumber && lens.symbol.command?.title === command.title); + if (!newLens || !newLens.symbol.command) { + return; + } + command = newLens.symbol.command; } try { - await commandService.executeCommand(item.command.id, ...(item.command.arguments || [])); + await commandService.executeCommand(command.id, ...(command.arguments || [])); } catch (err) { notificationService.error(err); } From 812643de4b3679950a4e92bb19f3f2bb9c08bab4 Mon Sep 17 00:00:00 2001 From: Johannes Date: Fri, 1 Sep 2023 17:45:32 +0200 Subject: [PATCH 192/198] comment out not-compiling code, fyi @bpasero --- src/vs/workbench/browser/parts/editor/editorPart.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index d8250c91f15..0f868b4ad97 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -525,9 +525,9 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro locationView.focus(); } - if (options?.activate) { - this.doSetGroupActive(group); - } + // if (options?.activate) { + // this.doSetGroupActive(group); + // } return group; } From a8b8e3a143bfb1530b373af80db47e2424c00897 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 1 Sep 2023 09:38:20 -0700 Subject: [PATCH 193/198] forwarding: fix log format again (#191941) Fixes #191759 --- cli/src/log.rs | 4 ++-- extensions/tunnel-forwarding/src/extension.ts | 22 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cli/src/log.rs b/cli/src/log.rs index a7561a37f6c..1180f2c82c2 100644 --- a/cli/src/log.rs +++ b/cli/src/log.rs @@ -323,8 +323,8 @@ fn format(level: Level, prefix: &str, message: &str, use_colors: bool) -> String } pub fn emit(level: Level, prefix: &str, message: &str) { - let line = format(level, prefix, message, true); - if level == Level::Trace { + let line = format(level, prefix, message, *COLORS_ENABLED); + if level == Level::Trace && *COLORS_ENABLED { print!("\x1b[2m{}\x1b[0m", line); } else { print!("{}", line); diff --git a/extensions/tunnel-forwarding/src/extension.ts b/extensions/tunnel-forwarding/src/extension.ts index 83789934df5..f6ef85e71b1 100644 --- a/extensions/tunnel-forwarding/src/extension.ts +++ b/extensions/tunnel-forwarding/src/extension.ts @@ -231,8 +231,8 @@ class TunnelProvider implements vscode.TunnelProvider { ]; this.logger.log('info', '[forwarding] starting CLI'); - const process = spawn(cliPath, args, { stdio: 'pipe' }); - this.state = { state: State.Starting, process }; + const child = spawn(cliPath, args, { stdio: 'pipe', env: { ...process.env, NO_COLOR: '1' } }); + this.state = { state: State.Starting, process: child }; const progressP = new DeferredPromise(); vscode.window.withProgress( @@ -248,29 +248,29 @@ class TunnelProvider implements vscode.TunnelProvider { ); let lastPortFormat: string | undefined; - process.on('exit', status => { + child.on('exit', status => { const msg = `[forwarding] exited with code ${status}`; this.logger.log('info', msg); progressP.complete(); // make sure to clear progress on unexpected exit - if (this.isInStateWithProcess(process)) { + if (this.isInStateWithProcess(child)) { this.state = { state: State.Error, error: msg }; } }); - process.on('error', err => { + child.on('error', err => { this.logger.log('error', `[forwarding] ${err}`); progressP.complete(); // make sure to clear progress on unexpected exit - if (this.isInStateWithProcess(process)) { + if (this.isInStateWithProcess(child)) { this.state = { state: State.Error, error: String(err) }; } }); - process.stdout + child.stdout .pipe(splitNewLines()) .on('data', line => this.logger.log('info', `[forwarding] ${line}`)) .resume(); - process.stderr + child.stderr .pipe(splitNewLines()) .on('data', line => { try { @@ -278,7 +278,7 @@ class TunnelProvider implements vscode.TunnelProvider { if (l.port_format && l.port_format !== lastPortFormat) { this.state = { state: State.Active, - portFormat: l.port_format, process, + portFormat: l.port_format, process: child, cleanupTimeout: 'cleanupTimeout' in this.state ? this.state.cleanupTimeout : undefined, }; progressP.complete(); @@ -290,8 +290,8 @@ class TunnelProvider implements vscode.TunnelProvider { .resume(); await new Promise((resolve, reject) => { - process.on('spawn', resolve); - process.on('error', reject); + child.on('spawn', resolve); + child.on('error', reject); }); } } From 55b37e271d882fe28b41de79f0a6381ffd15112e Mon Sep 17 00:00:00 2001 From: Tyler James Leonhardt Date: Fri, 1 Sep 2023 10:02:14 -0700 Subject: [PATCH 194/198] Bump distro (#192006) for the removal of semantic similarity. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f473f744fc..4a0405868b6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.83.0", - "distro": "0a5805caff2d59440704a3bf75eebaa509be862f", + "distro": "46e7bb69af9f06de037c3d7e8f61de4a679f9ef1", "author": { "name": "Microsoft Corporation" }, From 2d502be79d044ed34fcea16eeb02cf98b789789c Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 1 Sep 2023 10:27:03 -0700 Subject: [PATCH 195/198] testing: compress single test messages in the Test Results tree view (#192011) Fixes #192010 --- .../testing/browser/testingOutputPeek.ts | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts index 6223c1c211f..f5e1fce889c 100644 --- a/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts +++ b/src/vs/workbench/contrib/testing/browser/testingOutputPeek.ts @@ -78,7 +78,6 @@ import { DetachedProcessInfo } from 'vs/workbench/contrib/terminal/browser/detac import { IDetachedTerminalInstance, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { getXtermScaledDimensions } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal'; import { TERMINAL_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; -import { flatTestItemDelimiter } from 'vs/workbench/contrib/testing/browser/explorerProjections/display'; import { getTestItemContextOverlay } from 'vs/workbench/contrib/testing/browser/explorerProjections/testItemContextOverlay'; import * as icons from 'vs/workbench/contrib/testing/browser/icons'; import { testingPeekBorder, testingPeekHeaderBackground } from 'vs/workbench/contrib/testing/browser/theme'; @@ -1704,15 +1703,7 @@ class TestCaseElement implements ITreeElement { private readonly task: ITestRunTask, public readonly test: TestResultItem, public readonly taskIndex: number, - ) { - for (const parent of resultItemParents(results, test)) { - if (parent !== test) { - this.description = this.description - ? parent.item.label + flatTestItemDelimiter + this.description - : parent.item.label; - } - } - } + ) { } } class TaskElement implements ITreeElement { @@ -1871,7 +1862,7 @@ class OutputPeekTree extends Disposable { return test.tasks[taskIndex].messages .map((m, messageIndex) => m.type === TestMessageType.Error - ? { element: cc.getOrCreate(m, () => new TestMessageElement(result, test, taskIndex, messageIndex)), incompressible: true } + ? { element: cc.getOrCreate(m, () => new TestMessageElement(result, test, taskIndex, messageIndex)), incompressible: false } : undefined ) .filter(isDefined); @@ -2103,8 +2094,8 @@ class TestRunElementRenderer implements ICompressibleTreeRenderer, FuzzyScore>, _index: number, templateData: TemplateData): void { const chain = node.element.elements; const lastElement = chain[chain.length - 1]; - if (lastElement instanceof TaskElement && chain.length >= 2) { - this.doRender(chain[chain.length - 2], templateData); + if ((lastElement instanceof TaskElement || lastElement instanceof TestMessageElement) && chain.length >= 2) { + this.doRender(chain[chain.length - 2], templateData, lastElement); } else { this.doRender(lastElement, templateData); } @@ -2148,20 +2139,26 @@ class TestRunElementRenderer implements ICompressibleTreeRenderer this.doRender(element, templateData))); - this.doRenderInner(element, templateData); + templateData.elementDisposable.add( + element.onDidChange(() => this.doRender(element, templateData, subjectElement)), + ); + this.doRenderInner(element, templateData, subjectElement); } /** Called, and may be re-called, to render or re-render an element */ - private doRenderInner(element: ITreeElement, templateData: TemplateData) { - if (element.labelWithIcons) { - dom.reset(templateData.label, ...element.labelWithIcons); - } else if (element.description) { - dom.reset(templateData.label, element.label, dom.$('span.test-label-description', {}, element.description)); + private doRenderInner(element: ITreeElement, templateData: TemplateData, subjectElement: ITreeElement | undefined) { + let { label, labelWithIcons, description } = element; + if (subjectElement instanceof TestMessageElement) { + description = subjectElement.label; + } + + const descriptionElement = description ? dom.$('span.test-label-description', {}, description) : ''; + if (labelWithIcons) { + dom.reset(templateData.label, ...labelWithIcons, descriptionElement); } else { - dom.reset(templateData.label, element.label); + dom.reset(templateData.label, label, descriptionElement); } const icon = element.icon; From 0ee7a576b6c2e252266a392cac6d9c9be7b3a1d0 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 1 Sep 2023 13:17:58 -0700 Subject: [PATCH 196/198] tunnels: fix command prompt windows show up on windows machine (#192016) Fixes #190425 --- cli/src/tunnels/control_server.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cli/src/tunnels/control_server.rs b/cli/src/tunnels/control_server.rs index 6f8c1060e1f..45e0c9748ef 100644 --- a/cli/src/tunnels/control_server.rs +++ b/cli/src/tunnels/control_server.rs @@ -1021,6 +1021,9 @@ where p.current_dir(cwd); } + #[cfg(target_os = "windows")] + p.creation_flags(winapi::um::winbase::CREATE_NO_WINDOW); + let mut p = p.spawn().map_err(CodeError::ProcessSpawnFailed)?; let futs = FuturesUnordered::new(); From a6808a1534469d4cb2f52e70fedef7fcbf92e1f8 Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Fri, 1 Sep 2023 13:18:17 -0700 Subject: [PATCH 197/198] testing: fix text centering in filter (#192017) Fixes #182648 --- .../workbench/contrib/testing/browser/testingExplorerFilter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts b/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts index c577c7ba942..05be7da398c 100644 --- a/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts +++ b/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.ts @@ -135,7 +135,7 @@ export class TestingExplorerFilter extends BaseActionViewItem { public layout(width: number) { this.input.layout(new dom.Dimension( width - /* horizontal padding */ 24 - /* editor padding */ 8 - /* filter button padding */ 22, - /* line height */ 27 - /* editor padding */ 4, + 20, // line height from suggestEnabledInput.ts )); } From 3519b130fbbd41281980d726dae3ca964305b329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E8=89=AF?= <1204183885@qq.com> Date: Sat, 2 Sep 2023 04:47:01 +0800 Subject: [PATCH 198/198] fix: Close #191880, Repair command cannot be searched by keyword after localization (#191953) --- .../api/browser/mainThreadComments.ts | 4 +- .../api/browser/viewsExtensionPoint.ts | 3 +- .../test/browser/mainThreadTreeViews.test.ts | 2 +- src/vs/workbench/common/views.ts | 2 +- .../browser/preview/bulkEdit.contribution.ts | 2 +- .../browser/chatContributionServiceImpl.ts | 2 +- .../comments/browser/commentsTreeViewer.ts | 1 + .../test/browser/commentsView.test.ts | 2 +- .../debug/browser/debug.contribution.ts | 2 +- .../browser/editSessions.contribution.ts | 4 +- .../editSessions/common/editSessions.ts | 1 + .../contrib/files/browser/explorerViewlet.ts | 2 +- .../markers/browser/markers.contribution.ts | 2 +- .../contrib/markers/browser/messages.ts | 1 + .../output/browser/output.contribution.ts | 2 +- .../contrib/remote/browser/remoteExplorer.ts | 2 +- .../contrib/scm/browser/scm.contribution.ts | 2 +- .../terminal/browser/terminal.contribution.ts | 2 +- .../testing/browser/testing.contribution.ts | 4 +- .../userDataSync/browser/userDataSync.ts | 4 +- .../userDataSync/common/userDataSync.ts | 1 + .../views/browser/viewDescriptorService.ts | 2 +- .../test/browser/viewContainerModel.test.ts | 44 +++++++++---------- .../browser/viewDescriptorService.test.ts | 16 +++---- 24 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadComments.ts b/src/vs/workbench/api/browser/mainThreadComments.ts index 29f7b613e5a..ab886d7dc8c 100644 --- a/src/vs/workbench/api/browser/mainThreadComments.ts +++ b/src/vs/workbench/api/browser/mainThreadComments.ts @@ -16,7 +16,7 @@ import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/ext import { ICommentController, ICommentInfo, ICommentService, INotebookCommentInfo } from 'vs/workbench/contrib/comments/browser/commentService'; import { CommentsPanel } from 'vs/workbench/contrib/comments/browser/commentsView'; import { CommentProviderFeatures, ExtHostCommentsShape, ExtHostContext, MainContext, MainThreadCommentsShape, CommentThreadChanges } from '../common/extHost.protocol'; -import { COMMENTS_VIEW_ID, COMMENTS_VIEW_STORAGE_ID, COMMENTS_VIEW_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; +import { COMMENTS_VIEW_ID, COMMENTS_VIEW_STORAGE_ID, COMMENTS_VIEW_TITLE, COMMENTS_VIEW_ORIGINAL_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; import { ViewContainer, IViewContainersRegistry, Extensions as ViewExtensions, ViewContainerLocation, IViewsRegistry, IViewsService, IViewDescriptorService } from 'vs/workbench/common/views'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; @@ -596,7 +596,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments if (!commentsViewAlreadyRegistered) { const VIEW_CONTAINER: ViewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer({ id: COMMENTS_VIEW_ID, - title: COMMENTS_VIEW_TITLE, + title: { value: COMMENTS_VIEW_TITLE, original: COMMENTS_VIEW_ORIGINAL_TITLE }, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [COMMENTS_VIEW_ID, { mergeViewWithContainerWhenSingleView: true }]), storageId: COMMENTS_VIEW_STORAGE_ID, hideIfEmpty: true, diff --git a/src/vs/workbench/api/browser/viewsExtensionPoint.ts b/src/vs/workbench/api/browser/viewsExtensionPoint.ts index f97885e8e02..23d64b26b76 100644 --- a/src/vs/workbench/api/browser/viewsExtensionPoint.ts +++ b/src/vs/workbench/api/browser/viewsExtensionPoint.ts @@ -435,7 +435,8 @@ class ViewsExtensionHandler implements IWorkbenchContribution { viewContainer = this.viewContainersRegistry.registerViewContainer({ id, - title, extensionId, + title: { value: title, original: title }, + extensionId, ctorDescriptor: new SyncDescriptor( ViewPaneContainer, [id, { mergeViewWithContainerWhenSingleView: true }] diff --git a/src/vs/workbench/api/test/browser/mainThreadTreeViews.test.ts b/src/vs/workbench/api/test/browser/mainThreadTreeViews.test.ts index 421d9eecd4a..f796cae8ed2 100644 --- a/src/vs/workbench/api/test/browser/mainThreadTreeViews.test.ts +++ b/src/vs/workbench/api/test/browser/mainThreadTreeViews.test.ts @@ -52,7 +52,7 @@ suite('MainThreadHostTreeView', function () { const instantiationService: TestInstantiationService = workbenchInstantiationService(undefined, disposables); const viewDescriptorService = instantiationService.createInstance(ViewDescriptorService); instantiationService.stub(IViewDescriptorService, viewDescriptorService); - container = Registry.as(Extensions.ViewContainersRegistry).registerViewContainer({ id: 'testContainer', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = Registry.as(Extensions.ViewContainersRegistry).registerViewContainer({ id: 'testContainer', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const viewDescriptor: ITreeViewDescriptor = { id: testTreeViewId, ctorDescriptor: null!, diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts index 07578cb75b6..8633aac784a 100644 --- a/src/vs/workbench/common/views.ts +++ b/src/vs/workbench/common/views.ts @@ -75,7 +75,7 @@ export interface IViewContainerDescriptor { /** * The title of the view container */ - readonly title: ILocalizedString | string; + readonly title: ILocalizedString; /** * Icon representation of the View container diff --git a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts index 2c3c2a6d72e..ff63502983b 100644 --- a/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts +++ b/src/vs/workbench/contrib/bulkEdit/browser/preview/bulkEdit.contribution.ts @@ -326,7 +326,7 @@ const refactorPreviewViewIcon = registerIcon('refactor-preview-view-icon', Codic const container = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: BulkEditPane.ID, - title: localize('panel', "Refactor Preview"), + title: { value: localize('panel', "Refactor Preview"), original: 'Refactor Preview' }, hideIfEmpty: true, ctorDescriptor: new SyncDescriptor( ViewPaneContainer, diff --git a/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts b/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts index d10beb91120..aa774249863 100644 --- a/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts +++ b/src/vs/workbench/contrib/chat/browser/chatContributionServiceImpl.ts @@ -113,7 +113,7 @@ export class ChatContributionService implements IChatContributionService { const viewContainerId = CHAT_SIDEBAR_PANEL_ID + '.' + providerDescriptor.id; const viewContainer: ViewContainer = Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer({ id: viewContainerId, - title, + title: { value: title, original: 'Chat' }, icon, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [viewContainerId, { mergeViewWithContainerWhenSingleView: true }]), storageId: viewContainerId, diff --git a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts index c0e24d570e5..890437bb65a 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts @@ -33,6 +33,7 @@ import { IListStyles } from 'vs/base/browser/ui/list/listWidget'; export const COMMENTS_VIEW_ID = 'workbench.panel.comments'; export const COMMENTS_VIEW_STORAGE_ID = 'Comments'; +export const COMMENTS_VIEW_ORIGINAL_TITLE = 'Comments'; export const COMMENTS_VIEW_TITLE = nls.localize('comments.view.title', "Comments"); interface IResourceTemplateData { diff --git a/src/vs/workbench/contrib/comments/test/browser/commentsView.test.ts b/src/vs/workbench/contrib/comments/test/browser/commentsView.test.ts index 7dbdff3d855..83d2bf1ccea 100644 --- a/src/vs/workbench/contrib/comments/test/browser/commentsView.test.ts +++ b/src/vs/workbench/contrib/comments/test/browser/commentsView.test.ts @@ -54,7 +54,7 @@ export class TestViewDescriptorService implements Partial(ViewExtensions.ViewContainersRegistry).registerViewContainer({ id: DEBUG_PANEL_ID, - title: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugPanel' }, "Debug Console"), + title: { value: nls.localize({ comment: ['Debug is a noun in this context, not a verb.'], key: 'debugPanel' }, "Debug Console"), original: 'Debug Console' }, icon: icons.debugConsoleViewIcon, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [DEBUG_PANEL_ID, { mergeViewWithContainerWhenSingleView: true }]), storageId: DEBUG_PANEL_ID, diff --git a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts index 2ac22f1d0d7..9495543aad6 100644 --- a/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts +++ b/src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts @@ -10,7 +10,7 @@ import { ILifecycleService, LifecyclePhase, ShutdownReason } from 'vs/workbench/ import { Action2, IAction2Options, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; import { localize } from 'vs/nls'; -import { IEditSessionsStorageService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EDIT_SESSIONS_CONTAINER_ID, EditSessionSchemaVersion, IEditSessionsLogService, EDIT_SESSIONS_VIEW_ICON, EDIT_SESSIONS_TITLE, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_DATA_VIEW_ID, decodeEditSessionFileContent, hashedEditSessionId, editSessionsLogId, EDIT_SESSIONS_PENDING } from 'vs/workbench/contrib/editSessions/common/editSessions'; +import { IEditSessionsStorageService, Change, ChangeType, Folder, EditSession, FileType, EDIT_SESSION_SYNC_CATEGORY, EDIT_SESSIONS_CONTAINER_ID, EditSessionSchemaVersion, IEditSessionsLogService, EDIT_SESSIONS_VIEW_ICON, EDIT_SESSIONS_TITLE, EDIT_SESSIONS_ORIGINAL_TITLE, EDIT_SESSIONS_SHOW_VIEW, EDIT_SESSIONS_DATA_VIEW_ID, decodeEditSessionFileContent, hashedEditSessionId, editSessionsLogId, EDIT_SESSIONS_PENDING } from 'vs/workbench/contrib/editSessions/common/editSessions'; import { ISCMRepository, ISCMService } from 'vs/workbench/contrib/scm/common/scm'; import { IFileService } from 'vs/platform/files/common/files'; import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState } from 'vs/platform/workspace/common/workspace'; @@ -274,7 +274,7 @@ export class EditSessionsContribution extends Disposable implements IWorkbenchCo const container = Registry.as(ViewExtensions.ViewContainersRegistry).registerViewContainer( { id: EDIT_SESSIONS_CONTAINER_ID, - title: EDIT_SESSIONS_TITLE, + title: { value: EDIT_SESSIONS_TITLE, original: EDIT_SESSIONS_ORIGINAL_TITLE }, ctorDescriptor: new SyncDescriptor( ViewPaneContainer, [EDIT_SESSIONS_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }] diff --git a/src/vs/workbench/contrib/editSessions/common/editSessions.ts b/src/vs/workbench/contrib/editSessions/common/editSessions.ts index 53c39076411..4cb53dc45f7 100644 --- a/src/vs/workbench/contrib/editSessions/common/editSessions.ts +++ b/src/vs/workbench/contrib/editSessions/common/editSessions.ts @@ -98,6 +98,7 @@ export const EDIT_SESSIONS_PENDING = new RawContextKey(EDIT_SESSIONS_PE export const EDIT_SESSIONS_CONTAINER_ID = 'workbench.view.editSessions'; export const EDIT_SESSIONS_DATA_VIEW_ID = 'workbench.views.editSessions.data'; +export const EDIT_SESSIONS_ORIGINAL_TITLE = 'Cloud Changes'; export const EDIT_SESSIONS_TITLE = localize('cloud changes', 'Cloud Changes'); export const EDIT_SESSIONS_VIEW_ICON = registerIcon('edit-sessions-view-icon', Codicon.cloudDownload, localize('editSessionViewIcon', 'View icon of the cloud changes view.')); diff --git a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts index 602ffa99968..af0be566a8b 100644 --- a/src/vs/workbench/contrib/files/browser/explorerViewlet.ts +++ b/src/vs/workbench/contrib/files/browser/explorerViewlet.ts @@ -252,7 +252,7 @@ const viewContainerRegistry = Registry.as(Extensions.Vi */ export const VIEW_CONTAINER: ViewContainer = viewContainerRegistry.registerViewContainer({ id: VIEWLET_ID, - title: localize('explore', "Explorer"), + title: { value: localize('explore', "Explorer"), original: 'Explorer' }, ctorDescriptor: new SyncDescriptor(ExplorerViewPaneContainer), storageId: 'workbench.explorer.views.state', icon: explorerViewIcon, diff --git a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts index 275a84b8c9a..ef2f37cee8c 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.contribution.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.contribution.ts @@ -128,7 +128,7 @@ const markersViewIcon = registerIcon('markers-view-icon', Codicon.warning, local // markers view container const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: Markers.MARKERS_CONTAINER_ID, - title: Messages.MARKERS_PANEL_TITLE_PROBLEMS, + title: { value: Messages.MARKERS_PANEL_TITLE_PROBLEMS, original: Messages.MARKERS_PANEL_ORIGINAL_TITLE_PROBLEMS }, icon: markersViewIcon, hideIfEmpty: true, order: 0, diff --git a/src/vs/workbench/contrib/markers/browser/messages.ts b/src/vs/workbench/contrib/markers/browser/messages.ts index 7ff0582f02f..767485b3692 100644 --- a/src/vs/workbench/contrib/markers/browser/messages.ts +++ b/src/vs/workbench/contrib/markers/browser/messages.ts @@ -21,6 +21,7 @@ export default class Messages { public static PROBLEMS_PANEL_CONFIGURATION_COMPARE_ORDER_SEVERITY: string = nls.localize('problems.panel.configuration.compareOrder.severity', "Navigate problems ordered by severity"); public static PROBLEMS_PANEL_CONFIGURATION_COMPARE_ORDER_POSITION: string = nls.localize('problems.panel.configuration.compareOrder.position', "Navigate problems ordered by position"); + public static MARKERS_PANEL_ORIGINAL_TITLE_PROBLEMS: string = 'Problems'; public static MARKERS_PANEL_TITLE_PROBLEMS: string = nls.localize('markers.panel.title.problems', "Problems"); public static MARKERS_PANEL_NO_PROBLEMS_BUILT: string = nls.localize('markers.panel.no.problems.build', "No problems have been detected in the workspace."); diff --git a/src/vs/workbench/contrib/output/browser/output.contribution.ts b/src/vs/workbench/contrib/output/browser/output.contribution.ts index 87d04e5fb83..44b292ed5b1 100644 --- a/src/vs/workbench/contrib/output/browser/output.contribution.ts +++ b/src/vs/workbench/contrib/output/browser/output.contribution.ts @@ -54,7 +54,7 @@ ModesRegistry.registerLanguage({ const outputViewIcon = registerIcon('output-view-icon', Codicon.output, nls.localize('outputViewIcon', 'View icon of the output view.')); const VIEW_CONTAINER: ViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: OUTPUT_VIEW_ID, - title: nls.localize('output', "Output"), + title: { value: nls.localize('output', "Output"), original: 'Output' }, icon: outputViewIcon, order: 1, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [OUTPUT_VIEW_ID, { mergeViewWithContainerWhenSingleView: true }]), diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts index fef42ab467a..f3785c75aed 100644 --- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts +++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts @@ -61,7 +61,7 @@ export class ForwardedPortsView extends Disposable implements IWorkbenchContribu private async getViewContainer(): Promise { return Registry.as(Extensions.ViewContainersRegistry).registerViewContainer({ id: TUNNEL_VIEW_CONTAINER_ID, - title: nls.localize('ports', "Ports"), + title: { value: nls.localize('ports', "Ports"), original: 'Ports' }, icon: portsViewIcon, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [TUNNEL_VIEW_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }]), storageId: TUNNEL_VIEW_CONTAINER_ID, diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index e034cf09200..f78bcd673ab 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -47,7 +47,7 @@ const sourceControlViewIcon = registerIcon('source-control-view-icon', Codicon.s const viewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: VIEWLET_ID, - title: localize('source control', "Source Control"), + title: { value: localize('source control', "Source Control"), original: 'Source Control' }, ctorDescriptor: new SyncDescriptor(SCMViewPaneContainer), storageId: 'workbench.scm.views.state', icon: sourceControlViewIcon, diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index eea627b0e88..1bb341555ef 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -123,7 +123,7 @@ Registry.as(DragAndDropExtensions.DragAndDropC // Register views const VIEW_CONTAINER = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: TERMINAL_VIEW_ID, - title: nls.localize('terminal', "Terminal"), + title: { value: nls.localize('terminal', "Terminal"), original: 'Terminal' }, icon: terminalViewIcon, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [TERMINAL_VIEW_ID, { mergeViewWithContainerWhenSingleView: true }]), storageId: TERMINAL_VIEW_ID, diff --git a/src/vs/workbench/contrib/testing/browser/testing.contribution.ts b/src/vs/workbench/contrib/testing/browser/testing.contribution.ts index cac9c0c5022..f628cbf59ec 100644 --- a/src/vs/workbench/contrib/testing/browser/testing.contribution.ts +++ b/src/vs/workbench/contrib/testing/browser/testing.contribution.ts @@ -56,7 +56,7 @@ registerSingleton(ITestingDecorationsService, TestingDecorationService, Instanti const viewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: Testing.ViewletId, - title: localize('test', "Testing"), + title: { value: localize('test', "Testing"), original: 'Testing' }, ctorDescriptor: new SyncDescriptor(TestingViewPaneContainer), icon: testingViewIcon, alwaysUseContainerInfo: true, @@ -74,7 +74,7 @@ const viewContainer = Registry.as(ViewContainerExtensio const testResultsViewContainer = Registry.as(ViewContainerExtensions.ViewContainersRegistry).registerViewContainer({ id: Testing.ResultsPanelId, - title: localize('testResultsPanelName', "Test Results"), + title: { value: localize('testResultsPanelName', "Test Results"), original: 'Test Results' }, icon: testingResultsIcon, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [Testing.ResultsPanelId, { mergeViewWithContainerWhenSingleView: true }]), hideIfEmpty: true, diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts index 870402650e2..e50bd3e8559 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts @@ -43,7 +43,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { ViewContainerLocation, IViewContainersRegistry, Extensions, ViewContainer } from 'vs/workbench/common/views'; import { UserDataSyncDataViews } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncViews'; -import { IUserDataSyncWorkbenchService, getSyncAreaLabel, AccountStatus, CONTEXT_SYNC_STATE, CONTEXT_SYNC_ENABLEMENT, CONTEXT_ACCOUNT_STATE, CONFIGURE_SYNC_COMMAND_ID, SHOW_SYNC_LOG_COMMAND_ID, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_VIEW_ICON, CONTEXT_HAS_CONFLICTS } from 'vs/workbench/services/userDataSync/common/userDataSync'; +import { IUserDataSyncWorkbenchService, getSyncAreaLabel, AccountStatus, CONTEXT_SYNC_STATE, CONTEXT_SYNC_ENABLEMENT, CONTEXT_ACCOUNT_STATE, CONFIGURE_SYNC_COMMAND_ID, SHOW_SYNC_LOG_COMMAND_ID, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_ORIGINAL_TITLE, SYNC_VIEW_ICON, CONTEXT_HAS_CONFLICTS } from 'vs/workbench/services/userDataSync/common/userDataSync'; import { Codicon } from 'vs/base/common/codicons'; import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer'; import { Categories } from 'vs/platform/action/common/actionCommonCategories'; @@ -1134,7 +1134,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo return Registry.as(Extensions.ViewContainersRegistry).registerViewContainer( { id: SYNC_VIEW_CONTAINER_ID, - title: SYNC_TITLE, + title: { value: SYNC_TITLE, original: SYNC_ORIGINAL_TITLE }, ctorDescriptor: new SyncDescriptor( ViewPaneContainer, [SYNC_VIEW_CONTAINER_ID, { mergeViewWithContainerWhenSingleView: true }] diff --git a/src/vs/workbench/services/userDataSync/common/userDataSync.ts b/src/vs/workbench/services/userDataSync/common/userDataSync.ts index 9a709322d34..1cfcc42cc02 100644 --- a/src/vs/workbench/services/userDataSync/common/userDataSync.ts +++ b/src/vs/workbench/services/userDataSync/common/userDataSync.ts @@ -69,6 +69,7 @@ export interface IUserDataSyncConflictsView extends IView { open(conflict: IResourcePreview): Promise; } +export const SYNC_ORIGINAL_TITLE = 'Settings Sync'; export const SYNC_TITLE = localize('sync category', "Settings Sync"); export const SYNC_VIEW_ICON = registerIcon('settings-sync-view-icon', Codicon.sync, localize('syncViewIcon', 'View icon of the Settings Sync view.')); diff --git a/src/vs/workbench/services/views/browser/viewDescriptorService.ts b/src/vs/workbench/services/views/browser/viewDescriptorService.ts index b802ba5eab5..248e5db87be 100644 --- a/src/vs/workbench/services/views/browser/viewDescriptorService.ts +++ b/src/vs/workbench/services/views/browser/viewDescriptorService.ts @@ -490,7 +490,7 @@ export class ViewDescriptorService extends Disposable implements IViewDescriptor const container = this.viewContainersRegistry.registerViewContainer({ id, ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [id, { mergeViewWithContainerWhenSingleView: true }]), - title: id, // we don't want to see this so using id + title: { value: id, original: id }, // we don't want to see this so using id icon: location === ViewContainerLocation.Sidebar ? defaultViewIcon : undefined, storageId: getViewContainerStorageId(id), hideIfEmpty: true diff --git a/src/vs/workbench/services/views/test/browser/viewContainerModel.test.ts b/src/vs/workbench/services/views/test/browser/viewContainerModel.test.ts index e445f4a41b9..57723675e03 100644 --- a/src/vs/workbench/services/views/test/browser/viewContainerModel.test.ts +++ b/src/vs/workbench/services/views/test/browser/viewContainerModel.test.ts @@ -64,13 +64,13 @@ suite('ViewContainerModel', () => { }); test('empty model', function () { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); assert.strictEqual(testObject.visibleViewDescriptors.length, 0); }); test('register/unregister', () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); @@ -97,7 +97,7 @@ suite('ViewContainerModel', () => { }); test('when contexts', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); assert.strictEqual(testObject.visibleViewDescriptors.length, 0); @@ -141,7 +141,7 @@ suite('ViewContainerModel', () => { })); test('when contexts - multiple', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null!, name: 'Test View 1' }; @@ -164,7 +164,7 @@ suite('ViewContainerModel', () => { })); test('when contexts - multiple 2', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null!, name: 'Test View 1', when: ContextKeyExpr.equals('showview1', true) }; @@ -187,7 +187,7 @@ suite('ViewContainerModel', () => { })); test('setVisible', () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null!, name: 'Test View 1', canToggleVisibility: true }; @@ -232,7 +232,7 @@ suite('ViewContainerModel', () => { }); test('move', () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const view1: IViewDescriptor = { id: 'view1', ctorDescriptor: null!, name: 'Test View 1' }; @@ -262,7 +262,7 @@ suite('ViewContainerModel', () => { test('view states', () => runWithFakedTimers({ useFakeTimers: true }, async () => { storageService.store(`${container.id}.state.hidden`, JSON.stringify([{ id: 'view1', isHidden: true }]), StorageScope.PROFILE, StorageTarget.MACHINE); - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); @@ -282,7 +282,7 @@ suite('ViewContainerModel', () => { test('view states and when contexts', () => runWithFakedTimers({ useFakeTimers: true }, async () => { storageService.store(`${container.id}.state.hidden`, JSON.stringify([{ id: 'view1', isHidden: true }]), StorageScope.PROFILE, StorageTarget.MACHINE); - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); @@ -312,7 +312,7 @@ suite('ViewContainerModel', () => { test('view states and when contexts multiple views', () => runWithFakedTimers({ useFakeTimers: true }, async () => { storageService.store(`${container.id}.state.hidden`, JSON.stringify([{ id: 'view1', isHidden: true }]), StorageScope.PROFILE, StorageTarget.MACHINE); - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); @@ -357,7 +357,7 @@ suite('ViewContainerModel', () => { })); test('remove event is not triggered if view was hidden and removed', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor: IViewDescriptor = { @@ -387,7 +387,7 @@ suite('ViewContainerModel', () => { })); test('add event is not triggered if view was set visible (when visible) and not active', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor: IViewDescriptor = { @@ -414,7 +414,7 @@ suite('ViewContainerModel', () => { })); test('remove event is not triggered if view was hidden and not active', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor: IViewDescriptor = { @@ -441,7 +441,7 @@ suite('ViewContainerModel', () => { })); test('add event is not triggered if view was set visible (when not visible) and not active', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor: IViewDescriptor = { @@ -472,7 +472,7 @@ suite('ViewContainerModel', () => { })); test('added view descriptors are in ascending order in the event', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); @@ -523,7 +523,7 @@ suite('ViewContainerModel', () => { })); test('add event is triggered only once when view is set visible while it is set active', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor: IViewDescriptor = { @@ -554,7 +554,7 @@ suite('ViewContainerModel', () => { })); test('add event is not triggered only when view is set hidden while it is set active', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor: IViewDescriptor = { @@ -583,7 +583,7 @@ suite('ViewContainerModel', () => { })); test('#142087: view descriptor visibility is not reset', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const viewDescriptor: IViewDescriptor = { id: 'view1', @@ -606,7 +606,7 @@ suite('ViewContainerModel', () => { })); test('remove event is triggered properly if mutliple views are hidden at the same time', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor1: IViewDescriptor = { @@ -664,7 +664,7 @@ suite('ViewContainerModel', () => { })); test('add event is triggered properly if mutliple views are hidden at the same time', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor1: IViewDescriptor = { @@ -732,7 +732,7 @@ suite('ViewContainerModel', () => { })); test('add and remove events are triggered properly if mutliple views are hidden and added at the same time', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const testObject = viewDescriptorService.getViewContainerModel(container); const target = disposableStore.add(new ViewDescriptorSequence(testObject)); const viewDescriptor1: IViewDescriptor = { @@ -809,7 +809,7 @@ suite('ViewContainerModel', () => { })); test('newly added view descriptor is hidden if it was toggled hidden in storage before adding', () => runWithFakedTimers({ useFakeTimers: true }, async () => { - container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + container = ViewContainerRegistry.registerViewContainer({ id: 'test', title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const viewDescriptor: IViewDescriptor = { id: 'view1', ctorDescriptor: null!, diff --git a/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts b/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts index 74b4b56185d..4a1c167c07f 100644 --- a/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts +++ b/src/vs/workbench/services/views/test/browser/viewDescriptorService.test.ts @@ -21,8 +21,8 @@ import { compare } from 'vs/base/common/strings'; const ViewsRegistry = Registry.as(ViewContainerExtensions.ViewsRegistry); const ViewContainersRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); const viewContainerIdPrefix = 'testViewContainer'; -const sidebarContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); -const panelContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Panel); +const sidebarContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); +const panelContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Panel); suite('ViewDescriptorService', () => { @@ -331,7 +331,7 @@ suite('ViewDescriptorService', () => { test('initialize with custom locations', async function () { const storageService = instantiationService.get(IStorageService); - const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const generateViewContainer1 = `workbench.views.service.${ViewContainerLocationToString(ViewContainerLocation.Sidebar)}.${generateUuid()}`; const viewsCustomizations = { viewContainerLocations: { @@ -390,7 +390,7 @@ suite('ViewDescriptorService', () => { test('storage change', async function () { const testObject = aViewDescriptorService(); - const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const generateViewContainer1 = `workbench.views.service.${ViewContainerLocationToString(ViewContainerLocation.Sidebar)}.${generateUuid()}`; const viewDescriptors: IViewDescriptor[] = [ @@ -525,7 +525,7 @@ suite('ViewDescriptorService', () => { test('custom locations take precedence when default view container of views change', async function () { const storageService = instantiationService.get(IStorageService); - const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const generateViewContainer1 = `workbench.views.service.${ViewContainerLocationToString(ViewContainerLocation.Sidebar)}.${generateUuid()}`; const viewsCustomizations = { viewContainerLocations: { @@ -587,7 +587,7 @@ suite('ViewDescriptorService', () => { test('view containers with not existing views are not removed from customizations', async function () { const storageService = instantiationService.get(IStorageService); - const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + const viewContainer1 = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const generateViewContainer1 = `workbench.views.service.${ViewContainerLocationToString(ViewContainerLocation.Sidebar)}.${generateUuid()}`; const viewsCustomizations = { viewContainerLocations: { @@ -637,7 +637,7 @@ suite('ViewDescriptorService', () => { }; storageService.store('views.customizations', JSON.stringify(viewsCustomizations), StorageScope.PROFILE, StorageTarget.USER); - const viewContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + const viewContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const viewDescriptors: IViewDescriptor[] = [ { id: 'view1', @@ -669,7 +669,7 @@ suite('ViewDescriptorService', () => { const storageService = instantiationService.get(IStorageService); const testObject = aViewDescriptorService(); - const viewContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: 'test', ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); + const viewContainer = ViewContainersRegistry.registerViewContainer({ id: `${viewContainerIdPrefix}-${generateUuid()}`, title: { value: 'test', original: 'test' }, ctorDescriptor: new SyncDescriptor({}) }, ViewContainerLocation.Sidebar); const viewDescriptors: IViewDescriptor[] = [ { id: 'view1',